From 6b9894255d7dcb8582947202d29dbb8af59addfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Fri, 11 Nov 2022 17:13:32 +0100 Subject: [PATCH 001/538] Explain that the contributors should base changes against `main` (#983) This isn't a particularly common issue but every now and then somebody will waste their time by preparing a change against a maintenance branch instead of working with `main` from the get-go. This change serves as a reminder to contributors to think about the `main` branch first. --- getting-started/pull-request-lifecycle.rst | 89 +++++++++++++--------- 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 907e6783a..fa6077d51 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -29,7 +29,8 @@ Here is a quick overview of how you can contribute to CPython: #. `Create an issue`_ that describes your change [*]_ -#. :ref:`Create a new branch in Git ` +#. :ref:`Create a new branch in Git ` from the + ``main`` branch #. Work on changes (e.g. fix a bug or add a new feature) @@ -79,10 +80,16 @@ You should have already :ref:`set up your system `, git fetch upstream -* Create a new branch in your local clone:: +* Create a new branch in your local clone from the ``main`` branch + in the upstream repository:: git checkout -b upstream/main + .. note:: + Almost all changes to Python, including bug fixes, should first be + made against the ``main`` branch. See :ref:`here ` for + more details. + * Make changes to the code, and use ``git status`` and ``git diff`` to see them. (Learn more about :ref:`good-prs`) @@ -180,40 +187,50 @@ Making Good PRs When creating a pull request for submission, there are several things that you should do to help ensure that your pull request is accepted. -First, 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 -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. - -.. note:: - Pull requests with only code formatting changes are usually rejected. On the other - hand, fixes for typos and grammar errors in documents and docstrings are - welcome. - -Second, be aware of backwards-compatibility considerations. While the core -developer who eventually handles your pull request will make the final call on -whether something is acceptable, thinking about backwards-compatibility early -will help prevent having your pull request rejected on these grounds. Put -yourself in the shoes of someone whose code will be broken by the change(s) -introduced by the pull request. It is quite likely that any change made will -break someone's code, so you need to have a good reason to make a change as -you will be forcing someone to update their code. (This obviously does not -apply to new classes or functions; new arguments should be optional and have -default values which maintain the existing behavior.) If in doubt, have a look -at :PEP:`387` or :ref:`discuss ` the issue with experienced -developers. - -Third, make sure you have proper tests to verify your pull request works as -expected. Pull requests will not be accepted without the proper tests! - -Fourth, make sure the entire test suite :ref:`runs ` **without -failure** because of your changes. It is not sufficient to only run whichever -test seems impacted by your changes, because there might be interferences -unknown to you between your changes and some other part of the interpreter. - -Fifth, proper :ref:`documentation ` -additions/changes should be included. +#. **Make your change against the right version of Python.** In general all + changes are made against the ``main`` branch first. This includes bug fixes. + After the change is merged there, it will be :ref:`ported back ` + to older :ref:`maintenance releases ` as well. That way we + ensure all affected versions are handled. Therefore, basing a new change + directly on a maintenance branch is only used in specific circumstances, + for instance when that change does not apply to ``main`` or the change + requires a different approach in an older Python version compared to + ``main``. + +#. **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 + 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. + + .. note:: + Pull requests with only code formatting changes are usually rejected. On + the other hand, fixes for typos and grammar errors in documents and + docstrings are welcome. + +#. **Be aware of backwards-compatibility considerations.** While the core + developer who eventually handles your pull request will make the final call on + whether something is acceptable, thinking about backwards-compatibility early + will help prevent having your pull request rejected on these grounds. Put + yourself in the shoes of someone whose code will be broken by the change(s) + introduced by the pull request. It is quite likely that any change made will + break someone's code, so you need to have a good reason to make a change as + you will be forcing someone to update their code. (This obviously does not + apply to new classes or functions; new arguments should be optional and have + default values which maintain the existing behavior.) If in doubt, have a look + at :PEP:`387` or :ref:`discuss ` the issue with experienced + developers. + +#. **Make sure you have proper tests** to verify your pull request works as + expected. Pull requests will not be accepted without the proper tests! + +#. **Make sure all tests pass.** The entire test suite needs to + :ref:`run ` **without failure** because of your changes. + It is not sufficient to only run whichever test seems impacted by your + changes, because there might be interferences unknown to you between your + changes and some other part of the interpreter. + +#. Proper :ref:`documentation ` additions/changes should be included. .. _patchcheck: From f0c9151b848688b260ced7878a6103a0b1cf4ed9 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 14 Nov 2022 02:20:43 +0100 Subject: [PATCH 002/538] Add a Sphinx role to link to GitHub files (#961) * Add a new role to link to cpython files. * Use the new :cpy-file: role in internals/parser.rst. * Make the output a literal. * Apply suggestions from code review Co-authored-by: C.A.M. Gerlach * Apply suggestions from code review Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> * Remove tabs. Co-authored-by: C.A.M. Gerlach Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- _extensions/custom_roles.py | 22 ++++++++++++++----- internals/parser.rst | 44 ++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/_extensions/custom_roles.py b/_extensions/custom_roles.py index ceba4909e..2c4e9d9d0 100644 --- a/_extensions/custom_roles.py +++ b/_extensions/custom_roles.py @@ -8,9 +8,15 @@ def setup(app): + # role to link to cpython files + app.add_role( + "cpy-file", + autolink("https://github.com/python/cpython/blob/main/{}"), + ) + # role to link to cpython labels app.add_role( "gh-label", - autolink("https://github.com/python/cpython/labels/%s"), + autolink("https://github.com/python/cpython/labels/{}"), ) # Parallel safety: # https://www.sphinx-doc.org/en/master/extdev/index.html#extension-metadata @@ -18,13 +24,19 @@ def setup(app): def autolink(pattern): - def role(name, rawtext, text, lineno, inliner, options={}, content=[]): + def role(name, rawtext, text, lineno, inliner, _options=None, _content=None): + """Combine literal + reference (unless the text is prefixed by a !).""" if " " in text: - url_text = urllib.parse.quote(f"{text}") + url_text = urllib.parse.quote(text) else: url_text = text - url = pattern % (url_text,) - node = nodes.reference(rawtext, text, refuri=url, **options) + url = pattern.format(url_text) + # don't create a reference if the text starts with ! + if text.startswith('!'): + node = nodes.literal(rawtext, text[1:]) + else: + node = nodes.reference(rawtext, '', nodes.literal(rawtext, text), + refuri=url, internal=False) return [node], [] return role diff --git a/internals/parser.rst b/internals/parser.rst index 9f979d8a1..df5f23444 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -518,17 +518,17 @@ Pegen ===== Pegen is the parser generator used in CPython to produce the final PEG parser used by the interpreter. It is the -program that can be used to read the python grammar located in :file:`Grammar/Python.gram` and produce the final C +program that can be used to read the python grammar located in :cpy-file:`Grammar/python.gram` and produce the final C parser. It contains the following pieces: * A parser generator that can read a grammar file and produce a PEG parser written in Python or C that can parse - said grammar. The generator is located at :file:`Tools/peg_generator/pegen`. + said grammar. The generator is located at :cpy-file:`Tools/peg_generator/pegen`. * A PEG meta-grammar that automatically generates a Python parser that is used for the parser generator itself (this means that there are no manually-written parsers). The meta-grammar is - located at :file:`Tools/peg_generator/pegen/metagrammar.gram`. + located at :cpy-file:`Tools/peg_generator/pegen/metagrammar.gram`. * A generated parser (using the parser generator) that can directly produce C and Python AST objects. -The source code for Pegen lives at :file:`Tools/peg_generator/pegen` but normally all typical commands to interact +The source code for Pegen lives at :cpy-file:`Tools/peg_generator/pegen` but normally all typical commands to interact with the parser generator are executed from the main makefile. How to regenerate the parser @@ -539,18 +539,18 @@ parser (the one used by the interpreter) just execute: :: make regen-pegen -using the :file:`Makefile` in the main directory. If you are on Windows you can +using the :cpy-file:`!Makefile` in the main directory. If you are on Windows you can use the Visual Studio project files to regenerate the parser or to execute: :: ./PCbuild/build.bat --regen -The generated parser file is located at :file:`Parser/parser.c`. +The generated parser file is located at :cpy-file:`Parser/parser.c`. How to regenerate the meta-parser --------------------------------- The meta-grammar (the grammar that describes the grammar for the grammar files -themselves) is located at :file:`Tools/peg_generator/pegen/metagrammar.gram`. +themselves) is located at :cpy-file:`Tools/peg_generator/pegen/metagrammar.gram`. Although it is very unlikely that you will ever need to modify it, if you make any modifications to this file (in order to implement new Pegen features) you will need to regenerate the meta-parser (the parser that parses the grammar files). To do so just execute: :: @@ -570,7 +570,7 @@ Pegen has some special grammatical elements and rules: * Strings with single quotes (') (e.g. ``'class'``) denote KEYWORDS. * Strings with double quotes (") (e.g. ``"match"``) denote SOFT KEYWORDS. -* Upper case names (e.g. ``NAME``) denote tokens in the :file:`Grammar/Tokens` file. +* Upper case names (e.g. ``NAME``) denote tokens in the :cpy-file:`Grammar/Tokens` file. * Rule names starting with ``invalid_`` are used for specialized syntax errors. - These rules are NOT used in the first pass of the parser. @@ -592,7 +592,7 @@ to handle things like indentation boundaries, some special keywords like ``ASYNC interactive mode and much more. Some of these reasons are also there for historical purposes, and some others are useful even today. -The list of tokens (all uppercase names in the grammar) that you can use can be found in the :file:`Grammar/Tokens` +The list of tokens (all uppercase names in the grammar) that you can use can be found in the :cpy-file:`Grammar/Tokens` file. If you change this file to add new tokens, make sure to regenerate the files by executing: :: make regen-token @@ -601,7 +601,7 @@ If you are on Windows you can use the Visual Studio project files to regenerate ./PCbuild/build.bat --regen -How tokens are generated and the rules governing this is completely up to the tokenizer (:file:`Parser/tokenizer.c`) +How tokens are generated and the rules governing this is completely up to the tokenizer (:cpy-file:`Parser/tokenizer.c`) and the parser just receives tokens from it. Memoization @@ -627,7 +627,7 @@ To know if a new rule needs memoization or not, benchmarking is required (comparing execution times and memory usage of some considerably big files with and without memoization). There is a very simple instrumentation API available in the generated C parse code that allows to measure how much each rule uses -memoization (check the :file:`Parser/pegen.c` file for more information) but it +memoization (check the :cpy-file:`Parser/pegen.c` file for more information) but it needs to be manually activated. Automatic variables @@ -777,7 +777,7 @@ two phases: (see the :ref:`how PEG parsers work section ` for more information). You can find a collection of macros to raise specialized syntax errors in the -:file:`Parser/pegen.h` header file. These macros allow also to report ranges for +:cpy-file:`Parser/pegen.h` header file. These macros allow also to report ranges for the custom errors that will be highlighted in the tracebacks that will be displayed when the error is reported. @@ -803,13 +803,13 @@ Generating AST objects ---------------------- The output of the C parser used by CPython that is generated by the -:file:`Grammar/Python.gram` grammar file is a Python AST object (using C +:cpy-file:`Grammar/python.gram` grammar file is a Python AST object (using C structures). This means that the actions in the grammar file generate AST objects when they succeed. Constructing these objects can be quite cumbersome (see the :ref:`AST compiler section ` for more information on how these objects are constructed and how they are used by the compiler) so special helper functions are used. These functions are declared in the -:file:`Parser/pegen.h` header file and defined in the :file:`Parser/action_helpers.c` +:cpy-file:`Parser/pegen.h` header file and defined in the :cpy-file:`Parser/action_helpers.c` file. These functions allow you to join AST sequences, get specific elements from them or to do extra processing on the generated tree. @@ -823,8 +823,8 @@ from them or to do extra processing on the generated tree. As a general rule, if an action spawns multiple lines or requires something more complicated than a single expression of C code, is normally better to create a -custom helper in :file:`Parser/action_helpers.c` and expose it in the -:file:`Parser/pegen.h` header file so it can be used from the grammar. +custom helper in :cpy-file:`Parser/action_helpers.c` and expose it in the +:cpy-file:`Parser/pegen.h` header file so it can be used from the grammar. If the parsing succeeds, the parser **must** return a **valid** AST object. @@ -833,14 +833,14 @@ Testing There are three files that contain tests for the grammar and the parser: -* ``Lib/test/test_grammar.py``. -* ``Lib/test/test_syntax.py``. -* ``Lib/test/test_exceptions.py``. +* :cpy-file:`Lib/test/test_grammar.py` +* :cpy-file:`Lib/test/test_syntax.py` +* :cpy-file:`Lib/test/test_exceptions.py` Check the contents of these files to know which is the best place to place new tests depending on the nature of the new feature you are adding. -Tests for the parser generator itself can be found in the :file:`Lib/test/test_peg_generator` directory. +Tests for the parser generator itself can be found in the :cpy-file:`Lib/test/test_peg_generator` directory. Debugging generated parsers @@ -854,7 +854,7 @@ new rules to the grammar you cannot correctly compile and execute Python anymore to debug when something goes wrong, especially when making experiments. For this reason it is a good idea to experiment first by generating a Python parser. To do this, you can go to the -:file:`Tools/peg_generator/` directory on the CPython repository and manually call the parser generator by executing: +:cpy-file:`Tools/peg_generator/` directory on the CPython repository and manually call the parser generator by executing: .. code-block:: shell @@ -874,7 +874,7 @@ Verbose mode ------------ When Python is compiled in debug mode (by adding ``--with-pydebug`` when running the configure step in Linux or by -adding ``-d`` when calling the :file:`PCbuild/build.bat` script in Windows), it is possible to activate a **very** verbose +adding ``-d`` when calling the :cpy-file:`PCbuild/build.bat` script in Windows), it is possible to activate a **very** verbose mode in the generated parser. This is very useful to debug the generated parser and to understand how it works, but it can be a bit hard to understand at first. From 5c163c6f5f98887ef736b87932038a58e9e24116 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 15 Nov 2022 22:06:56 +0200 Subject: [PATCH 003/538] Build with Python 3.11 on CI and RTD (#985) * Build with Python 3.11 * Use latest available Python 3 on CI * Use latest available Python 3 on RTD --- .github/workflows/ci.yml | 2 +- .readthedocs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7374643c3..3267db717 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3" cache: pip - name: Build docs run: make html diff --git a/.readthedocs.yml b/.readthedocs.yml index 8ccea3e0b..5d8884584 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -11,7 +11,7 @@ sphinx: build: os: ubuntu-22.04 tools: - python: "3.10" + python: "3" commands: - make dirhtml BUILDDIR=_readthedocs From 71f3b76bd7fd53c903e2836173b7e5648a5776cc Mon Sep 17 00:00:00 2001 From: Abdullah Nafees Date: Tue, 15 Nov 2022 21:10:06 +0000 Subject: [PATCH 004/538] Update steps for 'Getting the source code' and link 'Git Bootcamp' (#986) * Update steps for 'Getting the source code' and link 'Git Bootcamp' * Removed .DS_Store * Removed .github/.DS_Store * Added new line in .gitignore * Make long lines shorter Co-authored-by: Ezio Melotti --- getting-started/git-boot-camp.rst | 3 +++ getting-started/setup-building.rst | 18 +++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index f5854da56..c2ca538df 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -61,6 +61,9 @@ You can also use SSH-based or HTTPS-based URLs. Configure the Remotes --------------------- +.. These steps are duplicated in setup-building in step 6 and 7. + Please update these there as well. + Configure ``git`` to pull ``main`` from the ``upstream`` remote:: git config --local branch.main.remote upstream diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 8d09ea988..646495601 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -76,21 +76,18 @@ You will only need to execute these steps once per machine: (You can use both SSH-based or HTTPS-based URLs.) -6. Configure an ``upstream`` remote:: +.. Step 6 and 7 are are duplicated in bootcamp as well. + Please update these steps in both places. + +6. Add an ``upstream`` remote, then configure ``git`` + to pull ``main`` from ``upstream`` and always push to ``origin``:: $ cd cpython $ git remote add upstream https://github.com/python/cpython - -7. Configure ``git`` to pull ``main`` from the ``upstream`` remote:: - $ git config --local branch.main.remote upstream - -8. Since one should never attempt to push to ``upstream``, configure - ``git`` to push always to ``origin``:: - $ git remote set-url --push upstream git@github.com:/cpython.git -9. Verify that your setup is correct:: +7. Verify that your setup is correct:: $ git remote -v origin git@github.com:/cpython.git (fetch) @@ -100,6 +97,9 @@ You will only need to execute these steps once per machine: $ git config branch.main.remote upstream +For more information about these commands see +:ref:`Git Bootcamp and Cheat Sheat `. + If you did everything correctly, you should now have a copy of the code in the ``cpython`` directory and two remotes that refer to your own GitHub fork (``origin``) and the official CPython repository (``upstream``). From f8b870ff938ff9757b01d6b3f5b6a835b08714f7 Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Tue, 22 Nov 2022 06:57:06 -0600 Subject: [PATCH 005/538] Refine Windows build section, explain config & add how to run (#989) --- getting-started/setup-building.rst | 93 ++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 30 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 646495601..cd0f47c22 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -245,47 +245,80 @@ still build properly). Windows ------- -For a quick guide to building you can read `this documentation`_ from Victor -Stinner. - -All current versions of Python can be built using Microsoft Visual Studio 2017 -or later. You can download -and use any of the free or paid versions of `Visual Studio 2017`_. - -When installing Visual Studio 2017, select the **Python development** workload -and the optional **Python native development tools** component to obtain all of -the necessary build tools. If you do not already have git installed, you can -find git for Windows on the **Individual components** tab of the installer. +.. note:: If you are using the Windows Subsystem for Linux (WSL), + :ref:`clone the repository ` from a native Windows shell program + like PowerShell or the ``cmd.exe`` command prompt, + and use a build of Git targeted for Windows, + e.g. the `Git for Windows download from the official Git website`_. + Otherwise, Visual Studio will not be able to find all the project's files + and will fail the build. + +For a concise step by step summary of building Python on Windows, +you can read `Victor Stinner's guide`_. + +All supported versions of Python can be built +using Microsoft Visual Studio 2017 or later. +You can download and use any of the free or paid versions of `Visual Studio`_. + +When installing it, select the :guilabel:`Python development` workload +and the optional :guilabel:`Python native development tools` component +to obtain all of the necessary build tools. +You can find Git for Windows on the :guilabel:`Individual components` tab +if you don't already have it installed. .. note:: If you want to build MSI installers, be aware that the build toolchain - for them has a dependency on the Microsoft .NET Framework Version 3.5 (which - may not be configured on recent versions of Windows, such as Windows 10). If - you are building on a recent Windows version, use the Control Panel (Programs - | Programs and Features | Turn Windows Features on or off) and ensure that the - entry ".NET Framework 3.5 (includes .NET 2.0 and 3.0)" is enabled. + for them has a dependency on the Microsoft .NET Framework Version 3.5 + (which may not be included on recent versions of Windows, such as Windows 10). + If you are building on a recent Windows version, use the Control Panel + (:menuselection:`Programs --> Programs and Features --> Turn Windows Features on or off`) + and ensure that the entry + :guilabel:`.NET Framework 3.5 (includes .NET 2.0 and 3.0)` is enabled. Your first build should use the command line to ensure any external dependencies are downloaded: -.. code-block:: dosbatch +.. code-block:: batch + + PCbuild\build.bat -c Debug + +The above command line build uses the ``-c Debug`` argument +to build in the ``Debug`` configuration, +which enables checks and assertions helpful for developing Python. +By default, it builds in the ``Release`` configuration +and for the 64-bit ``x64`` platform rather than 32-bit ``Win32``; +use ``-c`` and ``-p`` to control build config and platform, respectively. + +After this build succeeds, you can open the ``PCbuild\pcbuild.sln`` solution +in the Visual Studio IDE to continue development, if you prefer. +When building in Visual Studio, +make sure to select build settings that match what you used with the script +(the :guilabel:`Debug` configuration and the :guilabel:`x64` platform) +from the dropdown menus in the toolbar. + +.. note:: + + If you need to change the build configuration or platform, + build once with the ``build.bat`` script set to those options first + before building with them in VS to ensure all files are rebuilt properly, + or you may encouter errors when loading modules that were not rebuilt. + + Avoid selecting the ``PGInstrument`` and ``PGUpdate`` configurations, + as these are intended for PGO builds and not for normal development. + +You can run the build of Python you've compiled with: - PCbuild\build.bat +.. code-block:: batch -After this build succeeds, you can open the ``PCbuild\pcbuild.sln`` solution in -Visual Studio to continue development. + PCbuild\amd64\python_d.exe -See the `readme`_ for more details on what other software is necessary and how -to build. +See the `PCBuild readme`_ for more details on what other software is necessary +and how to build. -.. note:: If you are using the Windows Subsystem for Linux (WSL), clone the - repository from a native Windows terminal program like cmd.exe command prompt - or PowerShell as well as use a build of git targeted for Windows, e.g., the - official one from ``_. Otherwise, Visual Studio will - not be able to find all the project's files and will fail the build. +.. _Victor Stinner's guide: https://cpython-core-tutorial.readthedocs.io/en/latest/build_cpython_windows.html +.. _Visual Studio: https://visualstudio.microsoft.com/ +.. _PCBuild readme: https://github.com/python/cpython/blob/main/PCbuild/readme.txt +.. _Git for Windows download from the official Git website: https://git-scm.com/download/win -.. _this documentation: https://cpython-core-tutorial.readthedocs.io/en/latest/build_cpython_windows.html -.. _Visual Studio 2017: https://visualstudio.microsoft.com/ -.. _readme: https://github.com/python/cpython/blob/main/PCbuild/readme.txt .. _build-dependencies: From 1ade6642a21b7450b785bf98dc5617443f2c6ece Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 22 Nov 2022 14:43:54 +0100 Subject: [PATCH 006/538] Add missing step to C API tests instructions (GH-990) --- developer-workflow/c-api.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index 5564bdc9c..d51814a0f 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -122,6 +122,11 @@ To add a new set of tests (or extract a set out of the monolithic - Call the ``_PyTestCapi_Init_*`` from ``PyInit__testcapi`` in ``Modules/_testcapimodule.c``. +- Add the new C file to :cpy-file:`Modules/Setup.stdlib.in`, + :cpy-file:`PCbuild/_testcapi.vcxproj` and + :cpy-file:`PCbuild/_testcapi.vcxproj.filters`, + alongside the other ``_testcapi/*.c`` entries. + Note that all ``Modules/_testcapi/*.c`` sources initialize the same module, so be careful about name collisions. From 7dd6544d134ef126e533247c6745612e24487d12 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 22 Nov 2022 16:05:58 -0800 Subject: [PATCH 007/538] Add Hugo van Kemenade to the developer log --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 6916c89bd..5f262b74c 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Hugo van Kemenade,hugovk,2022-11-21,, Alex Waygood,AlexWaygood,2022-10-18,, Filipe Laíns,FFY00,2022-10-17,, Erlend Egeberg Aasland,erlend-aasland,2022-05-05,, From c541302724bd767833db25215f9fdff529afb10b Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 23 Nov 2022 12:40:11 -0800 Subject: [PATCH 008/538] Add Kumar Aditya to the core developer log --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 5f262b74c..95d55c00f 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Kumar Aditya,kumaraditya303,2022-11-21,, Hugo van Kemenade,hugovk,2022-11-21,, Alex Waygood,AlexWaygood,2022-10-18,, Filipe Laíns,FFY00,2022-10-17,, From ed82ed55c14c1ad746a3a9ec548c91c625543691 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 27 Nov 2022 22:18:53 +0200 Subject: [PATCH 009/538] Add hugovk to the experts index (#993) --- 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 0aa8104de..e7b80febc 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -323,13 +323,13 @@ issue tracker ezio-melotti buildbots zware, pablogsal bytecode benjaminp, 1st1, markshannon, brandtbucher context managers ncoghlan -core workflow Mariatta, ezio-melotti +core workflow Mariatta, ezio-melotti, hugovk coverity scan tiran, brettcannon, Yhg1s cryptography gpshead, dstufft data formats mdickinson database malemburg -devguide merwok, ezio-melotti, willingc, Mariatta -documentation ezio-melotti, merwok, JulienPalard, willingc +devguide merwok, ezio-melotti, willingc, Mariatta, hugovk +documentation ezio-melotti, merwok, JulienPalard, willingc, hugovk emoji Mariatta extension modules encukou, ncoghlan filesystem giampaolo From 7dcba58da8005e87929f8d3397a1f46ed5ade317 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 28 Nov 2022 03:51:26 +0200 Subject: [PATCH 010/538] Add Python favicon (#992) --- _static/favicon.png | Bin 0 -> 11498 bytes conf.py | 1 + 2 files changed, 1 insertion(+) create mode 100644 _static/favicon.png diff --git a/_static/favicon.png b/_static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..462cfedd1fc8acd08d92a9d7bbf3fa653ccf8db6 GIT binary patch literal 11498 zcmX9^Wn5I<*S#|gFmy}9&@CO(-QA#s(yeqeq@ctQ(j^T_NJ+Ey(zH6^IU2PRSY$|L30PxgQ74;v#$p0QF#^YQ6w<{(9aDP!#lr!{S zIIsxFC7o%yAL}%lk>Y+A^a9MOY)8aT!KAEc2mxs=2PGGN_4wK^$@HeD!P(kRqL;5p zA@4I;(1>BL>KN?%VBbdQD4r6DQf(@OsVJ_9M;^d`4G5(LRte&EYO}kGBt|%u zO(@DwoLQD+dpo`o=O#6+FZ0S6FRJIJ-Xem(=fgHL`)Oiw*fH*xfimXW0`v{ zja3itzINlGr^aNokX~Zm>#N?!ua2Yc1S(!A681(+ zs)Md@s6&DrLKwZV!ST6YoJBvrnk9;JDYZLtOT#Jlp;Bn{Cv47G_xR*#7vT8@hx)lV z-_Q*WpF#DH(4QGvbWd=wCc=MZ8En#z`>tp7`X&kwp|gcs31GcIOfEXt{$d`2+>2Bt zuCN*Tt`T7&?Bs$D8UMDK)MSVDq$2=Y>xAs)Z5oDsOtl|$%B}Nqro>qL2DEB>Cu#)i z^7-P?RWEuyk;-l}>K4t;3s=z$peo8+AB{2c^jl$ojp5>Fqzvx`6E(uCg5F6kBjN&_ zaKOkM*4AyNiZgIb{`t3t$#Tg3Lky%s`B=w7OmpEM4TjIl;`fF!^)gte;Ez^TVI2Dj zj8Fmw;C1BWZims&u?G!RIH$Qy8P7a*6dChDU&86T6eP!xHswrG3PopVPeFQz+lqpG z1l|$+pK@)-Rs;$G%qYM)dgGQ$mME~_HS06B4dL=>3Jg(mC+RSxbQ4OvEx{}941*H0 z&Ccev^DxV!^*@D{gN+;fz&n7JQhh~2A1~N0t5@PYW4L+NyFW}41`MIPfkEB?B z887X2Uqa+^I`44h=B4wNumP0VIKsfm1|5ES-H7Fv?1GiQZSa|jiQa-_gSd+I?T{Mr#kpHjCRksly_Zja^d^rw3_|tAaL*;`EiEcblac)LWpRf#JCzy(%irZFJt{(bpX7AejUjsvLZbLdD|QnC z)5}%6=L%qmZJy=LZN9N+kYMuf?$#nMG-$M)LeR;`p*aT(QE*yPv4b!mC~76Hid!;dWeVO$;948AS`>Vj(4FI84szi{BV zQ}S2-U_<_$@_Z_!rlZ?BlT=t@0v(R={X5&~xxym&xC^!kS@nhGPa3mSy;nAJba=y~ zA1{#Q)9Vw|$LP&wny|}}>>4Yj+2qC~>*@vm9=uAa7+vc?B|6Rw1b+OxmD|&Jjk1{k za5QSE$auNT3~Lk2`D_hi#dU?!iuwJCK5wTS$rKX!?q31wPfJN zRBlhT?7CdzU;srZ0;4%mgiBdI+80bt&~e)RL`knx+o3%UzA|6m42+`Esrqia#>GFu zcdhYm^{#c~1?Q(B8IJ?gfhr^#PD(?eP6}L?4mhEK1H7k#p$;n!X2~v1?=n~y%)v=I zEI+xTHliRMdFL_ygwvcJ~QpDe%MYH!^$i{Va)_k zjeN^L<?ZQAq(6I3#$;+2F|ClBsbUVc{a_E zvYijh&?G5o!>p_;+ z?HgCNJ6UNgos7(~6Ic_|%_XB+qwYX6hO!><*P)QR`F$GoHo4i~VF9XeBoRC%dG(*6 z%)7MPZy)qgmsh0OmU8KM#_s>MA&qh-hA`NhKok(H-^)8>ak8eWaBHH~=4YLabs`LJ z@pSL;-O*K7ISpDLXPySA|LDeX@)1^!OlhgPkgRoWJsCY3{MBET(0Iwv)DX`1%yK5F zoWpKQ;0Dzobr5Bz;N&s&7%FDZxK+A%3D%|+wu{oEJ81_Pm zcy)kHMU|t#gX*tgaG;V?{DEsvXPN5+0{Fwp05WXXDjuI*Cj1Zh7o}!w%eU)JurJ8< zI#5KKB@uBU#AQ9cHTj2wu<(~98{u_jyG6n5clFNZ9sgRXLTEWhEwe-huk`RnYuAjU z+-$T(nD6JNFra~fN}lef=HO#YlFMkGyjM?|oB_w;aJ;*X#Vp-e2nYfmhb|5ae@&Cl8$bgyWZfK^rfc z4*VybSzVB=gRR(?dpbdF+s*tbUuZ4>YQV_Z%>HC7AA^%KVyUSHLn~bG+5x(`>YImW z3s~L`B%vm0Dl`Uo76dyP?OJI1HO|q8WZ?vCT@h3+gfA?>w)$%-tPcrX@GJU>TL(u; zZOrAfz*Q*UX^m1R4+AgyFn$>e4TZ;X{OZ@nrgNy}vd1zXfktpuN zy#8$jH`N{C{ed*#DitX$XFB*V`om||Phz023B?QtZ^9u&R5OO++xIzK^6-Y;C;x=g z&m^3leRmd3r!wBcRx1`z3zaDxHdQw(a&%c$=it(YbL-12y-`mol$+5X$8_i60*zHY zzjbT=TpraJPq_JIkmQ(2Hm7y*FLO2^94=tGOR zArw+}f8H<>2gF4EUhzMX#6!OFUVThjc4gJo?N9~SNT zwhapdGSf+e{zLNiMkNNX?hGy2DIajQSAnSH7O*}^a8>*S1*tnarVHlInK9!O=CRc%b>&uY*xRb{7L@;uOV}y`h zpf36XNUYDLc&{TjocLIUtD}(Dq zMI*c8^-fc9nuhK+bQsoI)9|XDRbv|HaFwTB!{LmXGS<>lmImM2EaXVToMHg3-?V6Z#U)>SOvgQM&{|?Bj)aN1oC@rBM;nQ0! zR-4SSZanWz+ISyRG=~bkrx8S_yeff8=m!bDuwV{J>1&eJ?{RFhFN~h7&r6Gb#NbbR z_5uI;E+rR2A?P-kJYtF?C(Os{-*vAqRD&0Cr$hw*5Omh|wkCIB=)1zz@%K+Jhi!6< z3gdy%l5Vd>s{M{v7}d2#r!vCCj)p$ddzYe{%t*?gPpoVfCvTd_KUE0rdZTd-5&!0@ z{?7K7MD|&)|mBZ4L8b(5C-og9m zbQb_Es+``Q8ClW(L{`N<`sHGM~e?hj13Y%C=YpNjQIgK2fnius*-c3+3DNq7a4$jt7?Gfnt6={nF;U zG1FV0$UitTzI%CL!nd#x9(-qpXI(l_8|L3jQeDIKCz75=SusC8bEvOS>+isb?L=9H zd??oBnimv{_-i03?Z0U+Hz=R|(0i$ba}nanLsw07aZbbLw0eCQ_sCDfE9ATBJ!6c{ zZnHZgYnx`S=lFBMD;xBsgsXS-7myKU=mPD)I&Yo^$3?>d`3G6ehj{#uQ}V|iA0tn> z2EþTc%vFWk1ut24*!?BT-;#YJ9zjl+h?w#-YOe`mr?*fh%G<2ClQxW$ExTmf+ zO6U_6`K8N(-Lo-(!!%E>quHd>!h7;%eco7SxD^%+;t6N?$yK9I$N=764>f&PphXo5 zt@p-cTw$6j@$1;?=pg!U%_`lR%Prk6=JY!2=$#-Ow92i|1Ek>i?6zaSskj$~9sV<{ zK}G|!^vA1~StZ@Rf5YaEe;ARMB;S9R&HMl`TI1(Wdj#YHj>}jBvZ#U2Jnc~3=UmD@ z&z#82ezjWrPQIdthBsj?dUln_LiUIXiU(H(f zoUQL(kB3gx`B10#;@L-D>rTj;`$W92sP~;DOA&Ew07>O#!I2Xy^0+PFj)!R${=@0r z8ksGyS(yk?17{2zm{wgW-|vuZ=!c|{-we~;Tu`>Vp7MQAM#+Rz?a>GYO8cDRCY!H} z)_N)-o=3`zUdEcs76+!`2L;Ltf|RFuD0p6u4nC`C!261wyzr94u2O?z7%i0Ayb^E0 zjpoa>=xoTeG0G|cBPtVb)EJw6QE+Z!%b$_4BMSd!m}3+|@yw@ZCY?4wHt6Ir#vhb~ zlG57_i*_;^AVzfpl>#t~({OH;D|xanGPMY-?!w$y9)yEHC?&Ca9j{$4glxW>%zMDD z+4`-Y5UoTxgB)C9OQ)$wShUKY+kaQZm{x4{+y2bvp`zEfS^HPQzDo+T9qETOp$}Cn zFiu`Iy^vtCt{e2Qa5vpsgcewLQ?TD3MtiZ}4gnlAvmR7lstmY{^Jr7~U|5Bzpv&k9 z%&z1deQDc2BCt4f4?NbnV&J~ks90w%bVi_fl1Km>+{~oXK8IQt{qRkk9b8dPx?D#W zk;NX5_H*?o4JKZRNp^h{OR^Y#D$>`dV@3_EWqIer&)I^>6a9%-*@d>YH*;~~Lk+Su z_NANyvA^2m((>PU2sQe~85tBCV>#goEN~TrC}^-=K%tSTmU`-O9^nZf!ErXb`=F&_ zlbR84agWYhAu-Pf;);lVV?lM3~J-l#zf7m{YOkZj9CN26$FWcx~xmxR8 zGJAAckt`e8mWBVYXGj%r^E(8#!KG-dV`I2HRiWTx2mtB;^WPQIbT*T+?ktVX1EC?b zzF>@rm7Z79kWE+r<98RW%ioV)gkrfqLyK}h)|7y>-zp={Duff&3-xr0`yK+(5^@DD zVfHROSYLD)@!`nm+hKAyt&-~$1e~95!Nq!&iQkKX zO2|de7pspXyrB-gZ|b(`#7-q*E7Q3Nx-!0xpG4vDr6yi25;&gc;ox7G){@KnI@pLe z))qj*qtL56l6vf$F&@IK;HEz#M3LZ96-?Tf^<9_UM>fx>^EH zy2vw8xo+K15Wm#h#LOVpgbp`%kLLcsi0uJabz(Oj=9SXVXk4){Zk*2@2d-B{z9SyS z%c0A^2u}w;HQv3u`!k3GyW$k9Cx69Rnf}H{<1T)O5Yj&qEbe&-eWY=Y2v6%Q2@mYE z>3rm3n>TeMZx^VUdFqU@S66n$maeDby_WGA2#zIWYQp0Q!2UF`4|s`^fI8F6#3)Oi zpxSeK{jY}AKO0im`aUwwCkh=u_}b+j9~eLhDcS zPtL@7=30$cmv{q_?velonl&FJDiygM`7~wKxx~$$>@gvubOls^8cTH*Ntt-<9PtO> z zCg;_ew`E!S>@NV9TGo&7AIP7c?_V?%jjB2z&63xn!s)4}6G=1Gx_Y99j$o6Q9pNrv zDxlXcU;bjv+k+xwSntV=M>F(l{GbY#%TB1NE)YM&C$zgLIr}b31Go(US5KjlvW@gK zSrw5yAL+ZG*A}^rw%XfgF(5ZxqsrlpCQyF4^x0V9$0oscrQE|$YUUxPpMZ__^&HEd z!C$oN0-xxAt@s?)*7xpqQYXUQY9KFZX!cwHVpJ_Z2nfN{6OL%JQUu;y2+_8#-WWcA z&b6E8QJa?Tm1}G{gF?kYa25E^qdpjn-?=H9hIk&hPyEA!y}>K`MHjmlWs93QkZ)G1 zdLtxz-Nr@USYQP!dt-xQRK)uCUcImQm#LrjnO`hDxTnuI`o0JFaI;h4UyABt50 zV@;3ot6f@KSJ&b1ovfu0QC!eSNbDTi9}K*!JWcGDtx!FX&^G0?Uylz2C||n2wMnfTeKyb3SNJ1B(k`7T&qT`Ian(f1<8F- zy-NXeq;jTt=$j?Gshzq@;FW&pMHZmnqZ5U_N%1k!c zV{+k|1zdg|-C=p?SDbyNQ?4bBlUQ>^KJpuX9jijL9B~KLLgz28SXtX57C}BzxojL; z!a?Cfp!*^zX*V^+M^@-J_1@lCr3TIyf-p~78h+X#21@%iHZcvXTKO20vL< zt((r*{+x>W#|gpy?g3gO499pnrw#Bm`l=CVh`5sKhvp?<*VTs22C1qe1Z*;96LMyZ zw;l#(0ZY(xx@^ZqB4&ja{l{!wU}Ist*88b%u3p#QRD{D5rx+JoqSY*)?S{*iSomiXaoniB?s)Ih`ziH%o168&o_>{ynJzG% z+CueLsgh7CCkuVF zFR_{7yc1+?R`5@n3WlHlF-`6O%!&sN{R0gpsdwCT0Da%!D*T05$+dJL<?hg@i*LW%!HU~$tEH?`&0YK0!PBoypuzBwxtr%3x*Hv8 zJIN^33v-uC@Cvep23TvR{vAA#LEfCI3vX~<*&K0a8rPPY-&g%<#UlUMC)T2Jk)fdCPi3+h$kl4 zs%s=3zL7eH`Woo;ca9>8f&!qrs>C@~Xhe3-WSMWnO%0!?fWK3cNlI4&`t#t|7neH~ zsB$mj!shgEIJf%(FX!2uHyBjWxY$WR&072DJvlISEx4|@Nd_Kb>_*`c`|$dtGMn^+ zA8G&~*7|Rrx^zQx#*+I}zSZOo0)Rra%D@nI*jx&SV``H3Q~z%L@3`tS*>zF}>FZTQ zvc;hY)T~wNp>{b7(&^!1)`MN&MJ?9-;1_>eLMMpOC<6FMivKIL+DNJZ=^-yFCwHPI zR2W+70S1s01$P@}P7)53yp}!TWY6N=i23YTWVc;v5AV!*Q~-X9B%OngLatdu?*X=l z{hdkX&)rl%(`e00+JBbU%H({(W2E@TR^8Py4PiI&ssJ07ea5iw(&tYFSyX8gvKX3R zFYw}Ag)8DHl4s~XY$Vxba8OP;c5(cQZK4eBe(TQU}?Ry z>bosMp=90B+1WM~m%Za>tN@UEd-iY#`VpGqldt8ap{JWVu&k;n%1s6mS9_j(3IQ}HYY|9NYtHJI5oT!uin@Y?$43%eQjgDE-dNJgwx%oozXqd$tW z`RjL=o+q7*PKRAjzbH>B7^n6eepq%;Vw`mrwR~g%zn}|$BP#5i!KBAi&hd;@S`_eoR=T^qy33rkbVi1V_9@X-!#uuIyc?q)4Afgv zzq>rX#R#O}z6ut>dvW5>?Qzni-Eke~ks3e3RJ0^0JkA+cOP{5|5eIdhR{M0++0O>z z13U1o8?cL8R!WWEfS2$T=LP0rJ>fG6X_)r zB?8^BZMd7-(8p6D%FY;>x5HZ#lU(`3mj{O1UH?zzUnA;1_xbvyaxKpmVBO|6f{@~9 zAk7G1!MkhKz#$E#b*Mca3=oh{!O3v2uc7ipdsp-_p@s2^VW2XcC_Aj;4ravguEL3g7EyR?XSJ(rnw}YgZ+b8A@^VvmMac7g}g0 z?oUbkl!yw=SlZrfz9vQ~_X%m5HrqZ572xxYZ6?oB);uBe#Aj84k|0$!EM%Uk_)P*O zskroDEy0RMzqn3`IpedX=oQQyO2>E^+3z(@>=^AV46>&LMLnWY!jRRoAIGl&%v3kF z`!U;3O7_}J*UzqnQ@SxrRkukO;SkfkkG$hwx1*aOy6AI2mb)*=s~mffTK%fpFTA2+ z-h9SBc1xCpf&cRh=A>^4m=nrK$!LoE>FLFWIU{-SzPZA~*%vzgVJi06M7s$9=*%3o z?4L&Of09|*H0dIM{$1aS5a;B`rOc{PTnbbX=n8kxtr_q|_NBwV!v`ZA$=1 zVBhA_NiE+y&#w*R&MZd%-hLB6(;!~BQ}sUj?h zK>g>EyLZz+2xAyP>asv`BZ$I?Xfi<+wmDk7+#nB*g0O=?rj5Gc@3c6%guYSSrw%cK zV=K2REAZ#bfkLx<1X1;03#WI{`dY}6gDX_%n>rd;|k}Ts{G{EjQ~I_ zaN}pLaLwi1U>l6+X1T$Vi1kzBrhg(vFy&;PIG)GBu;6v9Uw@->Jyz>f;TnN*!;G## zHwGi8&=@`ckJOcyl3 zsxoKEq+~+k`F}WAx}^}P8}P%H@?&{RuQhtCXx{|6^)eb5O*R-zBTo1ZWOu7}_ozFO zg?opDb3z6R_qU)(!6Q&GW_+ev2zkiDrn#G>os8;HFrj-?bja%FGgHa`<~lKjar_cy ztn{3?pn8D`;{Sr6l(*!5xOu(9z83$G;D=0aSuv65qsS&7$gix)Ue!NzASoPCb`*?2 z@!m{a`UHjiVBia6h!P{^Yy?$h03Mc8IQ4c`h1`eoR)t)RcffF!wVOHYNOg$Oh0&B-p`Osd(2-&)UK3~C*ylcdsp zDF4q4n8kLz+wv59#rNW8z|<30;N3$am3TV7*%Pi?tiaoR_#D82Kco(4ZDbcrOSHU} zSB1lpSF6wHloC2<60q}FlT;pAFtpe!z3Iyh9h@%Ty(9@pdM90k?{F1Z4V*R)Vp}Lk zG`$Udv?E$QIN9n+4wHT1qgh#S=wIX#86%+JD0?^5o3Pqb{O8BBiCihJULv@Q@!AYp z%*348qeKk>Jzgg0!Z&e^Qj*H1|68icIV=%3%A2VnB+a2$5-Lh-^pF}+yHs{08AJ7k z=+(em%pbqi?~JE?Nq>7&fB~TUnLDfV=LQmI-RP3nrKO>J;~yXt%lMgpD^`Z8uY=&) z;@IhCAoJ*C6CL%o{rX$%4y(~26ObAN!x z@ECN}&PsfrUDbGonJC8MK*&8ga{27MmR`$n#JUy%Y+PV;UMw`kn%fW>9Ps81w^>oa z+cxFqmTE75niPl<9AM}Z^b!5_iYNe}j$ef$5-qzbm|m7C5W!AJ#e!g}9niw(-}5N4 z{%EttPY39to`?s|EX2=l&m7SZtUjH46Eq1gBGeMRjwW)AS}sIN)8#3sFS zX|isL9}B6#bL&;WHlf6dyEZ1GVxkNF3J{6{ebI0 z0q_Tp^KiuJ7Oacn$^2`dT`24-4z@L!J>j>kE5WU%^(C^J&mOyZv3rayg@(8=JMK7X zl1*Vk3s9B^x9>v5!>2PKVvzo8K|Z?3Ph~&(KP?}{i)}YTR9__@Cneh;*UX{P=!uBe zc%0;NHOG1G`aUnt7@#_`dv7Zqs(A7!(eknZo-~r)hXg9{HV!BkU1cBdwScu@O-U>E zl7$-9>UTV}#wWJ-kY0o7^3do0TMFQkGYVRWhy&c8n_?w~rwwgTI$NuHHj?{7iTD^C z$If?!M=^rA?bLBIsZQ0zLbtqu0HhD1eiB5k8Gu5>;eTP}oM)9@j)e*y$O55iFA@E>UZuf$mw6 zA;2MeUyy<>sYp}ikLA<1KV?X>%LYU*&OF)#6|o9kd_ln&YnLDtCL9m84E<>Jtt|h@ zH;roPF=A-GpJQARLMKTuI%PX};Y&S@60z-Y4)Ck;EDT&cc_xYkpbPv* z5H1ZmyMcw0AdcY2tgkjLf?s+ZxptvEYaTGI?pC0=6r=5r8fHLENn5c--a6v{06I!< Ay8r+H literal 0 HcmV?d00001 diff --git a/conf.py b/conf.py index c914ccc1e..648cc8a26 100644 --- a/conf.py +++ b/conf.py @@ -37,6 +37,7 @@ 'devguide_overrides.css', ] html_logo = "_static/python-logo.svg" +html_favicon = "_static/favicon.png" # Set to '' to prevent appending "documentation" to the site title html_title = "" From 86770f21ffeca9bd6f0f9c38a9274ab2cdcce0cb Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 30 Nov 2022 15:42:48 +0200 Subject: [PATCH 011/538] Use sphinxext-opengraph to generate OpenGraph metadata (#953) Co-authored-by: Ezio Melotti --- _static/og-image.png | Bin 0 -> 48408 bytes conf.py | 11 +++++++++++ requirements.txt | 1 + 3 files changed, 12 insertions(+) create mode 100644 _static/og-image.png diff --git a/_static/og-image.png b/_static/og-image.png new file mode 100644 index 0000000000000000000000000000000000000000..d792932b87e43d923608d2aadc841e7b0a774fcb GIT binary patch literal 48408 zcmeEt`9IWc_^%~PWY3m0C1orj`<5hy5XM-?B&4w~!yw_2J(QlY%Tf}98T&TYEZHN2 zj4f-%I`-Z9=y{&+IX|3#;JjYv^P^YX*YdvJ*ZaEeyC_3_Z3en4bYx^?438e(HzFgu zfF&cN@S&v!eqwMpz>16vH}&Ygh6!?PW#W;ul`kL7h6JrgD81+mnMk6L2eGJChM!QT z6xDi_b*3p>&|@apP>WacSqFc7$D`Wl7IJ3Rdlc)IDRd=`z^-Fnw>*yy)4`F>~h(CGk*wWu~YyAl{e)l9`dZj&$@;&F*U)z}z z`v!jpwM9(^6$ROz%%7Gm2QBf~1WApZT9>O$$(L0AkZ-7DDQYD0*ql6q+s?j(J0tGM zHXLS{c+B$zvUQ92M|bb-awe$>1hyNrW^OsG_qw#r@Z~Kmti9=1M8Mbj_A45>fg}X) z>C#qp*!SeuxIfSPLbq;Z(l$Q?I~Y_=(b+*(S{<1dTk&-3L4wl7-7wF)2>s9V(2`mN zjGZoCzBIR}s`LlpsyyLR7`;JwGtCEL;lWmX#Boi=+syjQo+yWJiOW}wi^KH1oxO|R z-U4gZma_w1KNakgr5b*~rBG*MxB47LoH_L%kp}!SwyHG!mGs3w%`W%fQI495>3_ry z(RA~e@0~0`1$~MJNop?(7`M%L=a}vf|1mLzm)B=0D-NX zc49GWyRn#+&+U+1qc)U}6%6=EL_^d~5<+QYijFdO_4aLRrlsl?QF*2Hoj9@88`?=W zkK-g7lDW*sAH9({xuaNm=Wj0aeScfWhDA_YMgREka9_HjeP~2l8jKQfdjI>aHTAXO z6gq#Nz}$B0nysB@H9A`j$9k(Y2Pq3OVLul#J!N)AXe3ow^wkcn6i&a(Of2PtsKBao zpQ{Kpo4c-+RujE?ZdKCr3ix{G{INAVe{@DlaiucV@Tm#-b2;KMbr($zd?Jo>hqc7 zxg=!mGUQ1uo9T$%q2N(2UOW*(>6UbD9^YOEBnpJhDYWVx)%m?@cL0CDR64qL8GKDQ zAZj4jw7in_D}9|u&dJ19`-mod#`bqw;e+J|zqz4EaVeFv<(p-yd5ba~;R|Yh`vDut zR{>i$ewCeBnvNLkUG9@rS5_dXpwvf>pJWdnKmJ=@U(Hi7{pJ2o_nB;0a}?%I&XBK{ z%#LZX5rH6CJT|cW{qZWiYXWENhpNYK!im)L__@(w|TvJbH+3P?MiHc<#Tdhkr9Mlc!d!*2Hkq_Ve>vC8CyQV2; zVPnLNhS^2m1_k8W;2zzg1U?7nx%uw-9z8nm>vTlX?U2AX_m!cHD(rbG;G)&0csq%GpY(R)vyeIA4 zkjq)dgny8UX^c0j**mR~v^p5PcbqBk*p3`9L_l!lEOD??XZ1&iqzY-Z#o6n*d*y-Y z@k5x(3t8kZ(%Vdz%1zYG0gEqp#=?F+D94nj`yt-$HR6bu&5YL<2AcOaN2kXgKZf$% z!nC^@LSq|ZHVZ6aVIRJ7r%ox$-Qi3!FPeMkeL{+5b~)P`U8=D;PO4XqbveQ@DY&|I z4(EQY%_U$zYFShAp>t{#mK?$tFB;+ZLu;Rh1;JkA2 zC=-o^Ue5ll0H3N@NbZ!jxGhU5;5@)ZvwF&|i7dq`*~;@DzR&F8D0S6UH@X74LLif1 z+{u&NV#$O{rh!6c;-aAL7G& zZF;AntvXMVb?ddzMXA?;h-w{)kEAZ~x~&53{*vYvQkMi9M&BhHi735`v#5B$R!7i& z23~y@m6{}y@N{{9G^{HT-T!HFVU>^^Pxa>{ewvgz4_rMxelo<@VK=iTj~BTU*hUaw zc`CZFYN?03N6f6K_+m$IhVb*TG3UgzB(CDRg1p_?X7MrYGkBe*E4szIsERt5JC${T zCO>D>3=8zFj?BS?{jKixv#UPO{x}pY4nmY=b*%*)F{zxqYuw${X0xas^fA}6C4NkR zqA7-JCm^NTG>g&h-i94(pfirtfLs|UyNXgWH+F2K_=(nq!mel6Z1od;yne0ik{;T3 z&tqctf>wKE{x}ibo5TVl9(|-)?jJw-)jT2q-zrkccGOz|VxD&kx|9)MF9=+RKr-MREwfy3{YuJW;Dpf-n;u9qRecd!P{4%v)k?<(1Xhb}@D z#cMon_YY`Ll60oV(aW3KGzMIm0VqkRFlAz`g*GdD(KQm>;}h0pTf>jghKcUij+H#T za8~h8Bp8w={pQtt7k#hvO$O{uFAIoHp0>TQhM;FrkQ>k)4k;*t69j!sOb$Sa!#dm1 zX$#?%&toAYrLAa>XC$~^>`nF}2!B+D8Omk$tO5N3tM^hr((KRQhCR!j!IRr;%P$*D z1+M=bQ8&b8i}PYid3kyQybTZAHBLxfqkW+Fngp*lG~2=~o)|1!io4%hpmdsO^i%H8 zrYD^dhF7LD_)gwm z1(75j%c5&t#lzhtIy;I(m>^u;fevbae`sj`U(>Rx8Dm8vJOeaiC~X(O4H=NkIHYWb zF!XVXirh`9@`)T|g*JQv6-FvR*n`WV144;hYtRAzosZVBUzN-InL{W3~k{ zmm;fvjZ?NMV=r$3I6aJK;E;sYylF=l^O6dTC7?gw^x#C{xGoRx?}dmW*8E+JUU$)Y_9?Z7e+zG;59ibN=m$FB@gT4lgZ-GB%2=+ z{mZa(5>}NWYCvfX_+*qhi_)no!1wReKl`N3(v`K;%ou6{=H6 z#DaVzc)-)#vM!EMy}+OJ*=X{Px7wD>KiPnNFktDZuTBTVWuY*`|r@o>2E&-;O%`J>wr@ZeQfZ~`5!|)y)eUV z=n8VQy~2}8Pes3Utlz#tMZD=|*}n(r$4VAV@InNl_n8__f2B@9hTA|8ceORTo{rYN zq0D;B5Wqre1|~;pNuy!H4OIq#89#jS2!kW;=XQNwWZM+3GC9gDf@|IUB^{a$O1SDq{Zt_W@l0-O+fD8}jJmS>@SE{p&pSD^=cW zs7OdiO|nS&r!de?zd#-3R@HcO&HJ^cmDAeE8dl%E9sy;_GG*&#KTMtS_!{xzl)F!a z`eu5=$7=kduXn^V;uPD$0@OthH&*pjp3(K)$50SShxeLES6W25pV@qGQhV$37|V-) zFc5r8RxPvgs4GC}uqYfd$sQu=IzJ9tt%kX)m7J|m?gVfIeR?$|<$L>3IAyA+(rJ^4 zFXZ6H&f?im8FzVviTjNw3eb54rQedL6kM zhDL6wOPh&I>I$7pXfm?fVtgF9?BBnE_VEyTbS=Kz9q;yP5v8oaiD8@Kv@lYskHP%( zUuaBzWi7??h}ZfuM)Fk5wTLZ#W_@N#=D7%%>hr5^_T+We4yLvzn%aAMR=&6{+42cV zuUQyr7R7=*R$i_hzt7KjHLgSZ z$0F}d;pc3MH2f;77qxTcWOOqth*(IGw&Ki{nqlBFC%Sy6~;amkBcOhSqia z7g<+M2@HK}KjW?HW1{Pwlp3T+#Nk;sj5ni8l?2qD!AuC+CQ9f)m9}TENAAV{7jf66 z3CM@Z+`yxLRl@{%riDnz)s$zU`4f<4^Hq+owT5$xeQO(Pq$?JYI=zI!$0v$5qIQb@ zpSv9N__WIy(d#o{zb)Zh+>4t~4`;C_ zlPddFYm5CSaL=r|7KwjAC%FE-I^mMp$-DP7&_H#+qpYFWP`?@Qx>d_W9W#brtF<>| zXXYR?VC~m?)8mHz3e|kB!gSJT!a1;~;*nyyZer zzB1S%e!v8$gZZrMAw`cawErEvoAQj~pLBn}#)rk73{)}Vb{is%rHqv^L-TZf9mIYW zL#vRV#xpfeIUsGaBJ9@jfn6&x-L;rrJj#$=@-k-S#tfBO5pG}$yqdgAl+A7ZlssKL+8S|vwa9gP2?*tDO8Lr#@Lp=8eLpqh2U7XDr&0?q*pt+_niC;_cq92-8KDgNGgWtKO=?a7t zuBMJYU9T-t;UK|v`|4|r{;q-8J3(e)xSXAW!*4FH|AghPkrK@BUQB&wa0QnPFXk_= zizL;x>6M^>!<@#v`nx5*qc=N$ZR}1Ta{}?tRH*$LUH?q_>BKm?3ej6H&5xN(NDq)T zJx1COjH64%$kF8_+rpVqvz+a3h7WOWJ+f==@;&n^571ssQT5 zasthAAe+Gp$t<&1N7Gk27dg+=S57;Ril_gIG?nTG+JV*^h)A)$x>B;!BHrU83FxW? zw^hrnJJ!&jHFCEjIk0~xv^QgsQ^}$KG$J|+wR>C^yl%*O>)c{rL{q_gKogAx3b%lJ z0uJMlxFof)Bt|{0a@C5;pZbscsspa+xM(ZE%y}@o>`U#<@TD5avM&^D&W*8%=E1aH zDlEMgO4>|hVZokyEP5?wj%D@#!+6Mad)}+*mOR+)Rx~OY0rA-DsW024<6*`QcF-!{ z5V7ti*Oh~I_STPql=pO=t{Nf>~eNAiMx(l1`pDksd9(axw{q1 z>!X1+wAW_~C&2!k=V(6IBiUQtbBY z)z=yti>5Aq498|W$YrPJ1_0J*8RpXxFTvyTU5d63At?V>9Rs?VRS3P)_a8;X;uzc2 z!6co@^jzyxGJH#%K_l>PEIZw)g6FP*cZ@G{#1=X>FwGI(nvN`~JN$0c1dqnD~d zR@{J5wK9siaGJJEC<|24>+@Z++7CnT?J|%A@?pFFwe#*EF&J?}2G+Z*q?BBfJ~6}fi*JXtTa8?^ z<-4Y*?zWmAC2!pvX%qmLP7GKBSAGn2vsB;fg5e4#SxIoSS9_>tWCbhs0qs9--|f|HY$yHmgVo&Ia*9<>kCkT$Ho^jS<5i2-GENb2ta(C z9tSzO^7eRnV_lxbGo(gA?15G(4Xft{xp6}Jyhuy6~#Y2^KFt0j5`KWwuH@E9(luLf zdqf1g_K053kFz+A65fn5n;%fUC$DZH0;YX_+L(+xBv1N*ClDulE*U>``=)0$$I%u` z*{eTiz-!s7;j{QCCvzVg7b6_JLJ%rz$%fH^{&z;8G!PAG7?liVVgqvCf(?^CQB@%< zlsFoddrB|>G}BbiF;#1vn7G5O=)*cYv7L1xix zU<%5LW))p|@9<)VX$tAsGzr~^2?d3ld>9?+^C7=B=WpIq{(m8Oxm*HPlSnyi^(%YT z94NF{$dWL1k+O0BuivRPuIuUfgIh7fJ`zxRNw=h!OCzWcJ8{GI#U zp>x6P-Huj0mu~XXP}$Bl^q}l7xG=0+k;S{DS?3!kUQ5AHE6X zp!Gh`7OCrl%RydZl8fI`45T)mvB9LU1~SW2x~1d42JUv~ulJX^2CdIu`45PEK!^ce zosWS4+o%GNHjemr45U(=6XVItcZVG#=e3469GE?ak>0;28kJHPB1obe3T@~rd3or( zk{r@%piDC(f-Yx(M&=dR{vfY7FKr2B}rAzOac1Seg>c4 zAq9;!moHa!!%6$i!iJHk#deMN=hj91PgWi@rCRf0J=@V(du2?eGp-95n<{`ofQJVo zS{Mfz^uo+JK<(Sn-c6#y|1!s;WlGb2XFWM!4-^IQUx2c6jh%V|mG&PMm;-Z<0FU!I z8!Xa79xwPpfw(I(l*6u-axaZkv7d<7e8MQD@M*~4ONo8n&5>= z?PYZ7XTw5oL!1!1_V3C3skC=KIqrGw~?niCL(x(@x4xc}izYo7c%SfU6_U(ni zVx(TUe%dFt5z{c?tNaOfnXZeovS#5WW}YgK-q3&J@}2T^t0t@9i!ibd*u&MK$DdQm z8JVs&afQ0{j9RQNDekQ;uT9nktWS2VMNi3Z`Gwtnvs=0VSI^v12b#j=tC!5=IIxH5 z{(bcp%$_^oIg-xLadfCC#767Ia@JHAy7l2KIEtF2vqVIrJ|M&Xt-rgtgrp>S6#R3; zBk>M)ax$(cNto;*MdEF%7xH_e+g)hnq|!|ejKxQQ*PqEl{V0d8{2L}R+YB5I_h`tQ z2pS@o%v6#?XvkpKUy-Bt?!~#>6ol<`O(}gLwl;q!iI$=uo0W_Yg4XbAT3(oi`@ERz zm5f(dF;EtTkF@`$E7UW7x+TFwIO8c9`{ls;us zm!zltpC4lb#EWo-ohs=ZcA)4556MAgC3_=^yH6_zyXF3I+(9>$=0{hA|q zSjrX5;T6&vE!JO9=>3k}{KM0=7d$7cyQyo?cd|BiTBa7OSNlxjW%& zy?*PB>8Wcw`vtQ5w_rQ<72lNhwH%(U*B7==9`VbhFsKeaTkGIokC&07^8dT)gD?3a z3-Re`N#E4hy&oxm%radr(RF-0a&nL!@!C{Ix&AY9+}#i+T}BM9M)B>v|I4{C)8v;I z|8t(_Mq0~@kLHVPXu~VDnK7*3R`gpD#)4=_b`|3T4$NzEdP~}WWJV;s$)6R#5wovY z;rfZb>B)e33PVSxmEn}kHR(FLw3&lyi<(<_zC$zqvHO@KhwI?-ew~7qWHn6AYF;Op z#_W@4*pwU>FfGNtBN6R4uhW}3?ItWy{j2B5{!r-m48>(=W=i?h+pyIU9|A1pK29`N z46166#QFaOaboFgJYNOL(wo(>{3FxIB3VT#hdHb?$nKh8&BWe|aZuQ&W(GYKt#j}a zok~t>HH8&1aboA%K`0T%=yo)-2qT;Y6FuJnvT5>X__r#^{uG=4Oq7HdXj1Pob>WGJ z@*c3e_cjZZy>=T`^k3r^O#O1n%+iC3oJ^2$gSt@qESUW%PShAV1Iy?4!n}!s$k3TL zjm7?#$iL5jFPJ9SkX#p214;O$voj7VanCitr9Rnb{kPMQNdCGefHVpCB zZ+Wk#JQm{SSm|OoJggCg6ux9eoMm5kT@?F=5`t+I(^WKzJ~J9)j2g2ha~iZK9zAXb zOV9O_pC{+yb@KN3{QS6ED^ewP>sAI$Mr;_?kK7nj?JJnw$W}C@r4{swYFLa)bNr&; z&8w+1>z}Ll7nT*-r(SXwy+7pMxkj`nYQdRyz;O1Rh@o{O79Sw}daVJwnNRkr*CT$d zrF5A8ZUJiozHv?FJ)}^sh^sfZnVeKp#LpzRSWW8RD9ijx6)icMDIAbqb-JS{2J21ggRulfFTCWe0~N>B#79H7aI5bxnyaOp@y>8iBo@EY z;meXUe9v4C@UC9)k?fJcoghP``Y|oK#8wVw4rC$OusK@K_Fc4U*MabdFI3N_wAxge z)a^?2QX!`fMn?8DF($=XNa1IW0RTXM2SeP}?XZhRSA?dW|qNYn!&MEy!qHZ*#K2YB&-tb+u__^Y-AOsf*Tt+apy1h)@FGnqEKIdIBn z9Kc<-^4%6kBL?*zhaM;nzmHWMZiaXjo=p54K0VcXEYdGA=D(S-^7(WNCxVk07oFjl zEEMn1vaZgJSKH0#x05sCNv>Dp2?$f)_5D$@#jU}wn)zg1CS!|s{XzB%p1RzMeZqWM zqVKEKtJ(M-eM~;T{B0&$y@eIpx37u|LS-Jojt)NQND=x(Q1ls)2Adw=h2p8RUEF41 zV}|AA72A36rB<};J7C2VENi?r4vIqV*o7Pi&zt|cUz}8#Kvy*3rZ6{$XT*<;e z(LZ7AQP43(pq2K6k(5pp*x-A7-o-{}LKCL1r3*mc#L341*Kf1?KWNCvm}&Nw9u3)` zaeF5MI|lBu&qQIevvd^9L3q&+my4IisU0g7PlfVc-0ZdE`_k>|<83d`bSyy_JF|D~ z=1!#!)-2pvrrh|96>~lTNWIK_ z_2A>tq`%eU^A3D}B03Btgq+Q=SKjI6J({K~bHRSKMK_lVE z(0W(pZv1n328FUBk&fh;%3Wo}v}BQbiE-lk#Yu6Td3r~n>+Wbr%2LU@pFDOCD9c1f zA9tkF|D{5-GVD)V+liE^ml!Rt{n}R^8{*^DSM>*7@)f&p`>(`jq~GF4tMYHB_KY{F zFgt@IWNv-$@(I~eF)gRAo>ELQ=l`wN*SfRqF>&fq5{$a(yN3Eef>-#E;HHrwtIe7O zEmJ6|3?sx~)_Bzyls@Oblw^{Z9amcqm45I*cRUlsEh4XTkmb`D&1C&ic<)>9psQz@ zo#H{$X5_k}SjV`~1+i<#uPrnJFJR8!9!eoIUqL<|P26NZ3%%__k;njH4z8w!G{}#~ z_-v~r&X^+J&IuA8c?!EFjL1#W1zC2g zIQV59DQadYe7OP5SM<2;jiaka7(T(#`ORdFRyI#iTpPW&uU6BomE&z?LN+igQx{rf)0*9Gxgef5aE(SfjR}+5pgo%o9qDQ0A3*=DrcSCZJ367P) zEG>{61iIfeGmE<4Gu6ywi_zXC@5Q*myAQjvfg1%@#xW})N z;4@T(teGEsDqdSz%IG5!2==dEmd3qh8rgmO4i(g|E^^6FyGgnyW+jUce z{ZrFW^c5NM?l=(bU9n$P*0;;N*YA`~l=L|ZT$yiS=lSf)!`oe=*uHcv#ta%83kf`Q z<{OfM;)z_C0;Sd}MtH*}JO@~#emofmy+g`+P$WLA-mDGZ8zXv1m%`Iub_orq670Np zeoQVp_|aO@v0&e9sPUx7K!8pkeDN}t=m9>LFy#A<`F#}`eLXIUfgarSkQKYTglR5I zgng+Z?Q=ui6%$@Sf-S%PHjZYiZAJHRy@71WPRMcDu7ShSYalG`pf(VuJTqW^Lhj2F zpe~R*r7K8TDT>4(oCSyYo#S#h zxzDEyKqhW3K&g6h1^64#+*TLd7#g_Ed1vNl?~a?HFm1liXht`Smt7FOSIklO?IB6w z;HB!xOAish#*HWU3zO;0g7TV2Zljc9532)U;z!}PLl3XPWp}{D7kg151CeGJz*Hby zH^)CV=8{gt*dgqI#A#}@*TkN6D!AS5;Ow~YaMQ;)#ptI`2qs7l0>|vNP?r{NCk$# zEVs{O=J^%%5VvWe_w8GklqcrRTb{O)xjpq)msp%;E{IXtI8p2<4+VW(%Z19^w%svq z42N6-0vWpg)Xs!is{6gg=Ux@&ckkrqJbZ0#3Cw~UA0-#YM12iyK3umNIu3Cy@ zKW%Nk%nriX%0a^vJPdcbKzuWJJqEy}3x%xnWyLM+XjB7I)~Ge0;%&Scgx+F*vF@ex z>4R5TO4BAU9bZi1Ajr1jNy#P?fUqZf73&4bln08IMQ_ktUgS>7#e!t*!=SaaJ+XkP z*&2dA18J)`yd9v{oRco}`>|r&m>3J@%C#5>_mgPI(}+rR9Aq`Rih+)DSWQclu;>Wf z1`YRsVu4N6$qaafrjRwolKPq%VqV}}_|6H9&~<#{J3O+sAl(rHs`1;F?N;e&hQD@R zWCcBjABYe2P^Su)dVd<-<39ON36#eE5eXGUj8_BMc>D;bIMd&J0|8i@5+e?4m~D3*XSjyp~ zA#)_KEFrtS->^$rka3u~1~y-L<^8oju;Jp~jq_>ftXScxU%-*w=T5buu3j8)TNF`> zw2zHN<^r#ozSb5s3_7iWjlSU_)U9agC?vRGw^d`FBs$au!UJ!Agkm5i+}NRFoTzET zW|tE=Jw(hl_MO4+b%bzZdeGXaPGqp~fz{7T?{u$di^-YoJ;5aa5dnrp;AmS~j^fde zol1_@yJhswZD2bPrm#e6Pt>@oD0CnSl3&{fs<5P)8nR!WHrA>9GjnRTp_3440qkky zx~|pHcc7iL5PnRd`@4a^JUl;6%T%Jidr4nCZGX^|fNZeIgAOU!p0HxBpPxvs8=?%% zJGTX)^JYgurFJ8PR-B93N0-p-MW_}Brlr5$sLaLC6gS2dhRg-lrfJzEQ7P(K)JzRT z>yXhUzBgF-xnW)VR&i?!9>4e!3jKB6cWE7=*q9b{N((gTtC?GOh)-g#4aaZ5&jl(o zmKjSHDLt9Jx|_W&?yBe|?|YQuQP%q_x)+HTadWIAA`vE}?>?P1kVzz7*lz~bN-8MO zwA%smcA#0KkQJs-Tq<8@4~Uxt4<{#y9+G#fTfIPbW&JJyQIUv5x>xMOcy|5Gr&nXl zV)mVai(a4GuxAHP3nyQ`Mw~@zoo^gy%@lgMf*my;{?&HxM($|~DY8=y`D&@yOUy`d zz7_O7J!Dm>6&?2OgTknw?*jO^6>TRatL|}I0VZ6)HO4OrJ-I7pRfPAS$A8%H!hAA? zvM+IBayYR%-dscc&4uVJ_xU&=19Qrq;)m-tU5yVV<_y|y1Gj|S{U=WgG`~jf2tl8m zho6E27}lS(Y*8!b`DMLhaM|lS$2KF-^}itJQMX|kwCd&7on2^Pc#wgEFpQ7d(Fdun zJb$MKu=8RP%HKdz3vmgfN?*JQS)VltfR-4zXeKOObqVg#0()ZjD>@#6OWMkqlRK*L zJL|HE@F{G$*F?8>-1y)m_5peKql`ERJ77g{FnjwVfP(Kz(3(YPN?L@&VrBYi3(f^O z?kwP0!bYP7f&K(YJ`Vi`!fHt)8xLtF2i=6?g`irVGt(=;QU@3_VrRkGyCRGa)M5Fm zPYvV25Y}JOTk6UBo-wDXy8Y1Wt6;+;>K)S`BezN#94en-~dI5v14#a;=$Ak#X-i>6@Z=Q*!>wWx)3P~ zS*vW8cA3Q+OR->}gMm9J4|3hLLiEE~RJ1uH8(476<2*c<6?aKY2Tmbiz<|~#YV&7&EIMHs&;d4`WC{>mapY#|8HlBFEQ2<8_ zE;e73pgRRNez{L^I`4Tf@avTfrrI2s1c6p$uD4^rH>CYaRA@W3n7FC6mVZmuxOnK( z7F0)f&vR?L>-}14-wfu8HI?zHrOIU|j=6#EXzzulEIXk>CuOysy@Ol6Z(a)&DUew#W+y531 zy(U_9iJGeL`Nf0TGJVg8-WGocrXbbxinp_gUmB9ULuXx5dRD2YJ|Pk^03iDjF2O7?R}`uR+`c%GfW?_rV6H(^ zLft03f)Rw7>#H*=-;CZHl#!5bQG2!U%v0uU`E=xhAgr_chO(?hn0-6wTteM#y4OT; zSHws>5m;W0sF^fuhtanViIp4{{ETFyiC>o9>q+ZKVS=`YncKVy%ZzC8D>eMaAH?T^6N z-uVg&_zh)P42F!?LO4Pplqu7Akmoe}$2FANfKO~KWNGskN+DP{pIGprf++gfsvG9y zKED;3ukY=g$`d56{cRv>?n3K0IZSG9{-OrhEEJX$^5-LOQtFQp428kc7k)Hcsre-2 zw;kPoF>8k5By8UPW74`$$7K_R*l@@b3lN5*w48xD9OCN~0x{sC#|VWrq2*hnD$y-yNX27b zyT2e#Cr#+2wr2E7lS}A{-Z{U(dc8>o+&%9K5wg~4!zc?p*a?YX4%oRaq7;4>i0GRA z@Y3YIPk5C-nc1ZpKNGU1!;1mFqc8rm$ih#`j``A?ue^+N`FdO_He({LogL42su&8E zp;4g_%hzD2IR`XfkC!*+#Y|So20V-E7b<4~mEfqXJCADK&=F`#-H}xyO)Zioa=7EU zXszsHFtvkXL&YV;=q7aN`$**hmg9BC&nx$CmX_tkGM{JUMSm}9G>Dz7jTsFcGqo}2fyOdZU@j1$s{Cf<*7CU2z0a9Mkkp2b4M9)@ zmzw)sPT_|YlHFAU*+zxE;!wK{wqDA({e>E%Aabdo8SOP4?H@hjB$A=Ab4xzJixPNS zg-zZpgOW9gMr2U`^O2!ZNq4E6o3>N6aeN3pvr@FB^Q(i#2NHxZTZ>jg_lX{_35&Bl zB~0@bT@$+MQxp2?>G6}WVT}nClRWq7A^$w=>E1I?l1xXnWfz*-@lOkB) z$-hc>Uu$H8Auhl0&6h=#bPBLHdN$@RjM0+AO6H%xB@3Q!KcyLUshpzcE75)$#2KJu zci|H7k#UfT-M-D%BQnWvY^Wyax|CO(+~Qd!jT3!djDyo-E8&-279${g$)izGhJJ#_cbH6KnqrxDy2t^DS3(CR;!=<4-rD?Vz}*|?wM@m*bnipN^yqQ4$gE`*Q`c)q421#j5EJII z1x?sj^e!2i59dFwzd@As`h_wgz?6gS$#7k_gJ!a>G|?GI^5eVB zUx3Zm9#_#5i)y;QW9SWf_5=jc_WX*veArD1DIP=LwrjE6ISx;hgj7s0S0N%J=zsX zTlHM`#}N_Vk6Lp_4Spcb{tCRfi*~7wqsLB#1X8Ck>#XUnOg&S7FtXTkDzmG3*(~9t zf$iwV%E9)D=Y?G!tfs6RVf>UMfVy{y`CH`DNNDh$$%??>9IFPS z-VFxJl<~m772Q|wdqIWu{JCBHsTov{g5-~ZFtj)!=wm_CQhGjp;oG2gn!V`^0WuEF zI9E0@Y-)*(ZD_@A`&v^&gxUo`jZ?ne#gceo8XI~{BWU;HsIQaRkI&5hncp_bPJe7` ze9CKk)))!>(P+GX18$I+yVvQtGJA1|&chLZcw(E}JM6)*E5^9)`VO(5g{Scjs+`1x zy5Rb2p9TfPjrduROl+7OSj@`oBpG)4C7A;~QY(*%(tvSCU0b9{ZU&H|(lp)0p~^=+Ik2 za9rPKGF|WPENDGCUwWr_>@QHff#7skRNTzS7kwzPli@dvyverTI5${x?1Up+?guvL z)_(KdPJ=<8a(DXqY5y_)kycvafbegpQ|N>UnQi%v#wxR(5!;|dQ!>HO^p(si$FL6B ztJFnrW66hMeao*ZI={mcD9TG^n_8sK-ZfP5%5U%&e{G;Ua-`_HPFV<+tERphq()Yj zb+C=e*{X_-wK-J`0rvsjRN8_@eGs^`WrR++u;N$=O4U!ima}%IQI{sroU#>+yU*Z! z+cX$4a_so^MC^8sas3ZybrkDw{Z;bBy>&yEzSu7w?eSk;+z2so^+BR;nXePClKdeq z)A-k3`eegT2OlIKEA|;Yp9|)=M`qUJXCXQbt8BM*5?VD;EVrghnX7vUiilF=(%1UA zb1LWeigx8h?GpPVkQnp2@Mvc9DLU$COdb~!+$d6V7FMoCrC3f8Y;T22GIHE`MdoO) z8?4pGK03v0HUE+GGw#7t(-A`oGk3sKs-|f1n>HMcGrUcu)VQ&hiQ_C!$oZ1Ndt4qwc(N4q zBhaD1i#jj_VUc%9?RpkbG&c|r<_VUajD>&8>^OVfxE?;7#dOY`)Zd!}xSYznG{pj8 zN0W0Ap~L$8rp5ACnfmFgKXYCV4NA zINF1Pwa|f^-o*x$0@>^tRTnRqp~YXSzdk-7>uGtgjrpeOuBUPEoYd`;oqRk@hVC&$ zA|yLno9oOiXfjo%5RTCN7SLoD2v#NzHteF2hMP&_n^qIH+mx{JpjY=|DDLxh!|u$@+c zXCDNRbNm5tm$9$t!>$14y0$rlcQzBP1ihLd^T0$W_2R54xrYc9sbRh4i=s@+Ck16= z4+lH8vo}NsM9FVN|MbgvvS4A6K6o4#jpgx`_AMpUk8HRQvJb*|vRlyD>+|-QIP#QV z#%?kYJ(3&zwSk_Uqm=m~B|@L!&y{_+;^0+Y{Q1#vtjEXRMB6%|^(AONUX^NbtOeh*J7J zQLN9~N3mJJ1880CV$+KXFHy;tkC>H=#wD1j&stugG-@8PGP|t{PHb6nd19Mh@4HsG zcMHa_y(8vDRkEB%BAWtB8`*T~!#v*Tf1(v*MWY}P{F4dRwvcqRqldkYP43ehs3;!T{L&u9S%}WJ5{}8|t-4t*Z`H#yd{@Uou3&AsCHBVfm5B$0C z*SDP+j>rJw985+>T;RnuNMBvMKu>G2Omd4&o_o*+_X~r^gt|BG**Xi?3{39}aS?b{ zr?pG^O>z z-Dd=uaJ827IRAS>xI^^4WkGqIzvf?#N9Y+5#=|g(g$QG@6cg0mj1w9*i+G*ODZBkR za7{<2U~JiDpiz_ICnV=E{p*(()Z}1S4>sx_b6{(#*ANSIaUUfF%=BT4a@OiM^XZ4s zM|;REsz0jG6R+Kr9rN4K+78xZymaSI9skCe3v;W5Aj|?UtWi02)`dOgyJ2!Eopy$X zKsh>l9tgSz!C}v8$OEh+zk+^{YRpH@B-0M@iI5!nhxAtgno~el zXqgeRmNvQ!2wCuD7#ULbH6?Tjjhg|K++PqP3gSXOOl-|wS4TF5xZJt?(9Isew zc%ilK5B!(uu56AI^x+E2ms=xYjkS1@OAcc}Em=Z1{|yxZZ5%gW8|DdW`{tht^2BSs zeS4Ha-KK0|h*R6BWH_4j9wfw$Vm>J@=?A4v#`8x$LfgNGHIGXqcp)-^t?X$ApzD$K z2~SsKewgpew2$MxSh`m@Yl?}ppaTf!3MDi*jikr z!Z_S2XXv|duG|NstypR#KW=Q#-0_?erK^VA_ZMLvwpR<+?-gz;NU`~1{dyQR_PW_* zzyhMP5nav3*FI&LvLD9@)1U`fW8ozqv-@^}$hnw9Q^X`l04ojH)!01=3jjrg8rScNp-~DITQYs%#Dbwc% z<9axFS%EPSs6!tbv-?%FN4|fp$J4Fsy$|^Nngm5vJ8a6)U3ucl`{F-7zjzl%*B{IO z-sT32u2DIw zM?5dwuV17#EodTsZyvc<&BvGdC<|r$`)`dSQ>fp`-5h#ZX4S&hz%Qcn_x7)o1?OI~ zu`GNw+JXsE-4&oZet;l%tGiY-mvU2(|9Ze{xmPDQ$)zUQuOA)%FQVQ%p6dVoA3w+5 zBU?t2#IaXGR#wW)aZch8DOnMxj+MhfnUx$xW|DC@hinecQL+^}wouvOAbb6udcQuu z@4s%Ix7*{|_v?N=uE*g^EwW~4HIkLtGDkfdkG`B{`Z(_3)}Jfoil2@!@1IW8lsSVz zte{j;Fn^<|(U0ceRV`AVgJibY{_L}X;EHK}q9@SIdBZ{}zC$tO(f9R<_oKx(d5J35 zw&O$*jc(#7ce72(9=aYzt9hQov$#ox7ICwAuX9B4ajCXkD?cuYlWG3dy6`;LuYJ4u z+NQb)R~3+jQ&t6Mg76Usyst z&IMnLPk8g!bhCbt<$Jos54i?*p%bJ-_LpY$E)czIcpxbS4R7+MYMq!Y9L3i#KhX6~ z;I+mV`4LM{>NQ{h&xYE}rJKMt-!j?uEL1~n*2`dF^??Mo2pEoc8rtlFhAp)AJ{eK0 z|I{DXR2Me;#aC2EKC&?Hcr4xCh2s7s%CcLB)8&4qil)<#6oU`NxY(b?cn6)nxgIez zG_7{{6(KQK{x=6G{*tqQBnSTWwP!w{Im|ljeVF0Hqk5*o>vb^K&|?|>)4yfjuC85X z^9t)nqn@pN=Qh|D?W?(}BvEi@aa5Qk+vxHE9xH`lJMm1?o7lVKUum|q(;SA!euq62 z-&$Q}`e(EdulwSTJAigt-S4@vgwm`qkZ{o~RL_VtfE$>>n)Ge8p@2#_+li|NEmb`N zc}?vCjlPFACs7zgHUIgSeD85XDh@i14>#)I|LWvDE&u&kOZaWSr z=mmq6I~t`pOo;=`lPY_a8F4$D6w5KaI+(Db$*edbG@m>xeRm42^GRp=C0l~thG&7H6|vn2@UR)gV#PYfA6UqFbrC;ntt`H z%9!RP_>9rU^z}j8+xPp@uhAHERb*tlnSkX^;LKzwRHQHdnn0`K#=_uIh zegtgQzna|>KxK4<7zZu{JFi0!rFw5sv73i+<`d-BbrEm>2b<9BzdtJnw|zoTl-#_w z=FCv#;+{f7i%WFyIz!)<98U^gH0<-Xbgd0`Zb{MOn6@S;K(O9$1ymMzczz=RePvf9 zLiy!__ohg>oVv_wtANi3MZbreeiNIrNBtf+>$ko0a&n6UuRZe^lEAvg^7jO(%r(Z} z(Q!PHN$SjCm(ZkDN@!#&Fb}b3IDs>)V%pMEN4ng8&pQ>7ooLwhVl>POLc$ePl5q`x z|MdikKA1SFc`ot=E8_k@qi`W~+x$GS6U#(^k1_bzg&9YUefl5}wp&1FDxei)oxA5L zS=!W@9%VD3%RD;qfbAojPQz_1WaXIp63M=5Eo|m^% zCEM1!F{>OH4X}s{og?>XIA)jVTl=wMDw|(k-hHT`ddW2$;p#ZC@EMZj<>*}zb_o77 zI%t+OE~$6aw>KTbn7&N z{TE{2w6M_N#sOS5c0j_Fo{~M`vF5s-!T|OgU?$U;2^zzU2<62So)qFUt^rSI>5qFW zdAHu&Vn!L<;P_!bUOvuccr{&Vv>gXtD+h8YD(6CW_}Cx@FE= zp8~@Pd-`Wi4wNkR7fZCWmeau+s^8TcA1Jz_H=l6)?0R|N!DyEzK{<^``E)*H?{NZ8 zag2G=+->mou#C##SB5&q6Rb828f2wenOxHt(bfSi@pY7wcR_Nsa-M60?emc;Kw2F8 zNHqrr(&1F|1douhPF&BEDa!e4WSjv|v;O~f;S_OEz=#?*k9av~AhJ;dwBx}j2gaAl ze%g!AL`1c6_wG;FIDNS|?@>KQTSn6Y;dX%CwG@SJ%$SuOKZX1nwd7g(tzOg z54Y0MpLU06ex3<-ob>;!GG>WTUnps_5D|qh;`xp z=j-O^;g8LpF`v}8MrDMwzVt&v_x2m>la}E{h%QLA10YZ=M5??m#&trFp1z`Xl*ZAs z1xV|=o0MOtkc8Pr8GstQ!ZZ&oR7xYkDZG>;3|_E_>5?h7b1xtA~bO8jSXApG-Uit0&e2EhI>e=Sjo(g)>PF znz$Rm@N?Niwz)o#BZjw+=?-c%Mh5l;2mfA-ZX$bji0X498jJkjpcu6={;%HV=D6;JU5yp5KN7`_j8IXbrEL@+$vJB65%C;%rvjF z1QL32#D`Dw1ukxP1qp3tZW-3kowpb+EbKD+FdOuju-H#9P8713w?1Fg^w5hyO!xfM zi92`H2~i}T#ln08LB~OpZ&c?=Z|TO4#ejfJal9x zA1THBiocUF|2XqEs)_%_hKxqA-ZVX&77R2wA8AM}dcO?+m|hCljqce>f`Wm5`W(Pi zc7xzSV}psIE2<6=`FseO8jhs0lod*Yu<_WWtA{8XJ*vtwa)l!Nt+D@I2o~|1(rB)@ zo`6eC2rS&n%wt(SHmzD%>a(gd+V8v%r$7@6WiXyo=02S+$zO^gdQ+WqbS}#cU!xbP z+hGEF!Y3y9k`eoDZWl_zv@j=Si@TL)%=(qg@W=W)kuEXE?%a)EovSkOsww)cqEBix zHu>`SB$)vyVj2W7CLO+I16^Y>i`t0zy#ap1%%2I{^B?aQz2LcKFQ7>Ln7TsIP7ego z`U1kole5fd9&!2IH!Y8{6+TYlB7q*!Q9|rwVnHEONw~7Vr=I6%^7+9296sRoC8X&x zh<2Qp$5_?{!-~A2Fp3G(N$MliDTvIswIBL~U-T29E<8}-B)StWb@BU|nd%6OXJ8GC z9ErHrhrv8;!5`1HX=HC`@%aBm@K1Ez8J$$L=eGYsa6UWLl+4WM680K5Lcae)2v9K1L&jXpK0!<- zApTU(#4DHLB8;^0HgVjNR7&O-EkDMo!D_^U*?Eag#r1jq|?BE(%_!D4S)g!1A&L$03i%-#Pe=pijekDG4@L;YNR|;fB{=HsY!7v#zBF&*I z<5e@B~I!cUJLPK!|I&krMNAaot`|jNn>1uyRd<0Zx8%_231eg%{GLf)b z^^cv)(J&T^F$x(sCC$O{ex9fzPfXVIe^I|-PK)9@txN6fY3tF?$@k`b?1< zIGF95inRogy%l!9&3Z+f^gc-5W;gg*`A)Nk$e0Vm>Nfn<%)Vt_V`}~9iVTCKr$%Q; zi%&tU;8bSNpg_u{alUt(=n)YAAfwh0V{M?rLV&Odd*<92(zq{3T^mG9=hLNna`B*` z1t{+_RZ=nZ&Zs3VVGp-OG(_C>gr8i;_|t*cdZhc+ZGaw#<@^EUoa6kX6_ii z?V*>q7f_ph=-r4<(7Ej=*TBP&UymPEPX@_xaJ>Bb+#^!-Cd_#8D=i(o_~Dk4BpR96 zd3a6c@C{z&K4LW=8AW^x1z;hfn&jO|!2{aw31q4j&{YTBeEQ6W|z&G-C7l9w(m zs&{*AW~p^d0FSKxjB$xJbBWebt2CjGz3%g|tj~%@P1+Q+cm)_UGXM)ZYy@-lC|E1> z$dobdF#^d5FOR!Ec7+QV#nyEUpAiyDsFt7L^U2gRs}-tPdL|LVg_=?J(c3|(X>M5R zdx-&afa710mjaz&b|%ZRjd+gYOSi3G4q^3B^kw(XF*2G-4^nSXoo0QQ%D7x)+DEPc z-j*-BJ$b!+Zs>gP5<4#eNBVqB`v(_tJ$Xq?Y)bOtN|A8ez;gp%oZ;VnW_i+L{E1X# zke3Q(fBOj?{Q6Jw9tph%dd&e@9@#G74B1tsDN*Qr3S$QX$=)2bi5Ew0Cb^<0LM}dR zzN5WN2zE6IqWK*y4Z-&9Vr^pFJ!S&$V}!g$;}G9MecZIO^zqtKACL3G0xjX3!1thO z=t|Ew@5`VzZ_v|5s;p_gjdna9$K3A(d+O1EwIUe ze>zc#1WAR?1$tw4Ra!NeF6IKM<^O~`99bsZMbg7nrl9E#D0Nl+If|+Y83H_X1D=MW z`wV1JQeU@aZSbpno5L=JB*?}iM{Ym9Pt6}{-^uF!$PaI5`*^PO@O%m_ftU#^jUKvE zF>_iojnhwasP!O<{7J=1@W9~y5GA}r=eD)a5Czi-xZ*VBS?_3@*LGRo$~D`XsV?Qi7y@T^lmKK#ChUbDj>) zRF?9YVwTptEaAxc4OF6@;09QX1Xv8%#p|tBPg8ticzx6<8RS)c&_^bxCvr69kId)T zH^FGtmYa(E?gW-)n>4{}sj>>~!!Gk+x$-e!x<7m{LsJ`9Er0oQ+f9^LFqyBVXHMPw zH7jAus$MKTpgBsMRcnfmry0U8iSazdi=_?)<&Umo&3>NyW-cgDDSxCfT3=gOgCsv7ZaY;c;2~g#uz6+g2cZWhezQ;L z3z&$Vw_%(m^JRbzJ^ctNHQA?UrVAvigW@3OVpJ+gcsSKXc`Iavi zmOH5@@9yec-@4Rmc~U0-flod2?T&F(iY$+x8T zk^JfltBdyD&jp6R)HDl?e!x^Fi}#48>ZCu*tvWhX+U6 zJ70a0$`wMR!*$DReEhw$-@V2!2L?dx5oaGcM*Ojd5+<=!qH>L35$kpv1Gn1 zgK>E5l-O6hBr90E?(sPFv~a9|{h;=L?!{;l^n@C|%8P02DRI7VelMV-sV`;O<;Li)YeG=Y)@0kLY<2s^BGm`JB8^T)l5|mGD%{3>OfDW8)nG3tHP(N zaDVHy+JB~y^&qOAlQ=HKatFe6#Mwf zrQM|SKhm_EYlbf9#Ej?OaIBPmlgY8RDqRU$5nX-T#`8s- ze)lW;?_E52qx-ml$isM(gu6#Wg53PD{Ps>-^(17da)OiS8t^km54ikXH-`lgJZnGq z3xge`tY(gv7dBrwmUEmEtxAmDT4ZP5N*+R3H8ccXM(k8oEqk(Jz-dLn6GJ z`qbGqs^?pI*Dzp3SJUatBPY?UZW(c*JAFuXgZib#7pVx?$Y`+BE(S(J>iju%X5n+^ zjxd;?MvnfHc2CY5b6EKU9sb;8*}+{c)N_>|01O*a{&AJXwV|+0apph_riz+8P6FTy z@WmC7JsSXEVu2jIB={v_Ga`18)={{m@)G;KfmvTxU9CbtZ)OL#FmRU5*9TkQ9K!a$G;l^qJ#z8) z(?{t%J3(39p@&&E%E+g2jTL1~*zew%gy=ptS23I$FKeS%tyHo*!$ph3mO>63N_5<^|ot)nh>fZQ+x0PN@eKsEnUd)E1tN|@w1 zEJ61*9MMqM+!*}#@)j1h-}IQyyh!xsC-?3}2K=MXo9IDehu`O5kfi_(fR{5(88!jD zY{&%MCpN!3L{U0+f<>wrbEB)WLo@m!|99}qq?{L8ZA-R%A$l>!h3^rRU5DBP7>|4R zv74>6nnOYDiW{}5nSUCz-g|L6^7_o|KE=leStd(STvKOttkmJUAZIRv5@VZUVNQ5C9y zauV%vyYs!bWyzEH1p#yG9zf1SpE%HzOEwk7cA~hn-H*x_-s{5Z9$y07$HAAhY29&V zMOW+dB`X7+w!gwY=OzT$)-ST3{4X6m22^rSaJ;$Z|KbD3=~vDO_g&y&tZ4^c$`U1x za`7VAU1uoQKbBgVRM7HuNFXh{Q6< z0!Gc!k#C-d5Roog&D)Z{BH#b&EERFIaQ%i<&q}muDCS|H2v^+zy#FceUDVtaE7L{w zc+fTfCWO1SnY?w~_69u4+_MTibVc#GGq1(?HMOLdfpM4kK5xV&?N$JuA0R2>G7)`Z z9RpB&>(@_9TrSG7v`e(FD2%nkv?bXCv)*1$VQNjl{zd|aFWU-mk2Ic#QD_%IztD8{ zS0wFD`0EQr#Jf%pZ~BC+MdU@~GL(E?)3?dI{E?IvqN+BVawQ%>w7#^OFRe&?a}hB8 z)yJ)_cdUKqDDc=`+*7+phy}k+moum;=}(LvawmjEzK3Yg-9?i+$Fwf zSCmNcfAtC+UV1xJlJ^Twp4-Y@CDddEaQH*UlMficCGIIf0c&wAYx}PmTpBx+I7&EM zh9TSnV0gvp-aQ&Q$xy;d!9T#qK*ky6E)}Pq)^y`JXW_Kr;~M01SK6=D&&Zk%f_}#* zv`(=6oK` zap^~tXC0$TwTnV~0aW`Hd(1puaQH(Wo&4BbcUc|GHMPr zfHgET`G5vk{Btd}3zGYLBnH7WYp0MsT!b(v860u`afiqKK1<`>#`?+?ZX43x=*1 zfZ?Z4(kK|O#0ambsm}j8VnX5*Xy2Bl4!iiFu(AswGn|fTW83D!2>P|gQ&W`1_{ggv zBk7pfEvTpy42g`h%3Y_oPj;TGbY_=^5Ta8fv!;vU&bXGf9kndwmQR`NRmLk9| zKWOkRdHYP|u*kPNPMu4v9@W*4FFcpJP@+me!mP7({+DP?I*IC%Bv*c*K-RX1xrmy*Z4iy={?W3#)WmWP z#pf6JV)nDaeU$MRdY)^rhK_cZhr6StSM$4qW2abn(<=7&rbSV0K(#h zppZy`?;R>A9uJ|l5=x1JExcnQjbgWW{>9=$XwTH^WtF(Y$#>)X+$CtW1`YfSGIjm1 zXy^<+(_}?aQkP#8zQ)Z_b`2Wo51+mu-bfCsJ#Y=cKL+k`uM&+4n2afj{Zz;%vHD{sa z&p+%Gn%TXDMZZfr#chV=oT>z?&G>)wmdaT?tLEVJ&BOo74g4(-+=73e4u5VMm=;hM zmDv+UZ-zKse&4_3S=srLtT1H`9fE>TRgg>`&|t5G^a+q+NiMj6Fcm!bD0+pPcKNt0 ziOga);1v~}yVk6lAboZE=o5SUh$F+c-NPu_lChI7RG3_#HnYoj1Vbk;vI4~z1Va(X z6*Zyhx~sInSSb*=#Y78pAmM_6wF=Bx6!xbTAJ~Kui$v7D>Kc03abu{Cr^}P|^8M$@ zOGv3lj>rUo7P2XxZZ74zM-?F=FUel>mPAYOjTw-s2&nhe>kAF>$HMF5qD`_Z)?FzI zvWs%}B#zs0X@xoQ>tT0zD8HeIr|G2!dDso^XCHS8S!+FAZ~wn~czqNpMe7(#WpTNe zF5n_+jE)9D%(8w89lQ%m`7-zHxWVhfws(PR_7P{n-+urC z=wAm*Q|4jSq%F=cx!pqpv>_zE6_D4`VD5%)6uCm90YHp)m?=u*^)?2nP{N1Ki#`HV zl#kY4Nqp>>ANd1McrU(xyT0{{IaQQ;_wl$b&i)_hp$a}<( zfZbeg!~4cgx8ROZ2|K0+roARvuTsvjP04zA5VUaPl z(`ag4^GPGfcg`wX^}_cyn=jN;Ge^%|>EG`n*O@R&zx9MZE89$GHL`aOonzQd7X%QO zJ-e$RVC8F;IvhZUoyb)7=JS7(}NoU1uh@xI>9VM&R1SKI=|z<&57gxI`8<| z0H9pWeTSgAMnll1z#*ur&k&Xc)!Mz}=_r`3R9L-Kd>Y`uFAcLZcFa9J;5$jLu_6=g zT^4E5uGBDgcacgb7yc9L*yDdAGuFfQQVc}0FAP6;8nN4Xhss(e*#aIE|1angRr>{0 z*g%8lWBgsh&=4YQv_yV@2)Z^hoI^(pHot<}d=I7;pVgnkI-{XoYuS&bU?oq_wH5n& zPVxPzIDm)*$VL6i&q{)PeRd`iV&VkbJtc_=0x-He2G=H(p;UP1jy2wHebQDVc*MnaDUDz_eW?-_46@{E}!VB=bsfS(IYId4N>@v*CCK=!nMu6G@ zxF7+7V9AHtG~iSj&r3k*PYYqss*-v2hQ$`~SwN$!@i`+l_^FOb~wYKLtG~+~qK-YLs zt?xD#r@8(RU6oaa>0Or1k>uMyBe3->|5Ng^tM&VPD$g+0w`S-|(1CRb-8C%+Q$s!Fg%!SP#5C&2L^tTzBH0Uq-JOe1&x|0y`{Y4@nPP8lx=A|Fc7px z2gACj`QGv{DsqIb%bUrSBJ>}=bsF*yc5y*b{Dmbdwajx$Q+TeAW=aW2o^~vnCwjgd z3Cd5Kq}&03$$7ItMBC0Ip78T6Cy)MwXQqgUX(%XwV7S)Vq%1c>jV1l zI)kQQhFXCbN&zj&|DUHUcK0wBsZKVYF)Vp}$<2iEqNkEpE#heY3?I?qS2PTtvaosZ zYw`I<$dUq~i33-od@?LO7zQ97cmp}Nt{gqHkM-$hcPUlDO zcmw+2M`>_thizBQ__qA!#N*z}2CwXXY=vz$IUlYbpCX+_yEBkZh3%Qmjh9NJjpt}R zzq`_w%-q8J$^W1luYByusb1ISKoo5@vd|K8e!2jt=;){dlC=G{Le>w(1a#)q;<_oF z!DQ#ICI}7c7eEL|qw?*6g*C%Y7hXT4(S0oWDof&MB3|Xf*y`ewjwdjTdNKYi31`A2 z0Fu)iV>|;1kps)oz;Dmas)$WWpr2`T?f;EUdZO0H++Nm5YhHLoYr6+weWB=}0qVI$ z`*(mQph|dJc*z1358?;Q-2mB__STK9x}c#?#|5;+t>Y&j4Y4X_U@Pu?lBUfHZM;nC z2NOO9l5p4a`4|P#*$MVlYmLPo7BUV?RfsbSRJJRcx`b2Xlca5e~mH9^A)KP*pAQMBA395GK} za?G}j0uigwUGdurZfVtw>|+u-dbj22Pt)FArX#$-vFRqQBJ<(M=xL<;yG2>g&MDf( zgi$?v8Uk-5q=zbdv3^mOH>YWj=_oTSE-WJma$*6|*%=x!X9*oRr_su5(|h3zClaYsrUDbT^6S@pp3g-e=X6KZFe>_ z`owi;;2%IGIBvZ2MX(&;IC=aPGbwmQp@Tn!U8;zmv}bj-yV7r2bae z&hI6-cC29YT*L-0XU#9-e8{U6A8vMGvS5}mu;F6h$nV)KDXA)`9qtYp%rCVMY_5V; zZYU@ASAUTCWi2`O6etsd9-R7I6uo+H#cw?X3@#}PpeceoONw+#o6V0!>x63URlc;; zk6FoQiwdi>BTw4gk`MUUI=fKTdujBS3mU0@a`L-ixjsUk*4zX3|2w<8BL4KnorM}O zyy^=uAN|`H#{xVJ%uZl2rjT2px5yivzi#(gj6pVNn&5xtyZiq9cKnhgP^mRgc6ri~ zLg7v;hLj>;zfxd=-+v?34YL=`i)^$%ESgu?G_X*h4eftFeyW>_s7ePkSHcmneu^d# z&A2X>yjOF@w3(E0B%(zxRGfqd$NtDfuSnW60fJz3k>D;NOG$lAWrm~OB zE|*wbN-4LlerKVVx(AXR(}k}bFrmp{Fp?iL5?kKA>y0*S-^>8C#|aPzD? z1IyC50IV!{M8h^DNw~A_R9PtvB1~tnrcKAPTc{>>A>XoWGacdvw{V;LMe6K3+P_(tw^L{+Z3TqR>)D)?ORus3rXPhkZ#g z@E{WnJc$NAB>YlV^eM=THj}f^<_3LPHS()MsrHKoZ`Su5do4IZ${vF9xoQ>56n=b( zue2x{vcg7F(s==N?LCKv0I$~2wmCqL;8P6pJ8>QBDKJKPNB3`jGg#YZNJ0wPkxvG* zJcZ3xzsoSdbXs*^d$$n{vTvyKlN4#m-*0C6_MuI6o>lDLz}5C|jhi$rP4$v3Ud^Q{ zRaH3SIS)eb?(SLpV)qQ15(wZb>wv}?U1FOSEU-UJLGgf-6dK=`qjr?x0uR4{yJ~1k z)?=b!QiEoq*IzLZWO>QB_ap8u^spBWGr88PB}>ux=CX} zz&@2wG5g|bfY$z{xL(7URmH}TrFLwb@*JQoc){RHbHqTh19dr{mu__kOtI`|AgXJ8|<=^SA5fxvP}WMyh$mDpZN3 z>wqeJc=z=j_5M;a?55Dze(`;K`u*x><>#gIIb2~vp^mvW4Q$Q0Sk#k$Zo)algpV=4 zDkM^DjZ`;kp5!yZl9P&YTtpU737hynT?$-ibpQiojGfAtrnD{7r$NIO44bVeyclmUGzusfbfHwh7<7LUJfIY!vt9@!7V%F*HLqn^UfBB^h* z)57eTtlLbfooHE%sk^;U#8`Ywpokj%(cnI^}^@sI$i7;QP>gPNBJQm5=Q|I z{YN6TcP}$LW$r!E2SJn=!wt zjJD2O3mMt=LRr=vbnxJTBJxJ5Hdt;BB-hu>$$jQfN~7V4JY(5>sJ^_yEwc!$lkMBz z4vvc7VaO-n<1ks8XjnxT*pa?_?A63f#1*&G&-fTzf+80%7Q36h%D%ATdfRlB9e7F# zxoFguffLBvOy*&@(EAeVs}5pgR`Kjtyh|4ceQBqy-T0 zD{J6W#8KbM8m^X6pIn}oxl0sG8*`@DmQA5P=vWIrvuasM7U?mqFEVyciGzjp!nd1cF&9jhwTSo@GR{fp$zXf4#)qnpoCC?Dh-SL74Ei$CoI!rL zb){9}e)_j?voP<$k!>|CUZMKCUEEu@@Tk%uyOq8TA0<85I(0E4`-YAJaQH>ZTq{ZL zt%VA@G7-kI;Ef%dIY+TMe}(^Q7`LnY>%qpi`=6KOaFv5kal|+_f=bym)P@el*HL-- zJn_^bMCrlY;kAdaV`aJfy2q|y88@77Pkw3GJ1JH``c&&c!0Z9UP^$Dsx~|1V4V6z` z@_cTX_eg|-1;Ov@ZYduhYY!xqeL0$ABuqvr{F4OL9Dq7Nzi&#v`%{wzxfNC*3aJ^{ z32umZYV{x&1it+J&m_!8%@oQs^qYr+2Hq(3S4QYId-|Vb6EhHN)pJG3KbfviK_xwb zx;Z8m#v3R&3|w}kG*wh8hkM@}Pfu{o=ctCA+$pvNR6cE+`FlNUg`_wJ{9TDc{D)}(KLk6qM!^Ju!eB2*oQ&aPaAJYN zL`jsDKrjpRP+mi1!}@(3hHEo7Md8(#{#R{tT5Z;b1!u1e zd1HDvX`=gA?T#!zB+kxFzF?6Z*9Tn-$PSj65SQj6Jrp6;3xWGFu771|;3v|QIs8AxuA4$f0q+A13x*FBvCQB{MdsIo6~H5+KIk2hOnIX%JUJeeL~tO=qC=x|uS zSN1?Z3_6w1f?=8F^Nc2UblSmeZZJp}s(R|VqzqB6ut3;4l|0+1_5C1%5)^iCiqFUs zqTLuXycy1h7ud1bh)G{nTGH^tvZ|eahjsLm>qE0Il`>W-r4Lc;PTLELRnE^=y18)Mg zkUIQ!);*;EM&wZ0Q(pKUXL=jz&ag{K#Y-K+n;p9f0ze>p#(oVG9GZZCsdPyeMa*UoL?PTgnM`4>38ron`&Pn$SK7a!%EaKKRfR`T<6 zDJnHb?@E4-e!ArH8)3Wjii5xpv<Mef!qc?@NM50l;kuwJ@cixsEE5_W5U&Kvu`g9aMox^nQfU8>uS_vPH zUV}LC#gq)`V5azVj1Uh7E)^RH>Iv3Qdi1S1^|(p3V2)ao_b&3^=R9&j(ldhPWWo-4 z`ZvdheumtO!-7u?*y_w9<3G}hd=U9EQ*8%DRA5gVFQ+fJ9Cy(VCIK-lg^EX(E`&G zIFPUIt^^Y$_J1Irdb#M%NNT@a^-&)EXb1E6u${B}h5g*eZ#yfq<>EmJH{|M5$GE;! zr?p+u7-^UYI$)3;8ll!NVczCAPQH=u^yq+(KO!6_&OCt(4z<{7d-nnXqF#n04<1@Ez-t{lN zs6i}_b@I1XCmNcG8b!gT!m)I+B`qHZoqLMS*t(&>qHMMZa8qkOoMLB9Zjy=PIfmrR zV9ci}ZZ;{f8&xs{4hR%sQRxAcDq$R(>yFc*!^cUAKJcobS~JdUN)|*A^fFufc*QzG z33>LK+5FGIV;slR?Hlc!y*a4*j?c=QT%57PFLJ)METL5UQIj+qFxKZhAX1AuL6vq9wsht;P^kwH%c?yq_)^JM5N z(}*?C_zT|GaW{cnSvUbD>C!2N^F_@PxZ16*KmEa}Gev8VXjpJ4q5u6Z0y>X@MZ3#& zH1@xC{40zu;cT@tR`L@#f=RPHxGUdsTwF&IpL_yS{hrSz23>lr-fGkg83Du>hQfk? zim~lw=VXk52^X`iC^vMv2%`9&@hXmeZEjZGUDjWtPyH7CgI-G%6#UF8@9*sIfbe0NJM%&KYV8G za(@O9Tzr~#pW}ylIF?N|Q8F(iD}7ndda2**3%d4qmthSN zsXVED2Rf0^f1J(aw<*&vXo->L%j5(=ngz_w33SJuZ;1H1!aLqf@;fb|xP^p6vRo#} zfe5H`{P@2gcuU=5>D`f$fB&ZniwXvY1A=#&t{}VPZ9Aci59OUxyZ~`?^?$?-z$)0R z6Y<^FPRmdLbmrI~XKV}W`)Tk-f39zR#DL271gaaK6h&X=y0f8qZs9ho?%I*)b8v7Y zZv97PEQ0d&sw^LQ@qk8vPnIiIM_g}Ud-V|^D%tJbLC>CA& zKv((a4+hHRpzgW8gyHRD)d7cylm7TabU#x?oR>3`U|onOQDqvNRY`_7!8+o?2%Xw6 z(LYROvjn%;73{IlZq13f3N#&+C}@JXt~0K6lYGg)Z+ApoLrj zv#OCGSL{xJ1fI80YyKX)j_{2qceGzU;B>6P(v`W2a4Af!z5C6mXbmOGpa&(-<`*kI z?}~cIqARZl6FK*Q+r>xa`Q!%5RL7|OkGM$iO2xw7MD)Qo=4@YuS2xXX?eyui=h^1L z+RmQF^CaxPk7{gCx+X<5+^7c@ zYFIFC=WzHK$wGXL`9D0;37tdc<62xC?)g!;;_fK!M};4M`YoD}|CsYV*LiD}+?Fd> zVt%Vh;}}A1!{d8~RxX~JrRVrbh`VxhQ){2mPbIO#_h_owiy@B(^& zl;Wa{d7WD?&js$;g{#+oHitX~=`>ughh;t>jX&lQ*Ju}}-I4PBt!zkmcRh3%9M{+^ zvCVDQq?%~&)XGg-R2UQtvB>J9)sIdNIrF?gO6Kcr@gL^@a^@9p330ih$RXcu*`mv> zv}dr*Jj8WPT7*{-yDzT2A2LE#Gm~V~`5s;T)b_?ERmDOC zlmQ|Pc3E~Q`z?Pkx5H%cF3<)RGL-AVK2_DKb2t3o5;$U^j75x)$Zr z!V@t%j5(II=Pg%_U!UC*K-$q9(i3e_tObFdM?&&3oicz&T$lRMIrFj5aW)n#V87<`8K-X6BqF!l;Z}2BSV? zuZt1IoSxc$9Oe4AiT*73CIQa`ynnTCv$|$}M*_%g+)$Omtu@3nFu%X4+05yL`7`Yr z{mqSQVt`cF++!eqN8dYI`Ig7(n6OK%@?Q;`QV*jYBbJ{tfJgv|94kNZi&@U&L&0oa zhC88x&8iBK-4pyvj*-gM%iHkS#bEx2>r=Bea8J(oce-`!? zb>1`#%h^=#RYk3=@-HT%o=nlJBa(m-6Y%JNLGX^KP1uWm#&RrI^K+Y~VUFzXo@W;+ z(5TH|u8}u`e?SkaBm6&VSQj4(+D=CVh&(*5v;L^~svAT*<7$@2?G~ip=7qd?dnG*g zhWcIiR%lH0cBmsrPB}Gz&hgpPFj|(;qyHI5@~!o$nP6GPUbtP@g@(#3cZK40+*6n= z$lgX1&DXo_Sw(jOYl~?~k-RMj?I2t!Sj|fY^)(%IEqR@#sxv1Iz_HDcQUK*)VcU=> zm`Vz)FJZK&MCHu~5rn~?pXJ)SYGWhE_YA0ia{n3}V64P#7K%Ddo}O+lyc>}DX>gGv zlheTd*Pdw7@vHX=W5siK>Yt8WJPb?M+&l#-?$oWK6wKf2|gybkqZ1aVt| zt|c%Y6lGQVvyAbJ)%{PBR}M`5cTmO7JwdMVdTusVu=G_Ze1;;-{9zf#yN>{7B(B=% z&0-6%y_#RNjk{m^of*nG=1yFBG8U$Fg8{kgG*QsA>PhIA#W>smI@`oi)v5@H6ty_F z`E^+O>^<#QLyUN+l_9KH_rjr)R#clqe1U*(jG7=L;fCTGmro65;kMYWNx^lYT7{vr z@BPnR3bdMR`xVt15rlmI_w3Peo2R_kqVBc^6`)2NjB|rTR6EfOps2>t(J}Ir9WJ=m!18354u|$yLlmlP1 zK%vk>rby4*6-FZ=kkEP-PB?+OBURd)rruc|`<%-zGX(zNrtjMl;91<1|F6C8@M`LL z;zg=73q>g+Hb4mQ#ULQ4C?dTIhR{L}NbeL}N>_D?ehH_QN2F>(Dpl?0)jd0H)6@mlsSAd75n)a~XaI9a^I)Nm{vVmioe zB}-){aDl4P*it_%Qj$L5-lqy&}YF9E@R7Jop*ahhf3$;I9m%9UfN)Z2`Ox~@;n>4 zIU;(x_)uJ4x2A7C;I7LlgS1;`O3vLmrPGAW(Sh;#{g)5G8o5f+{>5vQxrf*obv6pZ zOE5+^OlRBrL9opf6b*sN;EK(`x_Je6qaMjy>c?l1@C1PX;Jtj{R6s9f5UEE*>iOkA z_TGw11VlukO=BSRpEyz2J}Dr-5(>S#u^qmaDttk8KIpeEUvk7IaY{v#P6rRVELdZc{Sq^w<@7M-npafjUx8~ShKG$Z}QyW zK)q2Y%}qL|_}erKiy4`o6LtP7P=6gtX26Qc?5fO0j19p)b|OIa!9fp&-+Yptl6#x( zc1Wm-^Jh=Z55hS+YApN>t3^lBj$eaI(Pk~|{&gC?8%MmU{B7ITTnP0d>%TytI55q5)&9r{+oKp3A4ne`L-<#1on*V7r-1I|1a*#f#Y!;&b z;v4!jHE4JiDT~Nw#Mq=ZM&I^^@Xd8v-Ua)rT#xCFfyK#^tI-<`IxX z%09)uvTvX6^44q8&K~F1PQbTFIqFJiVnQEnB4~;(QHz&8UmMoy*^>Q{FzjUhq_!Lj z`ku3Wi8p$9hF~dSm3|7`);W^#;JS@k^aVm2&6Q0?GJh#6%t5DzodoHH676NSTdgfJ zL3bPU>1LHGJR^gy`9I8vuHn5VNJ4x%tUkYm2^yRxa`N_UUx3g`qcZ#+K!gCJDO4yV zj-$>JzxsI)UUY*Lz59!)I9jJ{Wj z^;(-D-tj1%1Mi;i_mn)}&7a!Z?X_F`SYMFY(ADoau(Z=xpzZz^^%nVd9P&vIpQ=+=IbD;6l#Fd<4>=V;FIC{UXx2>ri=zu;8QCylOzG;-} z&1j_7@Oe`E28)Jmd&63-Ne-h6{g5J7rDf$-hdLkXSX8MgKV37M%dypqSM>_Q#PfiaWm*#2Fe8FK2j23FI`Qq(b1mPoLC|!Js3o zE?n;+{o=J`kxX8C8LkP5JD0jx!@uLPeXRx9$2gWqNv+6H3=P?NJ#ufLw~MC$2NZL@ zv2@YzEfW*wm%BgkKP=+5<&2~3!BFZd;W0t1kj6v$%r_w{n}%7jEj4=n8MU@W3IY7g zzGd=qX%V_hxfK%8tq;vvS63c{MAcx?dBYOPllsuz_3hW+RFJ>yggQrnve-Au8+S9a z8|B^rf>OD4&rsOswA~7hcK+Kn);SvYEqUo}NeAx$1qk7WuXlo8ocf!=-?3=ZG~gwbIbWDj7QQcfBwXD+07s_G=I9Ft zJx1IG>af#ZH0(Leg!ytJ7?n^dL2OJ1F2BxJE69}$6uWl4 z?gM&zc;0Y{`9XaAcp!;+Jn;v#?@T762+Z(804}Esv{!)BW7Renh;59&g{Y9ZC5Rg@ z&s}vucLzb?^LyAfn=P0UI}}{WV*B$RVvcE~sq7ET;ABxa*^o3X-W*6?! zV=&9#gmI>kYk6+n^+vjG^b?JniqI^K`cSr3B4!b^O{tC*?$Ict{Q(7piC3`50Qf}w z<Nh68DHN6OsoBTofaPl{Jw2MG6J9JH~nzBHU&GmfsICUdA2$5u3|M;4*^ z!t|laIF@nO7No*+v2bhpJ*-t3T(_+s`H|51Zo*f<#5AH1SD@Cg$G&@LZoSKNEE^-{ zmcsM7=EdVG>X-8KuOeog7wi8!Fgen^$DmF32FANo_Mtoo+ZZo~D`)eyn-MMp7f^TE z3=+eR7avi4509O`#~Sz5)0?0t;Mdt(Sosxt&0I>fD^CIWUTSkGzVCy z@;u+F&u+vs7Xm%fs20}Pb2cpzXS@#YD8?DWo-Yj2=bG|4y@w93^fHSwuB)FnB)%-X zbc@}vf*!|WAh3|wv>awa59g@pTEMdnfw>Zj(1e>%dQS|D+f>(7iHui&yPDXf`U4ui zVh^75f4eDL|FAutWBO$y(6-?n$2!SBH8i`?IFg+f;6BfV=@tCXt}CTBQ0zW`pJu>W zFFI=>oSc;)&S3D;RS?=*>N$L~GaImkfX@Y3abBRkjt&1`i_Lo&<;%Vjs(}B#sa)OM2&v(3b$?emn=k6k=_o zM`&!?`L0~l3+nWY`{V9?YzkmTj93^on&xEs9yj%1*+fhj0}_EL+{)kSVe{38HjcJ6 z?R-Watcwt{2~5lw@!jp-`-JLG;w4L?5;sL~Z=ylZbA0S!(0CaZ!R~(KLS&PuCoet2 z*Jw~y6KlA1C%ShNvOtu!&pY+ZY3b$1?{tdgoe6S=i$vwWBrIKT*a@! z@qx>NMFs3;W=aIPJ0@lkv;$MZcGh-&)LmtbW%eYJ^QUQtDuD1^+E%~}z#_-e8F3&4 z0$MDdv+~l<$a)J5d&55w@RR9+GiKX|i4jH`bpll)4p4y12Kmc|zfm}c;;h# zrdhF+3_{@3s))g~$PL`kK+_d&j|LTS{|3}OhQI3dV8U1`Jojce5me$;572gF98d9m z@0X^dgGkk(8;cPtTu!d{FieEDVb4T*Bx5k~0wp#&X7@!KR@LW`3K~IBO7s>ihIb5n z(;wcuFiWK86~vV}XA;yC#lrF9=wN8*o8ATr;gccaux`mD8fpWmRP83tC7+S09sT5F z4Otjl)nNjs7M$*xtvE044E^Zqz5!`WCdj$e64W{0LD48h>Mlz)3!-uy6!1jw_c_}y zoyWn|WBZ8;_CZiEmIWY{tO=V_5_Wtm?TxHk>nDayiwq|=ZGIjD-zh8~0}Ljce~=E! zJ_~g22)%L9Fe2;+)cHiq52=>rKGgp9tFOx6qcJCQ3w|uHX$N`ML7m%hX8?w&jq02i z3;~!+JqJBsh}~8l0$1OcHld%8sD-ax2G9piU&WG`JOaL1u_`h+)K9!pfVJ&Fo7sgD z7UAopTXP7N#O!ju0|vO{4h7WB_*^`Ry=G-1fo0PsKa9E4!IVbGNI zTCCN5Z_aq=55TL0b$}?oit9}I%Ye$`jm-`iyItvKi7L0Vni-F~%3SD`D@}wxI55)j zq!?u#Vfw=7oEA>EkKB3ok{|~LB7vv010Ra|BNGH^4YX7(>hyWv;o-Wr$5vdsghdxy z!JtnHv7M~iFivLR&+t8O&K>}NXCdi@SPsM-%R7Z#3Twd7-qyQgXLBK{QSQo}pshcbwhQD)jTXG(dmNSmHbfgeoDYQO z;}Xw`KHle+X0c64!}Cahuz~b4ENz=Wy1eG`gTzx5hS{)Mj&;DzG+v8?hA3}*0Fa+S z2x#y|)!vN5e1g_Ddi7`gNv&P%XUjguMfJp;rFc?<67`|AK*%+E^(J7;$S3XsBDl`4=G+|P5{4EnkxhQuuqYo`jkOSV zsGk$$$nSN;EW3KBu4;zN**G4G)j31HuyvAiDzAGOFp^N4ax>A$!ry*1wTrU|S2Fjs zy?nO~r1#0htvQVAS>>@iH{t6d&BUhD>ke?@)v_GDrxp-~*^3qb6|ja27GPN}R&)(X za21nL51S*KOdWaY#k^qxt&vUHeV(na(ZPdvH?2S3$oP=s)5nMa+J;y>X-88lAX@uE zPn^(Fn3nbVoL8AkbvmQ(hux;-?G%57;8W!oYmFBi?x`hz_E>Vv@>n7#`;<_uui_l8 zwSzRM(V6UqU?8-dLjv(I!^Ph~SXKmLU+;WX4L0tVFL_4*<1Kq%5TYZh`zo2h_N~G9 zNQ_ZvvtI$TIUDZlUHuQBnWn;>l}+R|D?lR_=iAY>qNaTNtli-BYk*2DB>hj#I^D~h zbGq{z^Qry-2Ee+i?e{7twyq~3qRGY~qVJ4-okS|IV(;*{n7Rji>LwBuiE|5@27}*A zs-#qG3lr<^UowSsEA9OLkb=SJNulVb23^c^LM)Z)BeM*KGvjn}<9X5x8o zga>+5+q{%4(M}Q-cWha-Gs@KvOnRfcYuM+lHZ#qfpVW$et#Z-#ooWAcS)$osxttNF zZs*W{V58PNTmGM?Q70pw&OI3nXFpUUzcDB3k)G8Rzcm z{c((7F^BYk2M=eIVs~Rh+?E`VlpGF9-=?z)MeQ}(Put&D9L31Ijw)_T`25{1?9Mhn z6vrJIkAj=;-IG-|7+h=-taxN3m5}?P|3yndi5_oldo;(Gc(hycJEqSTAjrd z9hC1~eIljcnR1wcd7p6*h}-bZ>)GMY8~n`&Uhqgr3erHhN96bbOX0PuSx}U1a~Oe? zTXRZ?5%}cuDZv-}!Ce8(L`lxhpNv?1C7~a`?f<2|vQUpa{0%eiyM!cqJJ+Ed zM+6r}x;B^d5+R~eqAK$RyKA$Zva+`mI3;(!&qj;DL_+>-qwv;HgQxN)PMQ{wjO+X> z*3%*u+Gfk8HLIxRzzJk|2l^S5zUsv+F<&dIS2O@rIG?bn$^f11$y{v7qK=r)}ozW7;$7V`u)BQgx_vj&1CW&+`9uGd@gt3a+= z0uK~sB!82gzR9wu>;!eq?T=j?t%@&|s(R zl=)~`#JKv?z1?%1{i&6hcW&AQbsDr4eWjonASEg-A|iqgG5oP-@tlA0@Gk*cNg$g_v#|i}9z&l+wr ze-Ucj)=6Wte);qXs~dcroSa$uIL7*i?C)-3fkk%Lt@D`3yS9C5@>FOkYxr5E^U&HQ zGCsc2veyE*dheT`0G*jjZxjhX-c3+Fe5C*6i95TNT(>pJi=$LH<8}zpg$ejU=+k*7 z438j|dLDpi85W*8aCP@6vWfBfdgtRoq?xJx6WW0b|3<-q!Wb)jN|@(P9kiD(ePVpx zJDPlj>3Hu>Wx?!8JHV-BAuxU7(~xAnHt_Wl-RW38FW{$F&g77!d4#&9QyX$+H6*QC zkc|;w<(bBYWA933b+ZJOQqD94?KiXZe6nW{P>5|_7r9X~p5Ne$+2p);(x>knGoZ!F zAN%R^;anQ19kABMTObr^U^yn>1g~ry&Sf`@0wcB_=4hEkfQ`Xg<3GRB4mi$wOci!4 zwB2oYTU=g`uX{C}nYMAp-|VN%l+iKoWH!TEwuh$nO3R?N|Bm$(dWQ+~lKN2))RlV- z{D(D72)9yUxsG!3X;W9^F60(F^X_{*$OiLABR4?6gP)nbg#&b<}O?2=z|=7Ox;IqYNn-ne|Xo9^A~_Zm@zN! zJcmCuNOs#Alyb(Lq6#q%p=@JS0h&Z z=O@XMSd9xw6;qqI?*a)L%6Ec97x8)Sza#p(rirbJA>ZyRiInGP$DB zS-no5KOeWqqhbRf7Hr8W0pzZx`-y44$H81$z|D|2XzSFQG7k5jA2qICy>1M6mR|V% zt1W+htw#H~tV_q7tN(IlDZxy|7irL6Jup7;wb%1>UPCXw@^QKPt6SQId{&m zLRte|_3U!~4k%svgte~4vb>6XFYSOhkOEl-f^-*28E+}e$7X61V6GsNNKUm#DhMmu zg(m!rx{3A3d4&cduGng0NvNsPd#FAA9MaCmA9l*4gW>sc_qA7y7*1(bw8rg;!rzv| z06yyG3nG36VjjbIU+2#YqXV@RTU2#ETk zLHg^Rq19zxa0#u+&TJ27T_mtIS$}jg>ClocC5}6ewJIj(8yrNO^m~IEO~OIo}q66ruD8_xyGcj}R@;-IvNj%R;J1 z|Ebg6Nypp&^?CK~KU{7%#zmue-HngOrs@yC%}d$m0(i?cULZfAlmJx*wgF!+R=njQ zfNy^K2m|VGgsqDx9`-|41J{{OCg}K!R8)emZkCM4-}kQ2awDmikUKvT*nl9~W}_c6 z4z!P>l*Wzv@_otZl44@YW6O7bR%9G)tozWux2R+6E7o_ge&eV7mwKTI>y@il8J$ld zsUt#C4Us(0`yN4F&^pKIKFy2X3)e&Gg*`iSqn~yTHHxs??%3X46z>-JmiuV8(h4DcQtAA$L_vFaB@wE{O*2z!)a}HN zdT%{!A0RH0|GaPVnIhKznTIJ=!X=hHb!#Ukqk-z7#}94!y+%D&%*%{F#?V4*7Z@Mw zPrTeEj5p_8Vw2TqAFcKP9fgO&32Ae=t!p=HmnSuzz{0G_F zH|=0_a+W1Rk?iy>FaEEtL+4Hn2mvRtPMz%Z2a(VZI$Za-Jjo8`v_dRC5+BFD^{6=GHK#4%(Il9zB1Zku=308D8^G}iOK+X&P4sBaX2L%G(aBsq9v?WLC6Kfm zL|J~%5#JzEGw!?S-SkJQ!^duP%U(FIUd(_p0#0&oNOCY2NdLxA!TxXkoEAM>a@n4- za*x-_pVzB)ZeU` zO#^4Jb)*vgnt{5fC*uX)cRyv&U&yjM2Ig|#K;^yez;Sb@rNwN?_y#HTVR)af^#mMazKgp6LJ=c zqRb^`2B!v$g#5^)!(Ob=#yQqaq1#E{A_H{KvIa{;0Kia`!+U}82Fu#ibY{;D| ze#o=K_|8{Dizv-igDIkpq zAbH`#xyjy~t&HJMSRKq?veR#fH4&##YPa;`taix3=%N^TOScST z=nfBkO(7f2%j%4(!K?>E9g}Hu6+ffAY22f!^>XVO8OujKj~$ zeQoA9CFL4Z4Ne&VmKM9`2t&41Vw-`kmS6EaYlvnG^FQqLP$t|a3EPew1Hd<6^{|!y zu)W5gxl8(6hm$&;F7g>Q=Cdw&>o};QqB7_oy(S$%dQeA2e$T!t9Io;x6TDD`kYZEZ zaJVu*kDORjmny-J?d8s!=RYW39ogyM9?FW_rJU;uEFVwzkULY-f3Mi|T0TzWe}lBA zH?a(5Nwyg||}nI}H()u(?6_>ASK4+x+uAp>LsB`7fVS+3XrXkd=J zG-eMD7Us)RPL^_v2VU1&soL^pEIAqC!@J#XR=bBn7icga0k~DH#GYvb+?A6Xan(~d zU}%6SGKDl7TiGHy;-M2&p5*EX3CD3Ec0PK;m^Becf_Uramvwd}j=V?gCn7hZfXUkV z+_E0cRI=h5)>AwDxsb)@-YV+BJOUaVj`sH>vXto6ZUve2P<4SLub(bK?eZAq-bBn? zB-lyRU)?+z)TCT5ONpRP@_MeM$VXHpe}C{-J2J@)a3p6Rhjd!l(`a+E{J=YiqH6^O zC_y`0cbjlKZw%+T>mnpZ)Iy0|lP~?aLo1)Y%CB_q_}Wo8Hz#>*Euf8_| z9%8|Hg+k&G6wl(%3A^LP@t)62x4ylLzvcQmYgYbH zydxEwm%K(_>g%6Wc4NK!CjNnf5{K0j+_=!@oit~NUe%k^Gg#8S5b7~c4Eag zS7Mc|GQBya38WYw-Mup4PN6Y$T<_|@i@o0(^Pw)^TJJD8x*rm;EqK{{o~Iez4XBRl zo$_=t-l(k&xVm}#goa%6NHEN;Qr-FExjtQ#x<{gQfN8aU$1?>qPwEB=v0%B)lx~qp zscW4Mj5sf@r~EJET>@1mYCUshzI<=)n=-WCo6Lv(%1>W%IwS(^F1RVbz6r?Z;yU*K z&g8krp1f0=zaPX${J5t71$Eehz6ng^EMxdV+RTe4pJKGFAJJ4wI5pNL<_(~f@{-hL z^y|B;33_FMi7w_56Y|MAA8|qYOECUTEdRuS%E_qR`1Dvs59IFqzkL5ztbIQ!Rg>b~#&VE~9 zXK7fx@9M;VoOht2x_X;eM*mB_p{u3rVH)&hmBog`s)3W4*x87(s0PQ;hMSKt0wxS% z8@%I`1q-r8?sJG+NYbO`{=vCTg%bkjls%IJ7H4s)J40k}0A{>78s+VMC6MgUtV4F_ zoe&PE%bJ4N6tWZ?WPulis*TG?8zmm|x#RauS+XA8ry)6#&nFMHWeu9>BfmAH{d=Wd z_S5QD3k8wP(IAWP^&~bC)3jCwQ?(CX zH2&8C^(81yGyoo3p>lCi>{X2Hvw@7N>cL%JzBfj;cHJP2qdd7}?5T-uRR(8``wX$*KZ92iA5Gh*EN^2|mL&*!%V=2&g9zMw^%liwRfY;7xwAMd>+7fN z=y!fCb=yhsz(LnP^}h_JwM)AjJQ}u({nOAJ^N<0I`Yj_*T!0d$pU>=0=fJ-?iJN~& ziTW;NGnLmqJJs0+6b|H=U<`KzUck16{gh{@P~kSMz`Ey($Wl^2k@nJ#gp6ha;-!ur zJ6#vP$j*;+TBq@cfrG~m2=Dg}jxOmxd#@3X1>af?-0jY2_O>bz8}J^Ry#q}%8bVW?$k|1axHPuZ znIcdsAN-QSa^CC&nnIJMUg9q*`@>h(c)0-71b4=?hh+Faphn6g1ccNc^)~y=^cl;AE)0qgw}*!Mq|UF zt{Eg{hkjOnrH9v-Y!~rQ3mBQWexCye{-wm4@c%lH%C9)H5s+xlamWPyw_3bHIH>MT z^kv#C$*%R5&#+zYtAyjdF%=bW{?E^4^s9;Mr%cTHuNo++U$5x)?6fd18Gz(%U|oPS zREOBaCvirU)i{|WXd65Kc4nM-^FLoyntIj1av>>?a1^lK_i=#=ecP0E0ME1j6Hhuj zjyIMh0KE&#WEO?Pd28BOSD&{0bn!+_C9L5KeRWC}j?`kk_-jrj{oL$_@(Xl_GQ%V!S@ zA`9n8S2+!ddAFa&xDF7h2OpA06zerg_f^<#cL%p(gP{>8~qEj7A}9`*90 zV>|@Kf|m{AlGmkDMsU>VXbuW7?B%g@2QIJzag$5-n!_k&QJ=nRWg`3CN40PJ(f0y+ zmUlC2DQ5V8uA=cmuRkeWb7JtnxhakH=~M3J5JSk>G6N=He*^3fl|z~*W6IzqrLdBP z!&uV$rbp|9H$r-#G0zhXgo-tds2gO(Y&jh*>+$$&3T}(Fzg2!L2%&K-xfanhJaFGq z0%1)DrK9+!dmdeuwbpi;VUH2ZC0+gm|GQ?L>@|iBwCJ z@!WV}05Ykt{G&NunJmetW7scv$_Gz)9b?fUwicqT?g-~2_cL2 z_$-HtYEmvg93v2e8RL)Zn@q~P?FPZJM15Um?^rEXvvkcr#P23HNu@!bynxE6ZlJzb zmT9@x6W?F%%|xdE<`xzhuk$+^5xsN9p|K|x`6y%%2~ao+H0QS*EVRbv7-(How!b7B zJ9#9_uzYOdJ9Yf=(!eGuBoJf4v9V)v$m2RiyTf9_|1i}||D_OQW-AJYjgQ3V=1QOAfeLT)7O!#m)+ zHwHIeaDaPiaIRf}S?x=g<2-QHtNK$ArKR^XSk%yB>a1P`8S9;2Nh{4`koe^LkvRT= zXU)h6&&SHs!}H~PhaqvM)A}pqFId)(UeCN^EB|Tb%Vw`Hr)`GG@Yg>6Pm&G7JDH#2 zy8;zG>`j(7-_EVO#L4<jq_{`hm@1CLtDo1xWEvY@a1^FIB_u zDv}8^ukR2G{DZB|+6$skcG3-N{cT)+{U?58;vb^&=r0n5CNDItZaGKxRos5@g!Oud zt-Rn)zfnhF!+iar?oz*oo@$io3TH~kE6seR=#>UfxpI$D$oa0#%27CbMPlQ#14Yz; z0c7CgLWz3Ny$~(K{7O38?y9l3$gx3Jz~mMA3}Ytt#^E8jwh8r@p)U+h);Sd!`|}&# z7HzpP)3X}bV3QDJCG-H~LwOL5GS=5;eu_tz>gtpl!(DNFI_ z7zAP8J3OkO*A5OBUL_kxqR3?b!7{DYJ=E$0Ay8iHYq$Z6~ z8U&4Igyin%S;nUdj~gHtudBTaYwdy$gltNI5O-gBfZpx&B3N{M)fQ8z-Lw2RhFjA!VZKJIYcwCyFMVsp`kso*t%fh-p8_8Sjhw69jNYxy z1BnH{9cpOX<=BAP@EWOHc#?+PcxxY@h7zZkk;Z#mzq9>?kH6FO|Ns8~8u))o1C8eL Yr`y4?r8>!C$KzI0(teD6WD)j%0K(&1`~Uy| literal 0 HcmV?d00001 diff --git a/conf.py b/conf.py index 648cc8a26..7fce14050 100644 --- a/conf.py +++ b/conf.py @@ -10,6 +10,7 @@ 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx_copybutton', + 'sphinxext.opengraph', 'sphinxext.rediraffe', ] @@ -105,6 +106,16 @@ todo_include_todos = True +# sphinxext-opengraph config +ogp_site_url = "https://devguide.python.org/" +ogp_site_name = "Python Developer's Guide" +ogp_image = "_static/og-image.png" +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 copybutton_prompt_text = "$" diff --git a/requirements.txt b/requirements.txt index 8bdf76e8a..e7831193e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ Sphinx==5.3.0 furo>=2022.6.4 sphinx_copybutton>=0.3.3 sphinx-lint==0.6.7 +sphinxext-opengraph>=0.7.1 sphinxext-rediraffe From b62b8656e3a07feadcfcf1e0100598fb05b2db79 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 5 Dec 2022 20:57:59 +0200 Subject: [PATCH 012/538] Replace og:image with 200x200 logo (#996) --- _static/og-image-200x200.png | Bin 0 -> 14572 bytes _static/og-image.png | Bin 48408 -> 0 bytes conf.py | 8 ++++---- 3 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 _static/og-image-200x200.png delete mode 100644 _static/og-image.png diff --git a/_static/og-image-200x200.png b/_static/og-image-200x200.png new file mode 100644 index 0000000000000000000000000000000000000000..0e80751e740387f9305718537f4b26b32e774088 GIT binary patch literal 14572 zcmX|IWmsEH6HN#b+}%Qf0tJc}hakm@6_?`f?(R_Bin|ndDa9R%OL2FX;{N6R^ZmHF z&$G$hJDEK@dv@k*grdA8ItmF2002OjmJ(Nj-G~0Wz=*KVN{y;)0Dz}nT3kfMed)B_ z!~dIV-X-QPrLxjk zSSlNW=k4E(?o{D9;fH1uBA{^$U*Q7%vA|-}%IN!#}>B! zKALS1GON7Nv8t9cCyOp{*bywb#O90{m;w|!aK<1)U`?C=3)nY6DP}U+DSC7CIWXWL zf>{ONUg70?RNTlMBXwGpyd+t_roehy)cu4tlPxQNOVY}5NMOjxQGz^4Wr~8+4PS3; z3KH+DNCOlRe+NW%e`3Qyivfjmlwgjwc0GTTYD1W_vzWF+4O<5c&nGIKuJ|i-1`!>y ztt)YUSgL`ZwA|R7ot;fStSM}p0}{fJi*IegxumP)0KKNe23tZd;7FQ>+@gb+tR z)Ax6;@HI-4G3b?z2zxr>*YCwTrK3_fuSSfAY-+9}fmRp0lD0y2tamRBp9>@~bFm{2 z2U6AnH0NfMYkz40XhBU1s6UY8eL%|mEp6r=H$L%V2{>H zXU4jj2?=+i80RIsoJ3B`6RF}iJbeua?_vt!gigatK^LW=$IPSNIRww;F6(yd3BV$+ zaROWSBnAvAFRzr*Z-NC=B?|&Zo6`Dxs8NaH5T3;FTqe||+FVUWM>!2Fj#{sW38TWb z4Wd0}fgU#JdAJGwf0>!>v8MCXY}kdYa5Tn%m}IHI2jA((IpOt%S}Ib{enWXsY$+1B z(aj~|EC%B*K{UxsvEQ>b!7r6K0WB$z>jz*Z8GBE>49*~x3 za+0JXVu%&afS$h};t(ry@84Z$Cx7&c? zq&>w8zG6rAUq7RsvEQX}dDX@Z>_P$)zn3@2(kO0}>40MbJqCuH_O1vJHi=%nx(D6; zX`Kk>w2-Na&_eSnX4^p^A3`CQC&KmYKU9QrKt6awHlMAV&bJgPcheNK&+<~}x0W@C z0ewS^zqqNHcTt4KjRt~dImoufcwe6oy3)DC(l$-S79$8xjLUpxnD+%&VW=ET=pgl< z_0mAt*r61fGvq79m*Dx=J*%H{N^tP}t$PqN=tGr8^03prhpy@A5Oio#=G2(cV=0s} zv)T89D0>=km}cj3mbUy1lT$&MnQPJtH(rxMvoRE(F-cOwv@)3$E+Ig7ghJ!GZ){&! z=&xgfG^*5|rQ6Z8svf$8=}J1;f+{@OsOIvFZ0_|wmqBC9JAB5E6f&l2(`Yi4e@UCh zD1En(a(tL^n?3_x{^y8mK6c*Z#P#J7j3{Q-Y2%#x{adqgB8YjEOTU0tmT7-j(~$Uv9!%cHXwME7C; zz!ofCtY_5kMGgp+gkVJoHgVDwXd(cAMbYvs){nF7oJBfpJ}X;Nncz|qn#9xM|Klw*Z%ox2Zbk& zimOXdV4r=XMPejZ?zBaRR}v{Kc8J5E-QoZ|CSZdn8gN1B;eGbK*|}O_>hzH*)x_fI zQkJebSKMokul1*=r**BZ+FXFr-j(en+H!d=Q8_>7grMKKnIq{`@DQ}nf~sh`zJ%5v8(@DX4r3v z5Fsu^x>PZ_Ru?FIK2DNnSQ%yZi%*%WSlieX z!KU`j8NGO01pGr7bn*3+akAEcDd$ASD5Y?HuPRTrD7zY+@ja4uUe zn7&k4){muG2W~{hc$H+)DXp`L+teIn9J4g1J6)@>>yIIkB>uCSfxiE?l1~E^l~b~! z7~ys_B+7`jNQx($ZXDlPj2}iY%fiX}e%B+$th?~K^X6cfoc@O=5x_8Lx}yqhCef{=U79%O@KyIu^G`BUw^njs`8S;p#n-a{Z@uXM=O& z5MxKUI`>@@)0qa!rAytg8T{+`fgXM4Xn&Zgh9liiO|EXEjnBTrnovVOfzYCbAsG`$ zhDvm-kpK$^cI{k~;_YU}*{_Y=;iVidUSNyGF1~5uE|OZ?JTNhSU*-=)M2laVd1sRm zW?tDk3vXgjru|FK_@}XAugpHEZYYzp8TR<?i1`#t!SXPH$3UkBhCB4k+suBAFHa`U-pNc9U0hd z`8uFI;a3NgY6s$2>RJyzt-SxdW3?N~4o7uZxD_k-T&dv8^Wwfsi|K%S?dqfC{16b6 zmqRU)Xd1FYg}E#JhjHfqp#KYgAdV=M;rM{g?|yd-2582<-%IBI^{0c$o?XjY&)y?9 z{ryg_ZEH#S+&b13;kOaFTELE2gFyg{csa|TcyH)Z&t7+)?Bv2h==z-SDwB4<{Am|K z#!+0d1t?AU+sk9HyD~PLf`lq$-A zw8(+e@}M|R&`x0nMGGI6?eHEXJ6grc6pl2Y1^|}-Fok(=I!cDb3KD-J%?r<~#7nX% zY7J(jFQ0o<(!rTr0TgxsH=T8Q!eDMSL=47D2!;>H)%+QzZk0^&<->c?ab{Ch{h~eq z6bd7_S#Z;B3lt|#$2k3Z-5v|fRl#3ern0m{s4&Ih(f)k_IFZk%9k>BxW2bMa$A?X^@JIj#~>IWbQ<1b##t8e^cZLH!iH|Q^xcM zf}h%Q-vbNaV9!fv?P`VD6-5E#0Lq}aM|c{^y~Qk|`~Hq*8Emkg=5;z9Nrwi6M|tg)A`m`|jUqZ7So%0U(+*er(rMXOdY`FYW*>-Qknvtls5GiL?b;lE_Uwef4h@F$)%c@&b|3C3pqd9z>Ul)kT^#!cpX+*RfB~X`oXU^gZSA-R z14fV&Q8*j6I}TjW?Al*uSL-xsL5+f+e<<9to#M)W-!_GK3UVVclt+C7K9JBraW_QV zU1qzMwbS@Mbb2WC10y5~-no&x?eT2?_{*Wx#0N$3q~yFcx;U$7K@i8ONE=iMV;2Sk zJP(Q+lsJ!;rv&zRuS>izvN$9c{&+-DxCT)$hegi~UWdbbsdQ9^y~D3Dz3B8me6}`M zJ&uk&#EM)PhU>{X`Azs0U9yw4`3t6WBwa#mv*$jB ze?US}#Xuv_Zgy2RJrBP%SBD7sOc+TSVB=CwbTP4>Q;%T8mdCU3=4dd~_XdwLBE#~hFZLMReG6UH{?t2H zq)k**&EEuv^8+E=2CIPtr?X%+<+@N06PP8g;)|)~3r#I;Z`C&blqtOXgR34PYJ&aP zRmAWI8hlZ=8vYz4$uPi&@ESBVFiP+YwmGIy5oyOR{AV z8juP;5C<#`F#yHrV)igM4352RcT~7)+S)0pLD>@#fg7_K>J$v(8#0JX(fT}v6*Ni7 zhFEwU;i(8KMdgVep{Iqm-lM2P+UjJ;76J&`POf$jb>F;KJyLBmM{ve~fq*#YAJq7r znYW!+9=fZhlRXqa_W;9PQv~g915w0Y-jX0#prSXYLxOES+&Du zE6P0BO86iGC~D@FBKoqJGBhVTQhbEdugz|kM0p|EOT2zBes?)}nx1z@xJI^sDfrNDCxS zY14iJ>b*4P_Zq_)O~fIlDLr_KV_Y_`W_v!cb?4DeJJ|n8s7F~zS7zI&5lD;_W3Zkz zht+3}EOjF59sPPU*qj7P*wSk&_j2-5Pm$_qn)geKx7aU6^x~>V3=mhXHphjH>9*3U zbOVC63viRIi^$`NRiP)Y5bG1#wN_3Z$Zti}a!dZRSIoG4dgqIC%f#m88MJU0%}PII zOdphH(1cKJ{+IJdM7n`?F>*K;`%a#xzxy?b(du}G0S;8EtGK|TlmB&q48LEdtG~_N z^4!s6WybdG!3M%!NzGL=f~f!agPW1}WBv4ilH_+)+Km!2i0=lGRVq0s9ltmY$7c?) z?brO^#jTozSM$f>&;8txw9nE%KWch7)tKB>w`3PM^H|EST^};PZzfV?hPDN(P_!dk zA+?5}oydHXep-JCG8ALh^KWRbKRJ8vvb2?KmKJ~5*^n57QUB=!;vh|$f%d!@MH!qF zGL>q_AP0x6q4`;mP4kw2jx9^^(iwT2xk_$*;>0hPu>g_*Wr*ce)915%{||l^TmsmI z@3e(6y>wY(8P<3D|G=?Zo_pr#Qtvw$fwuJ}CcC^YDW?L2+Z%{jMAshd-JAt&hRcLu z{{N{FiSdo^)q+bV0%;Udz z*#L`k!^KsRqa<2JVRG~ITYgyJk9lQL53tO)Bp0eG?4Kw5Q=a5ONY$3vtEZ$(0e$vF zH%79;JCvK&rD+Mqcs`teY08iL`6OQ8{O@cqbs9y`1im+nU#(}AEZ;WDBoM!x-6N)K z*9{+3h@xvW`;uxP)8)D*u53(j>flA$8lCrz0Ls3$J)1F~NeJe8W5PdIPC~Ar4v(C%9 z#IFYd{;6sJ5mz(ULXxHTb)?u)=XH))GO=zQ?PXTg$PrTYBtToxc-z@m%}>AC3hJ z*MfTxYN`)YR#8W{a?Lr{+9L;DIXPN&NW<>2Gj>`&Bq6<+JZj%?#oW1nOjnuj#;aNx zgxVxqlG9gR){2Yfl964WtP%=Enyc6!tL4Yo_S@W^+0uqwFVTl3b)+y26xKc~s*~R?RflZM z7FkiGnA&$F%9y()t{TxzMlqdLX5b zt>+6D`DX??w%|Aj^NwC@6$B9jLG7je&KoRm&4ev(ve5jglJI`R#~sp?Qx@Y350N_Q z`ac*P<+J!UGV^?8rAf(W!VRn-QQo;3g}3{jg6S{*sl1k0{bat|b>%hMGdOL8ZqPG| zc%v!?%I46o@^N)FjeHX5NeMi+r9y@W6<$yk^^xC&%*U5#aN*Ya0=L+zGW2puo$3+A@vsU19Gz*5Yh*TmEHuNg# zlft4%4YTUp|Mp7!vWU+jQh^`()9e^q@Dl5BW5X$=CRa;hy9tlew0(g+vFfwAjunl9 z2(3-sQ?FjY46R3plT-8*Coh!!EGisJS?=NB*#)&b%D8@AUr{WfNZ^*%YuL#PM>fic z+v`}W(WnVs7uaO11Y|EEFw>(xJUO? z?&a^GdtXR$+=h{k4)U36cfPO_)=5GF`p*zn^N4=gW~smf%5KM0mU0-CBD3XYC;VgU zVWf-yb#U1Fv5k>b*QN2x(Sh3Y#M?c7F_Lg(M-u3we6Aeb^3Nw__v^kE-){Lsgmj%9o)+55iErEIvq@&5k|rr_um8zUE39Iwbmhf z8im@lGnkm%QN&4Z{pN8&HCt zNCvBwxNHD$UxlyGO4GrgN%z4Y`+KG-Eh4Nx)!nglOYhN?^VudMMN^&zPLSy0Tx2ML zr0v>%G>u`_**GX1r$%SXWt$;5npbKGMZlN?K^>^JoMG--qutf@@tD-v{x13zHKbgf zGy}#x6HH6~)+(h>XAp9mE~t4jm2zJeD6O_^ORDckap?1?ZS9zywe946UE6MqoanyZ z5Ih)BnP5ERYTJW&w8sQl06{OqdXplZ!t>maoZp9=KFr0;q9hy|{Jh#Y3Q4s)>J??v z_u-dIQXiJ@HDrC&eR&o>i7^)^9<=V3^0Pc>X=~3O91hP4=EGkjTuS^ShK~-4ui`%ctXGiOLEqE`52Eo zTraV~-v@ISf(yi5(LKM87>%f*k>OKCrMho@uuiv0Jpx^KJT*Upc8c-WIRiJ3PmI0Y z1vDiGdIWyY)PFs`h)>{1BDVdMsp4JWZ2!2|%HmB|pJ-#M0NoJ8T|SKl6H|8i7g0&6 z3|OfY4h_YLD?Z}!?Ov{CrJ#>InoF^q(YA-Zc?TEqNT%=+MS*%h1e^~$UiRgIp=XWqPCNTO`D(3}vphxu-Vo z^tMss5^cZL4zrG7^0|I!A8nG?YPlk@h_C)D307~^l3WyJG)3f0O$CRd1$S$SSiShG z&2i_nTqW%LmjL*PA@YoB#5^Ad8oFY!oAEhOjc;9ZN+wH7_GhY)h@H>!de4L>=pdNF zEa+FPHri)GcNBMHA4`Oib6?ay^O9IBjGhUg8HQ3^9!07xOSJ9hjV%n`Q5c;L>h6f> zON-(Vzn7A78xh!`3hdZs5$-VO1sETZ0lNN6?0Z6b%L%`QnqGxT(IXUnZp!Mbul39_ z-f}Siwzk`b@ZW-#h$qFvcrb}X@PJxt>wb@(;7EDOBk(Qx!iko-Zcp)SHQW0yUn=p5 zu4)>sva&zKYVgiHR7$t1xteb;@yW3v*)S zp=iHu6VKmSip%=k!S^NqoZ8SE74#!?@7mapQi69=*GPk?1UnAy#}y&pb?n<7X52C5 zSx_#4sm=}Kz4$C&s%B6(O)#D*KpbaDUWB0)Gisjrna@89Ua%z1S|&vj%D%X_XKd$~Y%*wNRESd-Xz|1<9SUBa#2+rONY_V^boSoy5ENomf?UIlPS zg|^(mip$*1KSg%W=}L>A8qyh`U)1we6e9ui8@hx)xXCjf<7p=E6(wX|IEh9?#BD>3 zoIy=!Q{VivEX`=Hf0AOUyD*#Jz$9a?M^ID$6_Pdg+Az`B4u9%WepVgQq-HF3Gzydd z&Za$85ksC%V}B+ks1tkIgI+PW1QNIklx)6I8iW=4yt^OVm)`6(=i3H@C*) zQ8Xww(2fughyGLdWs3?7Ulk&f6J!e6qz}hN&3#`Ox@nZY^=p#?0E8a;@_8?E`bj^c zk8mwSvskG;v5;U?77{1Xz&F@bn~r^%XW_l-J|WNlI)xZcMon@!a=dH?;b3e|tU-iB zZE`&O&gXj^7?ii$576@uUkub?K;&$t&iT&z#{qq<_vM48F%95*BBzz+0wrXgrFoUg z;hPR`vte{BK!by$7CQ!PLYqT(U{~FKIeIqQzTEoT`0fX@KvHHg>E#?$U*r*`L!Ysr zResn!rx!}6Z0cxz_VZzmb__s{G`1gbLu`&LKA8h&eL7|(o65~FcxCZ9jD`C-L}Q*= zAt4vSF+U)*shjvu;5&Z38V#DXXkhY-82{^BGxzH2-;SvWi}$nUNK?jR{QlQ}IzfPJ z%z)T{2P5zwkUolj7aUoozjws1`9Aj~OU|uZL&j4NR6h^nO*Y-Znn*^g^u}+GvePN& zG&md@m~#8KddDT`{ogeiEJBOsjs(r0z8u@~9j{dk9t=R4(ihh}0%Yx9$097U2Eu9Zq;ji4@l zg2N=2ttgjwxzqp|I`i9JxefrV%<->N+JdZ#JTfi(z2RMf5VW^_(!&7Y+Hx)7Vl>T|5Y z%l6)4FntN%zTw*WGT9z#?EBR6ukBOT506IQFbqHUVqs`Ur*%6vnEZHwA*uT^oTU(x$`0axh9ITE|`_ooDs`hYPn|tsHLV{5$`w-AN^1`;;~x&TWvDJ!Ms$&&#NAjWl%kLx)yO?#qesH|*NX)LO1r zQc7a2VQ8XC#C^+gO7>0UCa)w(jGylf2#oX=oV!Bk!+;bRl@4dbPFkebH4+~bb#w2W z@clglwt8poBIEcC!q8yn(;x;h_(g5G)VaXr2EW{J=Nt9xJ6I)!g_}v}IMcx1xTowi zrTHC^27yu)u;W-`~ zdagc2>(3n3jHsrsWl!aq$ORr059RU2HTuto`cdBGv?>=@?Yf5k7i@gqe+xPQ7IxWPMP{JZ(_tI?@LAde4JMJ}6&=$W;yc$_{Fa~Hk4Zg2!E%(a3)|2~C* zs6KN+Yj9y=WHg32hDhG=qUk1b;bom7~bo$jRp{OC;$8RGl8@hPyw``M@H4hV0m z0g?N}E6LbtOA$R(KKx^b7-BY%QM3LjxZczN9^Ay|dpgZA-`wmLadw8$ucMQ|$A{PX z(5Ppmbs&39ORk^aCP~||!-wh6CeL)4mFwkeMg;p#QWPF?B!Vy@Ul zB!l757Ha&UJ4iE<#>pZ3ZsCYLI4Eqgo6*w;gcDsC-Y=E2;IYn5J^L)p$jdXEs7ehR z_D!Ph_r1~>&yKy*PUFN&<@|yKS7YTJQHKGowTx*5#3WRz=pj6>?b1_(>0f(E@U+k( ze7%Ure6D9#22>~fjgxY5`OhPXWKKuNO~zudV~AWWFY2NrCpxIr+a1gI z)L$uPg5FTurFC?mmKM1pEn=CXYvmMe$o#3cBnu`w(oXZQ{_4%d4U_wyCW(!#p4NQm zkc{s|24x7=Oe~F4RfehTYy+!8h_PxCQ0G^@&(d#iKQ8|Ln-|eFsvdm#{smoR8=w(W zr5kwWMDN6=4rP(hbQ;jouW=TEj;NkEBglj4%^mQ@4n1Os1HrEXQl=UX+SjpOUzAwl z;>Id6uZgCgzpEBmk{dyX?Fk(J?NV zr?~_=VyS_pBSiKYMzy&q0l3k^wV^1_(F);f&0i741{X?qCQY+VNHC8W872^dxe__0 z7|oDW3~vXtJDw?0Bc`arf8(G3`j-eM8CmI9NWP^I5+keT$S4-=`R3xG)w-!#?L$7M z<7Sh0Q5N^z39qYf4@0ghrQ*C03lx)|y7%+yLG?4`2w}HX?pI|awb~a1Z7C&+H*M)lZ^lwl zR(U0*_&rL7ih|J|Ph&{GUGgq0pRpp-ps8(2J2{=_3{}Y%>l2xZ1lur&KNPc zsnUitLoZd((kZ36s*Qw0G;#!U$T&{Zs#}9jKaHh6h`2aF=t;{`$1f}8qD&DZ;pQD` zr_*_LwBnW7NuNKdX|nb>b81rTsK_^jFUzI>byk4`F-g!IL`QEUKptd8RG^a2(-JEk z&^lq)!z>4UIWm>k{_T%Y?7?Yv+9Y~|Y3E-!@5FL{+y2&xZTU#akMD--@^QN+#E^t? zhBw@`;sZd*I(+-`%Wd10RV}h_OLX0j@9DaZan24ki&zJ4YBSi!3OnX1icEVJ!Vz$% zgt7n!?S}HSh6iD=qbIGGq)as`GN3rr;kD2a~>E!}|bk&e zw%qaJmSf*tuC{-Gp*TW|r`z)s#2#k#rAwi(h$tCGwe3$r#bQjm8p{;rL=fMq9+MAI z$vz3vdGCyb?3B)Rx_U9t6XBVBL5LIii^oqKstt7jb`{RHbFA*?3Phwlm)lzWa+j!| zNo*@Lt1>oT)=TS*04X*qd2(WtztQdAM!egDe-^ZbWn|v*Wm{3c0=g%2_hWsJ-8#`Y zxpGVfpUB^_qc8`SE%4pSVi;^xTYB^f{#Q(`pZy@&kT(PjswS{SS+@W^ey{WQPwf2$`YK4w`g4^voH~ch#gElZyq4)a1?zG}u0SnQC}^1^_wo>Jwv{wcb91AJC**2>CHU zOaq}H+Gtwx`DOdx3ARN|HtD)35M16ZC-$KVTn`a?dvmpgv7`lybqUFe&Xq6P(iZ+Z z?(wm{<;NVRCA-|NhF#Id2sGkH?r0-x@pL=Z&i9#>WU}+^wzWWF98KSP)AE@%2(5QUm*J&xL2T0zMnil??DrPRf-N2p1jm# z5lRRpp^|^du3j*-U?`9fq)5kqr}VB!4;mcP4Ycx_LdL_@N=B5D7jk^w?GymVPdZv4 zVyX^{kos%JSLTG>`B@mG_S9C|DB!`<)Q1+4j0G2wSd|{r%cw>lK!1> z0bBw;Hi>S5w{9=vM*kk9qt_P+yVt*9{j*Yzyky0?Vuhuu8q|@Bcc;#zyImX6?j2Q! z43>RGu;YY6K25(RlS0oTg0csoWy?|)lV!l`a+69;huA8>_oJ{*m+xHmeB!*m8UWjr z2+pA$AM~u5-g%p*bQMzvmynSN=(?PL-rI(3^I4=*PRocbBD2$c;$j_t zSTuAyUlN2-?G_P-pRsQFLiY}04-fM;;vJ#=&o*Fv{3kS=EI=~MOHq&2DjM}5`x+`aWP(8vf1!ReLmPZd$fssJ% z^T0l}I1S+71E|sV{tF@+WI$JYfetUOg8T3YC(UQL{_{Zfi(@R_Hsq6sAN^WJYC7-} zQM!adj!)tE!~9D`YHDzjmgc#2$IBPD-`WVk#oB`9PCl*vvIZ^X6a17k1C+pmHQ;vB zraEHurk#-9PTbX@h2ZU}$2lf6>Q~O3(YoF~|2a|TF`VC>@#hnOAyzOs#23AL@{99D zS+ir6wu-EuDl;G~ zN(^C1@v&^Ycz&!A1A*WpyR)Ng0jFycH!u|j{yqz6s7T#N;@2o|xL%rz zK%?mbD@Sw!%a2s*@2w5XOJm@;W&afWZN^o#hz>0S4AI)=*_+AN z8;-dy6(e0RCc|XcRC3z;WxUh^3RNVWYQh>-37pf|mj_SL5BH-UgC!;h*KaufyWgOa zResrN5#hgJY6>7b%$PK~`_;^jC@+_&HXST10(?LNUMlK}I-L6;Z)l9Cvoh^>XP8>z zN6J*d;VCwgj?PXh|afu*fvg@{x{)x$L~ofVv;h&+p0kz<_b z8oY_tp7z1RbI;e9(`lH9g%_gd$au(~NIe(Cxu=)xQYQry3L(;Hh+`-z3>?i^9b8)q z+`XO|lEHbL3tIu$9{|KZg6`2vWzZc4G}Dh5k{D*#_2$m30m|Ui9p7y&&=16u>veE` z34$EVI=ndbPR>F@?5OE>388`tgX-=>2R7z}4Rc88I{cL|fJQ`sJRMUcatcloge*yA zh7!H+vITn%KkjO^R=B`14jIisMkdPV%&a8M0H+($_4Q8lQiq81)ASUhXML>aYwwc? zk}&X~8uCuqUq~`Y^S&+|5pshjRg97Fwe~xw%mkHuv^(xt6aYKbEAP@Iy|Ijc-v$ft zj^qfsL${YlXEP+({m1m|{`^L*;2 z?e|z$pdc}kR`lSRJJGK%>Rx!*sX2mYj+`Uftf|P&FzL81^!2jEncI$i!ZYr}XlHtO zO-!RiJr%2d&X-ETPW_H9n%~P5ZyX?lEAOC~HR~%5$_L)!jQ#uxH3()LOm<`jwd6%A z4dylo38$K}drRB9ZFpF$NFavG0?5A|=!PFu0_4Ja>4_|1;#O|x5?X#XCxqH5?w!e8 zzNGh$BRR+HdF}NS(fXtVbu+{9^p6!5iN3B*W21GuX2Sn+Qf+;KKCX}TjDYaZSBFCq ztzJGJaq~iV__C-gp?8kPYw2Smf9!QlL*Ydn$Rv(f`MkG}eUXHJwaCQw%*8rG44)BS zDS`1S>4F<;Sqe!$gMl-0_^JCBlxY{p>ptT|cOHt&+g zH3VGM5Bg#$+5Y)hPJT6h$S^`efVOX+{<0waY+JnoFn$LZ4n}6lX$MdlaV221p5kp2 zFAedmAM>FkwfqxgFZ_4u$&vUKXT08Aa1$iXHg;yO{^oBj==w3q{e70-Me3&>eR%lp zX*-DdL~-w@8@ai!pA%7GvI0e>;)lOiw?RtFkWyp}4*L3>r^3}`F={9r!wX9BV*R0i zH1awHO-2xz9~qnmY9y~;!Z?atXkTu9{9dK7EBnM{{_t&Rs>neUj?mlI``}&gJ{$CR zU&)PbcsM^+r+iq-C={gShcp=8E)lZkLk@V679F2c*yPr@d=thoVA_iIIdT|rQGcd4 zg~?;zWAYv&j)K1h>6BuR*nZ*qqa}CI_#e^By2W?i`K|pzVlx*ca20QoYU=H{LX)LQ zZ3sqN`Z?2v?#FbOO$LiC<;E?w*H@>M(1jJWFk~WZLsi89Y3W|<>fTftzxee4(O=YeZxu@E0=2<7W1IEVP2S#*GaZXoBtd?kQonNDB z1PCr2mgLx%na-VmOky8*2&MIwOQVG!|9c3TV1kNQNhmQu(1(I)4k&)iKay|-dmn!y zf{)IPlPZlYb$Q7Wd+3Kl?_1$_3!Ge%Pi+Ze9~he;cf-_*avHGVFknS9WF5qoWQ@_h zBU#X^ngJBfiB=N6y)-W{&jw_bPJze-JQ7JV{8Y^)HJT;5!N>u4>rw7oUe4EhYi&6* z%7c`lkoC~_+s4<++uR@6`4^b=^?#BVcpUT5Ii0aR03(Wx4p^T3yaGl$p_AEC3>1Dh z-`eHaMSP_I`spG>&bpz+IU>hlRHG?*swmcH~0+rs; z`2T_E=Xb0;Be#vj&n6t+5~wC3hmb4hb}VsB4C$p0@=aXvEMzSSPGrZ%vcj!;bA80zpLj+tBG?l@Xx!u4j?}C89hovloI#v`+Y-?H zlW*XA4-`b}t~m?Y7rZyvEh%{~Qgs?Q@486buNV#WzCSI@;RShRXWB|4hw!4otu>u`t> z&Bc|4-}|YsMmZBz4tQkm$wz+ql)C_|wKo{%kej+%auNnrmAfWSLd>NMay8+CED6DG z2I`i`c(lIF>sM28req`XL`l(km)i5^` zjBujy*@1o`(VXRK#&!t&<48L~;t~oRg*LjzBbY1?BlTkKLyw)X@WP;2arOXhD?l1@ zaQ@!rhBH?}Zl3fz8ZZ@*hAa1hW%3si-;GuJ(|raptK+^I7wq^LH8cW6pV35Qv4cJk z=j~G$7U10(Dpc8)ksB!;5^BSP= zU=kJJXymx}3FL=Kfh^ewJmR7E1}EG~ivP+fk+EahV9n(ORXB-$l!;Z&z2=5KjQVM0 zN~A3htyXnG<~fLxC^m`%e#r!0!lhD%6;jmH2WU}x85oa;*aFB`(|a_#KAJ$3q9d! zIMk<}+@LNVqAsAm5LQ44#^Ehgk|F1t3E*#|m}>wxLFILoRSQI}w9) z;rke89}jM8N3+zMTTVGpJvqTE7kKDU5=q!grg=ytVe;K69uoim9}xU4{7T8J;9AUt TMokPm#R!o8EH7Rqsvr12Ay!q# literal 0 HcmV?d00001 diff --git a/_static/og-image.png b/_static/og-image.png deleted file mode 100644 index d792932b87e43d923608d2aadc841e7b0a774fcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48408 zcmeEt`9IWc_^%~PWY3m0C1orj`<5hy5XM-?B&4w~!yw_2J(QlY%Tf}98T&TYEZHN2 zj4f-%I`-Z9=y{&+IX|3#;JjYv^P^YX*YdvJ*ZaEeyC_3_Z3en4bYx^?438e(HzFgu zfF&cN@S&v!eqwMpz>16vH}&Ygh6!?PW#W;ul`kL7h6JrgD81+mnMk6L2eGJChM!QT z6xDi_b*3p>&|@apP>WacSqFc7$D`Wl7IJ3Rdlc)IDRd=`z^-Fnw>*yy)4`F>~h(CGk*wWu~YyAl{e)l9`dZj&$@;&F*U)z}z z`v!jpwM9(^6$ROz%%7Gm2QBf~1WApZT9>O$$(L0AkZ-7DDQYD0*ql6q+s?j(J0tGM zHXLS{c+B$zvUQ92M|bb-awe$>1hyNrW^OsG_qw#r@Z~Kmti9=1M8Mbj_A45>fg}X) z>C#qp*!SeuxIfSPLbq;Z(l$Q?I~Y_=(b+*(S{<1dTk&-3L4wl7-7wF)2>s9V(2`mN zjGZoCzBIR}s`LlpsyyLR7`;JwGtCEL;lWmX#Boi=+syjQo+yWJiOW}wi^KH1oxO|R z-U4gZma_w1KNakgr5b*~rBG*MxB47LoH_L%kp}!SwyHG!mGs3w%`W%fQI495>3_ry z(RA~e@0~0`1$~MJNop?(7`M%L=a}vf|1mLzm)B=0D-NX zc49GWyRn#+&+U+1qc)U}6%6=EL_^d~5<+QYijFdO_4aLRrlsl?QF*2Hoj9@88`?=W zkK-g7lDW*sAH9({xuaNm=Wj0aeScfWhDA_YMgREka9_HjeP~2l8jKQfdjI>aHTAXO z6gq#Nz}$B0nysB@H9A`j$9k(Y2Pq3OVLul#J!N)AXe3ow^wkcn6i&a(Of2PtsKBao zpQ{Kpo4c-+RujE?ZdKCr3ix{G{INAVe{@DlaiucV@Tm#-b2;KMbr($zd?Jo>hqc7 zxg=!mGUQ1uo9T$%q2N(2UOW*(>6UbD9^YOEBnpJhDYWVx)%m?@cL0CDR64qL8GKDQ zAZj4jw7in_D}9|u&dJ19`-mod#`bqw;e+J|zqz4EaVeFv<(p-yd5ba~;R|Yh`vDut zR{>i$ewCeBnvNLkUG9@rS5_dXpwvf>pJWdnKmJ=@U(Hi7{pJ2o_nB;0a}?%I&XBK{ z%#LZX5rH6CJT|cW{qZWiYXWENhpNYK!im)L__@(w|TvJbH+3P?MiHc<#Tdhkr9Mlc!d!*2Hkq_Ve>vC8CyQV2; zVPnLNhS^2m1_k8W;2zzg1U?7nx%uw-9z8nm>vTlX?U2AX_m!cHD(rbG;G)&0csq%GpY(R)vyeIA4 zkjq)dgny8UX^c0j**mR~v^p5PcbqBk*p3`9L_l!lEOD??XZ1&iqzY-Z#o6n*d*y-Y z@k5x(3t8kZ(%Vdz%1zYG0gEqp#=?F+D94nj`yt-$HR6bu&5YL<2AcOaN2kXgKZf$% z!nC^@LSq|ZHVZ6aVIRJ7r%ox$-Qi3!FPeMkeL{+5b~)P`U8=D;PO4XqbveQ@DY&|I z4(EQY%_U$zYFShAp>t{#mK?$tFB;+ZLu;Rh1;JkA2 zC=-o^Ue5ll0H3N@NbZ!jxGhU5;5@)ZvwF&|i7dq`*~;@DzR&F8D0S6UH@X74LLif1 z+{u&NV#$O{rh!6c;-aAL7G& zZF;AntvXMVb?ddzMXA?;h-w{)kEAZ~x~&53{*vYvQkMi9M&BhHi735`v#5B$R!7i& z23~y@m6{}y@N{{9G^{HT-T!HFVU>^^Pxa>{ewvgz4_rMxelo<@VK=iTj~BTU*hUaw zc`CZFYN?03N6f6K_+m$IhVb*TG3UgzB(CDRg1p_?X7MrYGkBe*E4szIsERt5JC${T zCO>D>3=8zFj?BS?{jKixv#UPO{x}pY4nmY=b*%*)F{zxqYuw${X0xas^fA}6C4NkR zqA7-JCm^NTG>g&h-i94(pfirtfLs|UyNXgWH+F2K_=(nq!mel6Z1od;yne0ik{;T3 z&tqctf>wKE{x}ibo5TVl9(|-)?jJw-)jT2q-zrkccGOz|VxD&kx|9)MF9=+RKr-MREwfy3{YuJW;Dpf-n;u9qRecd!P{4%v)k?<(1Xhb}@D z#cMon_YY`Ll60oV(aW3KGzMIm0VqkRFlAz`g*GdD(KQm>;}h0pTf>jghKcUij+H#T za8~h8Bp8w={pQtt7k#hvO$O{uFAIoHp0>TQhM;FrkQ>k)4k;*t69j!sOb$Sa!#dm1 zX$#?%&toAYrLAa>XC$~^>`nF}2!B+D8Omk$tO5N3tM^hr((KRQhCR!j!IRr;%P$*D z1+M=bQ8&b8i}PYid3kyQybTZAHBLxfqkW+Fngp*lG~2=~o)|1!io4%hpmdsO^i%H8 zrYD^dhF7LD_)gwm z1(75j%c5&t#lzhtIy;I(m>^u;fevbae`sj`U(>Rx8Dm8vJOeaiC~X(O4H=NkIHYWb zF!XVXirh`9@`)T|g*JQv6-FvR*n`WV144;hYtRAzosZVBUzN-InL{W3~k{ zmm;fvjZ?NMV=r$3I6aJK;E;sYylF=l^O6dTC7?gw^x#C{xGoRx?}dmW*8E+JUU$)Y_9?Z7e+zG;59ibN=m$FB@gT4lgZ-GB%2=+ z{mZa(5>}NWYCvfX_+*qhi_)no!1wReKl`N3(v`K;%ou6{=H6 z#DaVzc)-)#vM!EMy}+OJ*=X{Px7wD>KiPnNFktDZuTBTVWuY*`|r@o>2E&-;O%`J>wr@ZeQfZ~`5!|)y)eUV z=n8VQy~2}8Pes3Utlz#tMZD=|*}n(r$4VAV@InNl_n8__f2B@9hTA|8ceORTo{rYN zq0D;B5Wqre1|~;pNuy!H4OIq#89#jS2!kW;=XQNwWZM+3GC9gDf@|IUB^{a$O1SDq{Zt_W@l0-O+fD8}jJmS>@SE{p&pSD^=cW zs7OdiO|nS&r!de?zd#-3R@HcO&HJ^cmDAeE8dl%E9sy;_GG*&#KTMtS_!{xzl)F!a z`eu5=$7=kduXn^V;uPD$0@OthH&*pjp3(K)$50SShxeLES6W25pV@qGQhV$37|V-) zFc5r8RxPvgs4GC}uqYfd$sQu=IzJ9tt%kX)m7J|m?gVfIeR?$|<$L>3IAyA+(rJ^4 zFXZ6H&f?im8FzVviTjNw3eb54rQedL6kM zhDL6wOPh&I>I$7pXfm?fVtgF9?BBnE_VEyTbS=Kz9q;yP5v8oaiD8@Kv@lYskHP%( zUuaBzWi7??h}ZfuM)Fk5wTLZ#W_@N#=D7%%>hr5^_T+We4yLvzn%aAMR=&6{+42cV zuUQyr7R7=*R$i_hzt7KjHLgSZ z$0F}d;pc3MH2f;77qxTcWOOqth*(IGw&Ki{nqlBFC%Sy6~;amkBcOhSqia z7g<+M2@HK}KjW?HW1{Pwlp3T+#Nk;sj5ni8l?2qD!AuC+CQ9f)m9}TENAAV{7jf66 z3CM@Z+`yxLRl@{%riDnz)s$zU`4f<4^Hq+owT5$xeQO(Pq$?JYI=zI!$0v$5qIQb@ zpSv9N__WIy(d#o{zb)Zh+>4t~4`;C_ zlPddFYm5CSaL=r|7KwjAC%FE-I^mMp$-DP7&_H#+qpYFWP`?@Qx>d_W9W#brtF<>| zXXYR?VC~m?)8mHz3e|kB!gSJT!a1;~;*nyyZer zzB1S%e!v8$gZZrMAw`cawErEvoAQj~pLBn}#)rk73{)}Vb{is%rHqv^L-TZf9mIYW zL#vRV#xpfeIUsGaBJ9@jfn6&x-L;rrJj#$=@-k-S#tfBO5pG}$yqdgAl+A7ZlssKL+8S|vwa9gP2?*tDO8Lr#@Lp=8eLpqh2U7XDr&0?q*pt+_niC;_cq92-8KDgNGgWtKO=?a7t zuBMJYU9T-t;UK|v`|4|r{;q-8J3(e)xSXAW!*4FH|AghPkrK@BUQB&wa0QnPFXk_= zizL;x>6M^>!<@#v`nx5*qc=N$ZR}1Ta{}?tRH*$LUH?q_>BKm?3ej6H&5xN(NDq)T zJx1COjH64%$kF8_+rpVqvz+a3h7WOWJ+f==@;&n^571ssQT5 zasthAAe+Gp$t<&1N7Gk27dg+=S57;Ril_gIG?nTG+JV*^h)A)$x>B;!BHrU83FxW? zw^hrnJJ!&jHFCEjIk0~xv^QgsQ^}$KG$J|+wR>C^yl%*O>)c{rL{q_gKogAx3b%lJ z0uJMlxFof)Bt|{0a@C5;pZbscsspa+xM(ZE%y}@o>`U#<@TD5avM&^D&W*8%=E1aH zDlEMgO4>|hVZokyEP5?wj%D@#!+6Mad)}+*mOR+)Rx~OY0rA-DsW024<6*`QcF-!{ z5V7ti*Oh~I_STPql=pO=t{Nf>~eNAiMx(l1`pDksd9(axw{q1 z>!X1+wAW_~C&2!k=V(6IBiUQtbBY z)z=yti>5Aq498|W$YrPJ1_0J*8RpXxFTvyTU5d63At?V>9Rs?VRS3P)_a8;X;uzc2 z!6co@^jzyxGJH#%K_l>PEIZw)g6FP*cZ@G{#1=X>FwGI(nvN`~JN$0c1dqnD~d zR@{J5wK9siaGJJEC<|24>+@Z++7CnT?J|%A@?pFFwe#*EF&J?}2G+Z*q?BBfJ~6}fi*JXtTa8?^ z<-4Y*?zWmAC2!pvX%qmLP7GKBSAGn2vsB;fg5e4#SxIoSS9_>tWCbhs0qs9--|f|HY$yHmgVo&Ia*9<>kCkT$Ho^jS<5i2-GENb2ta(C z9tSzO^7eRnV_lxbGo(gA?15G(4Xft{xp6}Jyhuy6~#Y2^KFt0j5`KWwuH@E9(luLf zdqf1g_K053kFz+A65fn5n;%fUC$DZH0;YX_+L(+xBv1N*ClDulE*U>``=)0$$I%u` z*{eTiz-!s7;j{QCCvzVg7b6_JLJ%rz$%fH^{&z;8G!PAG7?liVVgqvCf(?^CQB@%< zlsFoddrB|>G}BbiF;#1vn7G5O=)*cYv7L1xix zU<%5LW))p|@9<)VX$tAsGzr~^2?d3ld>9?+^C7=B=WpIq{(m8Oxm*HPlSnyi^(%YT z94NF{$dWL1k+O0BuivRPuIuUfgIh7fJ`zxRNw=h!OCzWcJ8{GI#U zp>x6P-Huj0mu~XXP}$Bl^q}l7xG=0+k;S{DS?3!kUQ5AHE6X zp!Gh`7OCrl%RydZl8fI`45T)mvB9LU1~SW2x~1d42JUv~ulJX^2CdIu`45PEK!^ce zosWS4+o%GNHjemr45U(=6XVItcZVG#=e3469GE?ak>0;28kJHPB1obe3T@~rd3or( zk{r@%piDC(f-Yx(M&=dR{vfY7FKr2B}rAzOac1Seg>c4 zAq9;!moHa!!%6$i!iJHk#deMN=hj91PgWi@rCRf0J=@V(du2?eGp-95n<{`ofQJVo zS{Mfz^uo+JK<(Sn-c6#y|1!s;WlGb2XFWM!4-^IQUx2c6jh%V|mG&PMm;-Z<0FU!I z8!Xa79xwPpfw(I(l*6u-axaZkv7d<7e8MQD@M*~4ONo8n&5>= z?PYZ7XTw5oL!1!1_V3C3skC=KIqrGw~?niCL(x(@x4xc}izYo7c%SfU6_U(ni zVx(TUe%dFt5z{c?tNaOfnXZeovS#5WW}YgK-q3&J@}2T^t0t@9i!ibd*u&MK$DdQm z8JVs&afQ0{j9RQNDekQ;uT9nktWS2VMNi3Z`Gwtnvs=0VSI^v12b#j=tC!5=IIxH5 z{(bcp%$_^oIg-xLadfCC#767Ia@JHAy7l2KIEtF2vqVIrJ|M&Xt-rgtgrp>S6#R3; zBk>M)ax$(cNto;*MdEF%7xH_e+g)hnq|!|ejKxQQ*PqEl{V0d8{2L}R+YB5I_h`tQ z2pS@o%v6#?XvkpKUy-Bt?!~#>6ol<`O(}gLwl;q!iI$=uo0W_Yg4XbAT3(oi`@ERz zm5f(dF;EtTkF@`$E7UW7x+TFwIO8c9`{ls;us zm!zltpC4lb#EWo-ohs=ZcA)4556MAgC3_=^yH6_zyXF3I+(9>$=0{hA|q zSjrX5;T6&vE!JO9=>3k}{KM0=7d$7cyQyo?cd|BiTBa7OSNlxjW%& zy?*PB>8Wcw`vtQ5w_rQ<72lNhwH%(U*B7==9`VbhFsKeaTkGIokC&07^8dT)gD?3a z3-Re`N#E4hy&oxm%radr(RF-0a&nL!@!C{Ix&AY9+}#i+T}BM9M)B>v|I4{C)8v;I z|8t(_Mq0~@kLHVPXu~VDnK7*3R`gpD#)4=_b`|3T4$NzEdP~}WWJV;s$)6R#5wovY z;rfZb>B)e33PVSxmEn}kHR(FLw3&lyi<(<_zC$zqvHO@KhwI?-ew~7qWHn6AYF;Op z#_W@4*pwU>FfGNtBN6R4uhW}3?ItWy{j2B5{!r-m48>(=W=i?h+pyIU9|A1pK29`N z46166#QFaOaboFgJYNOL(wo(>{3FxIB3VT#hdHb?$nKh8&BWe|aZuQ&W(GYKt#j}a zok~t>HH8&1aboA%K`0T%=yo)-2qT;Y6FuJnvT5>X__r#^{uG=4Oq7HdXj1Pob>WGJ z@*c3e_cjZZy>=T`^k3r^O#O1n%+iC3oJ^2$gSt@qESUW%PShAV1Iy?4!n}!s$k3TL zjm7?#$iL5jFPJ9SkX#p214;O$voj7VanCitr9Rnb{kPMQNdCGefHVpCB zZ+Wk#JQm{SSm|OoJggCg6ux9eoMm5kT@?F=5`t+I(^WKzJ~J9)j2g2ha~iZK9zAXb zOV9O_pC{+yb@KN3{QS6ED^ewP>sAI$Mr;_?kK7nj?JJnw$W}C@r4{swYFLa)bNr&; z&8w+1>z}Ll7nT*-r(SXwy+7pMxkj`nYQdRyz;O1Rh@o{O79Sw}daVJwnNRkr*CT$d zrF5A8ZUJiozHv?FJ)}^sh^sfZnVeKp#LpzRSWW8RD9ijx6)icMDIAbqb-JS{2J21ggRulfFTCWe0~N>B#79H7aI5bxnyaOp@y>8iBo@EY z;meXUe9v4C@UC9)k?fJcoghP``Y|oK#8wVw4rC$OusK@K_Fc4U*MabdFI3N_wAxge z)a^?2QX!`fMn?8DF($=XNa1IW0RTXM2SeP}?XZhRSA?dW|qNYn!&MEy!qHZ*#K2YB&-tb+u__^Y-AOsf*Tt+apy1h)@FGnqEKIdIBn z9Kc<-^4%6kBL?*zhaM;nzmHWMZiaXjo=p54K0VcXEYdGA=D(S-^7(WNCxVk07oFjl zEEMn1vaZgJSKH0#x05sCNv>Dp2?$f)_5D$@#jU}wn)zg1CS!|s{XzB%p1RzMeZqWM zqVKEKtJ(M-eM~;T{B0&$y@eIpx37u|LS-Jojt)NQND=x(Q1ls)2Adw=h2p8RUEF41 zV}|AA72A36rB<};J7C2VENi?r4vIqV*o7Pi&zt|cUz}8#Kvy*3rZ6{$XT*<;e z(LZ7AQP43(pq2K6k(5pp*x-A7-o-{}LKCL1r3*mc#L341*Kf1?KWNCvm}&Nw9u3)` zaeF5MI|lBu&qQIevvd^9L3q&+my4IisU0g7PlfVc-0ZdE`_k>|<83d`bSyy_JF|D~ z=1!#!)-2pvrrh|96>~lTNWIK_ z_2A>tq`%eU^A3D}B03Btgq+Q=SKjI6J({K~bHRSKMK_lVE z(0W(pZv1n328FUBk&fh;%3Wo}v}BQbiE-lk#Yu6Td3r~n>+Wbr%2LU@pFDOCD9c1f zA9tkF|D{5-GVD)V+liE^ml!Rt{n}R^8{*^DSM>*7@)f&p`>(`jq~GF4tMYHB_KY{F zFgt@IWNv-$@(I~eF)gRAo>ELQ=l`wN*SfRqF>&fq5{$a(yN3Eef>-#E;HHrwtIe7O zEmJ6|3?sx~)_Bzyls@Oblw^{Z9amcqm45I*cRUlsEh4XTkmb`D&1C&ic<)>9psQz@ zo#H{$X5_k}SjV`~1+i<#uPrnJFJR8!9!eoIUqL<|P26NZ3%%__k;njH4z8w!G{}#~ z_-v~r&X^+J&IuA8c?!EFjL1#W1zC2g zIQV59DQadYe7OP5SM<2;jiaka7(T(#`ORdFRyI#iTpPW&uU6BomE&z?LN+igQx{rf)0*9Gxgef5aE(SfjR}+5pgo%o9qDQ0A3*=DrcSCZJ367P) zEG>{61iIfeGmE<4Gu6ywi_zXC@5Q*myAQjvfg1%@#xW})N z;4@T(teGEsDqdSz%IG5!2==dEmd3qh8rgmO4i(g|E^^6FyGgnyW+jUce z{ZrFW^c5NM?l=(bU9n$P*0;;N*YA`~l=L|ZT$yiS=lSf)!`oe=*uHcv#ta%83kf`Q z<{OfM;)z_C0;Sd}MtH*}JO@~#emofmy+g`+P$WLA-mDGZ8zXv1m%`Iub_orq670Np zeoQVp_|aO@v0&e9sPUx7K!8pkeDN}t=m9>LFy#A<`F#}`eLXIUfgarSkQKYTglR5I zgng+Z?Q=ui6%$@Sf-S%PHjZYiZAJHRy@71WPRMcDu7ShSYalG`pf(VuJTqW^Lhj2F zpe~R*r7K8TDT>4(oCSyYo#S#h zxzDEyKqhW3K&g6h1^64#+*TLd7#g_Ed1vNl?~a?HFm1liXht`Smt7FOSIklO?IB6w z;HB!xOAish#*HWU3zO;0g7TV2Zljc9532)U;z!}PLl3XPWp}{D7kg151CeGJz*Hby zH^)CV=8{gt*dgqI#A#}@*TkN6D!AS5;Ow~YaMQ;)#ptI`2qs7l0>|vNP?r{NCk$# zEVs{O=J^%%5VvWe_w8GklqcrRTb{O)xjpq)msp%;E{IXtI8p2<4+VW(%Z19^w%svq z42N6-0vWpg)Xs!is{6gg=Ux@&ckkrqJbZ0#3Cw~UA0-#YM12iyK3umNIu3Cy@ zKW%Nk%nriX%0a^vJPdcbKzuWJJqEy}3x%xnWyLM+XjB7I)~Ge0;%&Scgx+F*vF@ex z>4R5TO4BAU9bZi1Ajr1jNy#P?fUqZf73&4bln08IMQ_ktUgS>7#e!t*!=SaaJ+XkP z*&2dA18J)`yd9v{oRco}`>|r&m>3J@%C#5>_mgPI(}+rR9Aq`Rih+)DSWQclu;>Wf z1`YRsVu4N6$qaafrjRwolKPq%VqV}}_|6H9&~<#{J3O+sAl(rHs`1;F?N;e&hQD@R zWCcBjABYe2P^Su)dVd<-<39ON36#eE5eXGUj8_BMc>D;bIMd&J0|8i@5+e?4m~D3*XSjyp~ zA#)_KEFrtS->^$rka3u~1~y-L<^8oju;Jp~jq_>ftXScxU%-*w=T5buu3j8)TNF`> zw2zHN<^r#ozSb5s3_7iWjlSU_)U9agC?vRGw^d`FBs$au!UJ!Agkm5i+}NRFoTzET zW|tE=Jw(hl_MO4+b%bzZdeGXaPGqp~fz{7T?{u$di^-YoJ;5aa5dnrp;AmS~j^fde zol1_@yJhswZD2bPrm#e6Pt>@oD0CnSl3&{fs<5P)8nR!WHrA>9GjnRTp_3440qkky zx~|pHcc7iL5PnRd`@4a^JUl;6%T%Jidr4nCZGX^|fNZeIgAOU!p0HxBpPxvs8=?%% zJGTX)^JYgurFJ8PR-B93N0-p-MW_}Brlr5$sLaLC6gS2dhRg-lrfJzEQ7P(K)JzRT z>yXhUzBgF-xnW)VR&i?!9>4e!3jKB6cWE7=*q9b{N((gTtC?GOh)-g#4aaZ5&jl(o zmKjSHDLt9Jx|_W&?yBe|?|YQuQP%q_x)+HTadWIAA`vE}?>?P1kVzz7*lz~bN-8MO zwA%smcA#0KkQJs-Tq<8@4~Uxt4<{#y9+G#fTfIPbW&JJyQIUv5x>xMOcy|5Gr&nXl zV)mVai(a4GuxAHP3nyQ`Mw~@zoo^gy%@lgMf*my;{?&HxM($|~DY8=y`D&@yOUy`d zz7_O7J!Dm>6&?2OgTknw?*jO^6>TRatL|}I0VZ6)HO4OrJ-I7pRfPAS$A8%H!hAA? zvM+IBayYR%-dscc&4uVJ_xU&=19Qrq;)m-tU5yVV<_y|y1Gj|S{U=WgG`~jf2tl8m zho6E27}lS(Y*8!b`DMLhaM|lS$2KF-^}itJQMX|kwCd&7on2^Pc#wgEFpQ7d(Fdun zJb$MKu=8RP%HKdz3vmgfN?*JQS)VltfR-4zXeKOObqVg#0()ZjD>@#6OWMkqlRK*L zJL|HE@F{G$*F?8>-1y)m_5peKql`ERJ77g{FnjwVfP(Kz(3(YPN?L@&VrBYi3(f^O z?kwP0!bYP7f&K(YJ`Vi`!fHt)8xLtF2i=6?g`irVGt(=;QU@3_VrRkGyCRGa)M5Fm zPYvV25Y}JOTk6UBo-wDXy8Y1Wt6;+;>K)S`BezN#94en-~dI5v14#a;=$Ak#X-i>6@Z=Q*!>wWx)3P~ zS*vW8cA3Q+OR->}gMm9J4|3hLLiEE~RJ1uH8(476<2*c<6?aKY2Tmbiz<|~#YV&7&EIMHs&;d4`WC{>mapY#|8HlBFEQ2<8_ zE;e73pgRRNez{L^I`4Tf@avTfrrI2s1c6p$uD4^rH>CYaRA@W3n7FC6mVZmuxOnK( z7F0)f&vR?L>-}14-wfu8HI?zHrOIU|j=6#EXzzulEIXk>CuOysy@Ol6Z(a)&DUew#W+y531 zy(U_9iJGeL`Nf0TGJVg8-WGocrXbbxinp_gUmB9ULuXx5dRD2YJ|Pk^03iDjF2O7?R}`uR+`c%GfW?_rV6H(^ zLft03f)Rw7>#H*=-;CZHl#!5bQG2!U%v0uU`E=xhAgr_chO(?hn0-6wTteM#y4OT; zSHws>5m;W0sF^fuhtanViIp4{{ETFyiC>o9>q+ZKVS=`YncKVy%ZzC8D>eMaAH?T^6N z-uVg&_zh)P42F!?LO4Pplqu7Akmoe}$2FANfKO~KWNGskN+DP{pIGprf++gfsvG9y zKED;3ukY=g$`d56{cRv>?n3K0IZSG9{-OrhEEJX$^5-LOQtFQp428kc7k)Hcsre-2 zw;kPoF>8k5By8UPW74`$$7K_R*l@@b3lN5*w48xD9OCN~0x{sC#|VWrq2*hnD$y-yNX27b zyT2e#Cr#+2wr2E7lS}A{-Z{U(dc8>o+&%9K5wg~4!zc?p*a?YX4%oRaq7;4>i0GRA z@Y3YIPk5C-nc1ZpKNGU1!;1mFqc8rm$ih#`j``A?ue^+N`FdO_He({LogL42su&8E zp;4g_%hzD2IR`XfkC!*+#Y|So20V-E7b<4~mEfqXJCADK&=F`#-H}xyO)Zioa=7EU zXszsHFtvkXL&YV;=q7aN`$**hmg9BC&nx$CmX_tkGM{JUMSm}9G>Dz7jTsFcGqo}2fyOdZU@j1$s{Cf<*7CU2z0a9Mkkp2b4M9)@ zmzw)sPT_|YlHFAU*+zxE;!wK{wqDA({e>E%Aabdo8SOP4?H@hjB$A=Ab4xzJixPNS zg-zZpgOW9gMr2U`^O2!ZNq4E6o3>N6aeN3pvr@FB^Q(i#2NHxZTZ>jg_lX{_35&Bl zB~0@bT@$+MQxp2?>G6}WVT}nClRWq7A^$w=>E1I?l1xXnWfz*-@lOkB) z$-hc>Uu$H8Auhl0&6h=#bPBLHdN$@RjM0+AO6H%xB@3Q!KcyLUshpzcE75)$#2KJu zci|H7k#UfT-M-D%BQnWvY^Wyax|CO(+~Qd!jT3!djDyo-E8&-279${g$)izGhJJ#_cbH6KnqrxDy2t^DS3(CR;!=<4-rD?Vz}*|?wM@m*bnipN^yqQ4$gE`*Q`c)q421#j5EJII z1x?sj^e!2i59dFwzd@As`h_wgz?6gS$#7k_gJ!a>G|?GI^5eVB zUx3Zm9#_#5i)y;QW9SWf_5=jc_WX*veArD1DIP=LwrjE6ISx;hgj7s0S0N%J=zsX zTlHM`#}N_Vk6Lp_4Spcb{tCRfi*~7wqsLB#1X8Ck>#XUnOg&S7FtXTkDzmG3*(~9t zf$iwV%E9)D=Y?G!tfs6RVf>UMfVy{y`CH`DNNDh$$%??>9IFPS z-VFxJl<~m772Q|wdqIWu{JCBHsTov{g5-~ZFtj)!=wm_CQhGjp;oG2gn!V`^0WuEF zI9E0@Y-)*(ZD_@A`&v^&gxUo`jZ?ne#gceo8XI~{BWU;HsIQaRkI&5hncp_bPJe7` ze9CKk)))!>(P+GX18$I+yVvQtGJA1|&chLZcw(E}JM6)*E5^9)`VO(5g{Scjs+`1x zy5Rb2p9TfPjrduROl+7OSj@`oBpG)4C7A;~QY(*%(tvSCU0b9{ZU&H|(lp)0p~^=+Ik2 za9rPKGF|WPENDGCUwWr_>@QHff#7skRNTzS7kwzPli@dvyverTI5${x?1Up+?guvL z)_(KdPJ=<8a(DXqY5y_)kycvafbegpQ|N>UnQi%v#wxR(5!;|dQ!>HO^p(si$FL6B ztJFnrW66hMeao*ZI={mcD9TG^n_8sK-ZfP5%5U%&e{G;Ua-`_HPFV<+tERphq()Yj zb+C=e*{X_-wK-J`0rvsjRN8_@eGs^`WrR++u;N$=O4U!ima}%IQI{sroU#>+yU*Z! z+cX$4a_so^MC^8sas3ZybrkDw{Z;bBy>&yEzSu7w?eSk;+z2so^+BR;nXePClKdeq z)A-k3`eegT2OlIKEA|;Yp9|)=M`qUJXCXQbt8BM*5?VD;EVrghnX7vUiilF=(%1UA zb1LWeigx8h?GpPVkQnp2@Mvc9DLU$COdb~!+$d6V7FMoCrC3f8Y;T22GIHE`MdoO) z8?4pGK03v0HUE+GGw#7t(-A`oGk3sKs-|f1n>HMcGrUcu)VQ&hiQ_C!$oZ1Ndt4qwc(N4q zBhaD1i#jj_VUc%9?RpkbG&c|r<_VUajD>&8>^OVfxE?;7#dOY`)Zd!}xSYznG{pj8 zN0W0Ap~L$8rp5ACnfmFgKXYCV4NA zINF1Pwa|f^-o*x$0@>^tRTnRqp~YXSzdk-7>uGtgjrpeOuBUPEoYd`;oqRk@hVC&$ zA|yLno9oOiXfjo%5RTCN7SLoD2v#NzHteF2hMP&_n^qIH+mx{JpjY=|DDLxh!|u$@+c zXCDNRbNm5tm$9$t!>$14y0$rlcQzBP1ihLd^T0$W_2R54xrYc9sbRh4i=s@+Ck16= z4+lH8vo}NsM9FVN|MbgvvS4A6K6o4#jpgx`_AMpUk8HRQvJb*|vRlyD>+|-QIP#QV z#%?kYJ(3&zwSk_Uqm=m~B|@L!&y{_+;^0+Y{Q1#vtjEXRMB6%|^(AONUX^NbtOeh*J7J zQLN9~N3mJJ1880CV$+KXFHy;tkC>H=#wD1j&stugG-@8PGP|t{PHb6nd19Mh@4HsG zcMHa_y(8vDRkEB%BAWtB8`*T~!#v*Tf1(v*MWY}P{F4dRwvcqRqldkYP43ehs3;!T{L&u9S%}WJ5{}8|t-4t*Z`H#yd{@Uou3&AsCHBVfm5B$0C z*SDP+j>rJw985+>T;RnuNMBvMKu>G2Omd4&o_o*+_X~r^gt|BG**Xi?3{39}aS?b{ zr?pG^O>z z-Dd=uaJ827IRAS>xI^^4WkGqIzvf?#N9Y+5#=|g(g$QG@6cg0mj1w9*i+G*ODZBkR za7{<2U~JiDpiz_ICnV=E{p*(()Z}1S4>sx_b6{(#*ANSIaUUfF%=BT4a@OiM^XZ4s zM|;REsz0jG6R+Kr9rN4K+78xZymaSI9skCe3v;W5Aj|?UtWi02)`dOgyJ2!Eopy$X zKsh>l9tgSz!C}v8$OEh+zk+^{YRpH@B-0M@iI5!nhxAtgno~el zXqgeRmNvQ!2wCuD7#ULbH6?Tjjhg|K++PqP3gSXOOl-|wS4TF5xZJt?(9Isew zc%ilK5B!(uu56AI^x+E2ms=xYjkS1@OAcc}Em=Z1{|yxZZ5%gW8|DdW`{tht^2BSs zeS4Ha-KK0|h*R6BWH_4j9wfw$Vm>J@=?A4v#`8x$LfgNGHIGXqcp)-^t?X$ApzD$K z2~SsKewgpew2$MxSh`m@Yl?}ppaTf!3MDi*jikr z!Z_S2XXv|duG|NstypR#KW=Q#-0_?erK^VA_ZMLvwpR<+?-gz;NU`~1{dyQR_PW_* zzyhMP5nav3*FI&LvLD9@)1U`fW8ozqv-@^}$hnw9Q^X`l04ojH)!01=3jjrg8rScNp-~DITQYs%#Dbwc% z<9axFS%EPSs6!tbv-?%FN4|fp$J4Fsy$|^Nngm5vJ8a6)U3ucl`{F-7zjzl%*B{IO z-sT32u2DIw zM?5dwuV17#EodTsZyvc<&BvGdC<|r$`)`dSQ>fp`-5h#ZX4S&hz%Qcn_x7)o1?OI~ zu`GNw+JXsE-4&oZet;l%tGiY-mvU2(|9Ze{xmPDQ$)zUQuOA)%FQVQ%p6dVoA3w+5 zBU?t2#IaXGR#wW)aZch8DOnMxj+MhfnUx$xW|DC@hinecQL+^}wouvOAbb6udcQuu z@4s%Ix7*{|_v?N=uE*g^EwW~4HIkLtGDkfdkG`B{`Z(_3)}Jfoil2@!@1IW8lsSVz zte{j;Fn^<|(U0ceRV`AVgJibY{_L}X;EHK}q9@SIdBZ{}zC$tO(f9R<_oKx(d5J35 zw&O$*jc(#7ce72(9=aYzt9hQov$#ox7ICwAuX9B4ajCXkD?cuYlWG3dy6`;LuYJ4u z+NQb)R~3+jQ&t6Mg76Usyst z&IMnLPk8g!bhCbt<$Jos54i?*p%bJ-_LpY$E)czIcpxbS4R7+MYMq!Y9L3i#KhX6~ z;I+mV`4LM{>NQ{h&xYE}rJKMt-!j?uEL1~n*2`dF^??Mo2pEoc8rtlFhAp)AJ{eK0 z|I{DXR2Me;#aC2EKC&?Hcr4xCh2s7s%CcLB)8&4qil)<#6oU`NxY(b?cn6)nxgIez zG_7{{6(KQK{x=6G{*tqQBnSTWwP!w{Im|ljeVF0Hqk5*o>vb^K&|?|>)4yfjuC85X z^9t)nqn@pN=Qh|D?W?(}BvEi@aa5Qk+vxHE9xH`lJMm1?o7lVKUum|q(;SA!euq62 z-&$Q}`e(EdulwSTJAigt-S4@vgwm`qkZ{o~RL_VtfE$>>n)Ge8p@2#_+li|NEmb`N zc}?vCjlPFACs7zgHUIgSeD85XDh@i14>#)I|LWvDE&u&kOZaWSr z=mmq6I~t`pOo;=`lPY_a8F4$D6w5KaI+(Db$*edbG@m>xeRm42^GRp=C0l~thG&7H6|vn2@UR)gV#PYfA6UqFbrC;ntt`H z%9!RP_>9rU^z}j8+xPp@uhAHERb*tlnSkX^;LKzwRHQHdnn0`K#=_uIh zegtgQzna|>KxK4<7zZu{JFi0!rFw5sv73i+<`d-BbrEm>2b<9BzdtJnw|zoTl-#_w z=FCv#;+{f7i%WFyIz!)<98U^gH0<-Xbgd0`Zb{MOn6@S;K(O9$1ymMzczz=RePvf9 zLiy!__ohg>oVv_wtANi3MZbreeiNIrNBtf+>$ko0a&n6UuRZe^lEAvg^7jO(%r(Z} z(Q!PHN$SjCm(ZkDN@!#&Fb}b3IDs>)V%pMEN4ng8&pQ>7ooLwhVl>POLc$ePl5q`x z|MdikKA1SFc`ot=E8_k@qi`W~+x$GS6U#(^k1_bzg&9YUefl5}wp&1FDxei)oxA5L zS=!W@9%VD3%RD;qfbAojPQz_1WaXIp63M=5Eo|m^% zCEM1!F{>OH4X}s{og?>XIA)jVTl=wMDw|(k-hHT`ddW2$;p#ZC@EMZj<>*}zb_o77 zI%t+OE~$6aw>KTbn7&N z{TE{2w6M_N#sOS5c0j_Fo{~M`vF5s-!T|OgU?$U;2^zzU2<62So)qFUt^rSI>5qFW zdAHu&Vn!L<;P_!bUOvuccr{&Vv>gXtD+h8YD(6CW_}Cx@FE= zp8~@Pd-`Wi4wNkR7fZCWmeau+s^8TcA1Jz_H=l6)?0R|N!DyEzK{<^``E)*H?{NZ8 zag2G=+->mou#C##SB5&q6Rb828f2wenOxHt(bfSi@pY7wcR_Nsa-M60?emc;Kw2F8 zNHqrr(&1F|1douhPF&BEDa!e4WSjv|v;O~f;S_OEz=#?*k9av~AhJ;dwBx}j2gaAl ze%g!AL`1c6_wG;FIDNS|?@>KQTSn6Y;dX%CwG@SJ%$SuOKZX1nwd7g(tzOg z54Y0MpLU06ex3<-ob>;!GG>WTUnps_5D|qh;`xp z=j-O^;g8LpF`v}8MrDMwzVt&v_x2m>la}E{h%QLA10YZ=M5??m#&trFp1z`Xl*ZAs z1xV|=o0MOtkc8Pr8GstQ!ZZ&oR7xYkDZG>;3|_E_>5?h7b1xtA~bO8jSXApG-Uit0&e2EhI>e=Sjo(g)>PF znz$Rm@N?Niwz)o#BZjw+=?-c%Mh5l;2mfA-ZX$bji0X498jJkjpcu6={;%HV=D6;JU5yp5KN7`_j8IXbrEL@+$vJB65%C;%rvjF z1QL32#D`Dw1ukxP1qp3tZW-3kowpb+EbKD+FdOuju-H#9P8713w?1Fg^w5hyO!xfM zi92`H2~i}T#ln08LB~OpZ&c?=Z|TO4#ejfJal9x zA1THBiocUF|2XqEs)_%_hKxqA-ZVX&77R2wA8AM}dcO?+m|hCljqce>f`Wm5`W(Pi zc7xzSV}psIE2<6=`FseO8jhs0lod*Yu<_WWtA{8XJ*vtwa)l!Nt+D@I2o~|1(rB)@ zo`6eC2rS&n%wt(SHmzD%>a(gd+V8v%r$7@6WiXyo=02S+$zO^gdQ+WqbS}#cU!xbP z+hGEF!Y3y9k`eoDZWl_zv@j=Si@TL)%=(qg@W=W)kuEXE?%a)EovSkOsww)cqEBix zHu>`SB$)vyVj2W7CLO+I16^Y>i`t0zy#ap1%%2I{^B?aQz2LcKFQ7>Ln7TsIP7ego z`U1kole5fd9&!2IH!Y8{6+TYlB7q*!Q9|rwVnHEONw~7Vr=I6%^7+9296sRoC8X&x zh<2Qp$5_?{!-~A2Fp3G(N$MliDTvIswIBL~U-T29E<8}-B)StWb@BU|nd%6OXJ8GC z9ErHrhrv8;!5`1HX=HC`@%aBm@K1Ez8J$$L=eGYsa6UWLl+4WM680K5Lcae)2v9K1L&jXpK0!<- zApTU(#4DHLB8;^0HgVjNR7&O-EkDMo!D_^U*?Eag#r1jq|?BE(%_!D4S)g!1A&L$03i%-#Pe=pijekDG4@L;YNR|;fB{=HsY!7v#zBF&*I z<5e@B~I!cUJLPK!|I&krMNAaot`|jNn>1uyRd<0Zx8%_231eg%{GLf)b z^^cv)(J&T^F$x(sCC$O{ex9fzPfXVIe^I|-PK)9@txN6fY3tF?$@k`b?1< zIGF95inRogy%l!9&3Z+f^gc-5W;gg*`A)Nk$e0Vm>Nfn<%)Vt_V`}~9iVTCKr$%Q; zi%&tU;8bSNpg_u{alUt(=n)YAAfwh0V{M?rLV&Odd*<92(zq{3T^mG9=hLNna`B*` z1t{+_RZ=nZ&Zs3VVGp-OG(_C>gr8i;_|t*cdZhc+ZGaw#<@^EUoa6kX6_ii z?V*>q7f_ph=-r4<(7Ej=*TBP&UymPEPX@_xaJ>Bb+#^!-Cd_#8D=i(o_~Dk4BpR96 zd3a6c@C{z&K4LW=8AW^x1z;hfn&jO|!2{aw31q4j&{YTBeEQ6W|z&G-C7l9w(m zs&{*AW~p^d0FSKxjB$xJbBWebt2CjGz3%g|tj~%@P1+Q+cm)_UGXM)ZYy@-lC|E1> z$dobdF#^d5FOR!Ec7+QV#nyEUpAiyDsFt7L^U2gRs}-tPdL|LVg_=?J(c3|(X>M5R zdx-&afa710mjaz&b|%ZRjd+gYOSi3G4q^3B^kw(XF*2G-4^nSXoo0QQ%D7x)+DEPc z-j*-BJ$b!+Zs>gP5<4#eNBVqB`v(_tJ$Xq?Y)bOtN|A8ez;gp%oZ;VnW_i+L{E1X# zke3Q(fBOj?{Q6Jw9tph%dd&e@9@#G74B1tsDN*Qr3S$QX$=)2bi5Ew0Cb^<0LM}dR zzN5WN2zE6IqWK*y4Z-&9Vr^pFJ!S&$V}!g$;}G9MecZIO^zqtKACL3G0xjX3!1thO z=t|Ew@5`VzZ_v|5s;p_gjdna9$K3A(d+O1EwIUe ze>zc#1WAR?1$tw4Ra!NeF6IKM<^O~`99bsZMbg7nrl9E#D0Nl+If|+Y83H_X1D=MW z`wV1JQeU@aZSbpno5L=JB*?}iM{Ym9Pt6}{-^uF!$PaI5`*^PO@O%m_ftU#^jUKvE zF>_iojnhwasP!O<{7J=1@W9~y5GA}r=eD)a5Czi-xZ*VBS?_3@*LGRo$~D`XsV?Qi7y@T^lmKK#ChUbDj>) zRF?9YVwTptEaAxc4OF6@;09QX1Xv8%#p|tBPg8ticzx6<8RS)c&_^bxCvr69kId)T zH^FGtmYa(E?gW-)n>4{}sj>>~!!Gk+x$-e!x<7m{LsJ`9Er0oQ+f9^LFqyBVXHMPw zH7jAus$MKTpgBsMRcnfmry0U8iSazdi=_?)<&Umo&3>NyW-cgDDSxCfT3=gOgCsv7ZaY;c;2~g#uz6+g2cZWhezQ;L z3z&$Vw_%(m^JRbzJ^ctNHQA?UrVAvigW@3OVpJ+gcsSKXc`Iavi zmOH5@@9yec-@4Rmc~U0-flod2?T&F(iY$+x8T zk^JfltBdyD&jp6R)HDl?e!x^Fi}#48>ZCu*tvWhX+U6 zJ70a0$`wMR!*$DReEhw$-@V2!2L?dx5oaGcM*Ojd5+<=!qH>L35$kpv1Gn1 zgK>E5l-O6hBr90E?(sPFv~a9|{h;=L?!{;l^n@C|%8P02DRI7VelMV-sV`;O<;Li)YeG=Y)@0kLY<2s^BGm`JB8^T)l5|mGD%{3>OfDW8)nG3tHP(N zaDVHy+JB~y^&qOAlQ=HKatFe6#Mwf zrQM|SKhm_EYlbf9#Ej?OaIBPmlgY8RDqRU$5nX-T#`8s- ze)lW;?_E52qx-ml$isM(gu6#Wg53PD{Ps>-^(17da)OiS8t^km54ikXH-`lgJZnGq z3xge`tY(gv7dBrwmUEmEtxAmDT4ZP5N*+R3H8ccXM(k8oEqk(Jz-dLn6GJ z`qbGqs^?pI*Dzp3SJUatBPY?UZW(c*JAFuXgZib#7pVx?$Y`+BE(S(J>iju%X5n+^ zjxd;?MvnfHc2CY5b6EKU9sb;8*}+{c)N_>|01O*a{&AJXwV|+0apph_riz+8P6FTy z@WmC7JsSXEVu2jIB={v_Ga`18)={{m@)G;KfmvTxU9CbtZ)OL#FmRU5*9TkQ9K!a$G;l^qJ#z8) z(?{t%J3(39p@&&E%E+g2jTL1~*zew%gy=ptS23I$FKeS%tyHo*!$ph3mO>63N_5<^|ot)nh>fZQ+x0PN@eKsEnUd)E1tN|@w1 zEJ61*9MMqM+!*}#@)j1h-}IQyyh!xsC-?3}2K=MXo9IDehu`O5kfi_(fR{5(88!jD zY{&%MCpN!3L{U0+f<>wrbEB)WLo@m!|99}qq?{L8ZA-R%A$l>!h3^rRU5DBP7>|4R zv74>6nnOYDiW{}5nSUCz-g|L6^7_o|KE=leStd(STvKOttkmJUAZIRv5@VZUVNQ5C9y zauV%vyYs!bWyzEH1p#yG9zf1SpE%HzOEwk7cA~hn-H*x_-s{5Z9$y07$HAAhY29&V zMOW+dB`X7+w!gwY=OzT$)-ST3{4X6m22^rSaJ;$Z|KbD3=~vDO_g&y&tZ4^c$`U1x za`7VAU1uoQKbBgVRM7HuNFXh{Q6< z0!Gc!k#C-d5Roog&D)Z{BH#b&EERFIaQ%i<&q}muDCS|H2v^+zy#FceUDVtaE7L{w zc+fTfCWO1SnY?w~_69u4+_MTibVc#GGq1(?HMOLdfpM4kK5xV&?N$JuA0R2>G7)`Z z9RpB&>(@_9TrSG7v`e(FD2%nkv?bXCv)*1$VQNjl{zd|aFWU-mk2Ic#QD_%IztD8{ zS0wFD`0EQr#Jf%pZ~BC+MdU@~GL(E?)3?dI{E?IvqN+BVawQ%>w7#^OFRe&?a}hB8 z)yJ)_cdUKqDDc=`+*7+phy}k+moum;=}(LvawmjEzK3Yg-9?i+$Fwf zSCmNcfAtC+UV1xJlJ^Twp4-Y@CDddEaQH*UlMficCGIIf0c&wAYx}PmTpBx+I7&EM zh9TSnV0gvp-aQ&Q$xy;d!9T#qK*ky6E)}Pq)^y`JXW_Kr;~M01SK6=D&&Zk%f_}#* zv`(=6oK` zap^~tXC0$TwTnV~0aW`Hd(1puaQH(Wo&4BbcUc|GHMPr zfHgET`G5vk{Btd}3zGYLBnH7WYp0MsT!b(v860u`afiqKK1<`>#`?+?ZX43x=*1 zfZ?Z4(kK|O#0ambsm}j8VnX5*Xy2Bl4!iiFu(AswGn|fTW83D!2>P|gQ&W`1_{ggv zBk7pfEvTpy42g`h%3Y_oPj;TGbY_=^5Ta8fv!;vU&bXGf9kndwmQR`NRmLk9| zKWOkRdHYP|u*kPNPMu4v9@W*4FFcpJP@+me!mP7({+DP?I*IC%Bv*c*K-RX1xrmy*Z4iy={?W3#)WmWP z#pf6JV)nDaeU$MRdY)^rhK_cZhr6StSM$4qW2abn(<=7&rbSV0K(#h zppZy`?;R>A9uJ|l5=x1JExcnQjbgWW{>9=$XwTH^WtF(Y$#>)X+$CtW1`YfSGIjm1 zXy^<+(_}?aQkP#8zQ)Z_b`2Wo51+mu-bfCsJ#Y=cKL+k`uM&+4n2afj{Zz;%vHD{sa z&p+%Gn%TXDMZZfr#chV=oT>z?&G>)wmdaT?tLEVJ&BOo74g4(-+=73e4u5VMm=;hM zmDv+UZ-zKse&4_3S=srLtT1H`9fE>TRgg>`&|t5G^a+q+NiMj6Fcm!bD0+pPcKNt0 ziOga);1v~}yVk6lAboZE=o5SUh$F+c-NPu_lChI7RG3_#HnYoj1Vbk;vI4~z1Va(X z6*Zyhx~sInSSb*=#Y78pAmM_6wF=Bx6!xbTAJ~Kui$v7D>Kc03abu{Cr^}P|^8M$@ zOGv3lj>rUo7P2XxZZ74zM-?F=FUel>mPAYOjTw-s2&nhe>kAF>$HMF5qD`_Z)?FzI zvWs%}B#zs0X@xoQ>tT0zD8HeIr|G2!dDso^XCHS8S!+FAZ~wn~czqNpMe7(#WpTNe zF5n_+jE)9D%(8w89lQ%m`7-zHxWVhfws(PR_7P{n-+urC z=wAm*Q|4jSq%F=cx!pqpv>_zE6_D4`VD5%)6uCm90YHp)m?=u*^)?2nP{N1Ki#`HV zl#kY4Nqp>>ANd1McrU(xyT0{{IaQQ;_wl$b&i)_hp$a}<( zfZbeg!~4cgx8ROZ2|K0+roARvuTsvjP04zA5VUaPl z(`ag4^GPGfcg`wX^}_cyn=jN;Ge^%|>EG`n*O@R&zx9MZE89$GHL`aOonzQd7X%QO zJ-e$RVC8F;IvhZUoyb)7=JS7(}NoU1uh@xI>9VM&R1SKI=|z<&57gxI`8<| z0H9pWeTSgAMnll1z#*ur&k&Xc)!Mz}=_r`3R9L-Kd>Y`uFAcLZcFa9J;5$jLu_6=g zT^4E5uGBDgcacgb7yc9L*yDdAGuFfQQVc}0FAP6;8nN4Xhss(e*#aIE|1angRr>{0 z*g%8lWBgsh&=4YQv_yV@2)Z^hoI^(pHot<}d=I7;pVgnkI-{XoYuS&bU?oq_wH5n& zPVxPzIDm)*$VL6i&q{)PeRd`iV&VkbJtc_=0x-He2G=H(p;UP1jy2wHebQDVc*MnaDUDz_eW?-_46@{E}!VB=bsfS(IYId4N>@v*CCK=!nMu6G@ zxF7+7V9AHtG~iSj&r3k*PYYqss*-v2hQ$`~SwN$!@i`+l_^FOb~wYKLtG~+~qK-YLs zt?xD#r@8(RU6oaa>0Or1k>uMyBe3->|5Ng^tM&VPD$g+0w`S-|(1CRb-8C%+Q$s!Fg%!SP#5C&2L^tTzBH0Uq-JOe1&x|0y`{Y4@nPP8lx=A|Fc7px z2gACj`QGv{DsqIb%bUrSBJ>}=bsF*yc5y*b{Dmbdwajx$Q+TeAW=aW2o^~vnCwjgd z3Cd5Kq}&03$$7ItMBC0Ip78T6Cy)MwXQqgUX(%XwV7S)Vq%1c>jV1l zI)kQQhFXCbN&zj&|DUHUcK0wBsZKVYF)Vp}$<2iEqNkEpE#heY3?I?qS2PTtvaosZ zYw`I<$dUq~i33-od@?LO7zQ97cmp}Nt{gqHkM-$hcPUlDO zcmw+2M`>_thizBQ__qA!#N*z}2CwXXY=vz$IUlYbpCX+_yEBkZh3%Qmjh9NJjpt}R zzq`_w%-q8J$^W1luYByusb1ISKoo5@vd|K8e!2jt=;){dlC=G{Le>w(1a#)q;<_oF z!DQ#ICI}7c7eEL|qw?*6g*C%Y7hXT4(S0oWDof&MB3|Xf*y`ewjwdjTdNKYi31`A2 z0Fu)iV>|;1kps)oz;Dmas)$WWpr2`T?f;EUdZO0H++Nm5YhHLoYr6+weWB=}0qVI$ z`*(mQph|dJc*z1358?;Q-2mB__STK9x}c#?#|5;+t>Y&j4Y4X_U@Pu?lBUfHZM;nC z2NOO9l5p4a`4|P#*$MVlYmLPo7BUV?RfsbSRJJRcx`b2Xlca5e~mH9^A)KP*pAQMBA395GK} za?G}j0uigwUGdurZfVtw>|+u-dbj22Pt)FArX#$-vFRqQBJ<(M=xL<;yG2>g&MDf( zgi$?v8Uk-5q=zbdv3^mOH>YWj=_oTSE-WJma$*6|*%=x!X9*oRr_su5(|h3zClaYsrUDbT^6S@pp3g-e=X6KZFe>_ z`owi;;2%IGIBvZ2MX(&;IC=aPGbwmQp@Tn!U8;zmv}bj-yV7r2bae z&hI6-cC29YT*L-0XU#9-e8{U6A8vMGvS5}mu;F6h$nV)KDXA)`9qtYp%rCVMY_5V; zZYU@ASAUTCWi2`O6etsd9-R7I6uo+H#cw?X3@#}PpeceoONw+#o6V0!>x63URlc;; zk6FoQiwdi>BTw4gk`MUUI=fKTdujBS3mU0@a`L-ixjsUk*4zX3|2w<8BL4KnorM}O zyy^=uAN|`H#{xVJ%uZl2rjT2px5yivzi#(gj6pVNn&5xtyZiq9cKnhgP^mRgc6ri~ zLg7v;hLj>;zfxd=-+v?34YL=`i)^$%ESgu?G_X*h4eftFeyW>_s7ePkSHcmneu^d# z&A2X>yjOF@w3(E0B%(zxRGfqd$NtDfuSnW60fJz3k>D;NOG$lAWrm~OB zE|*wbN-4LlerKVVx(AXR(}k}bFrmp{Fp?iL5?kKA>y0*S-^>8C#|aPzD? z1IyC50IV!{M8h^DNw~A_R9PtvB1~tnrcKAPTc{>>A>XoWGacdvw{V;LMe6K3+P_(tw^L{+Z3TqR>)D)?ORus3rXPhkZ#g z@E{WnJc$NAB>YlV^eM=THj}f^<_3LPHS()MsrHKoZ`Su5do4IZ${vF9xoQ>56n=b( zue2x{vcg7F(s==N?LCKv0I$~2wmCqL;8P6pJ8>QBDKJKPNB3`jGg#YZNJ0wPkxvG* zJcZ3xzsoSdbXs*^d$$n{vTvyKlN4#m-*0C6_MuI6o>lDLz}5C|jhi$rP4$v3Ud^Q{ zRaH3SIS)eb?(SLpV)qQ15(wZb>wv}?U1FOSEU-UJLGgf-6dK=`qjr?x0uR4{yJ~1k z)?=b!QiEoq*IzLZWO>QB_ap8u^spBWGr88PB}>ux=CX} zz&@2wG5g|bfY$z{xL(7URmH}TrFLwb@*JQoc){RHbHqTh19dr{mu__kOtI`|AgXJ8|<=^SA5fxvP}WMyh$mDpZN3 z>wqeJc=z=j_5M;a?55Dze(`;K`u*x><>#gIIb2~vp^mvW4Q$Q0Sk#k$Zo)algpV=4 zDkM^DjZ`;kp5!yZl9P&YTtpU737hynT?$-ibpQiojGfAtrnD{7r$NIO44bVeyclmUGzusfbfHwh7<7LUJfIY!vt9@!7V%F*HLqn^UfBB^h* z)57eTtlLbfooHE%sk^;U#8`Ywpokj%(cnI^}^@sI$i7;QP>gPNBJQm5=Q|I z{YN6TcP}$LW$r!E2SJn=!wt zjJD2O3mMt=LRr=vbnxJTBJxJ5Hdt;BB-hu>$$jQfN~7V4JY(5>sJ^_yEwc!$lkMBz z4vvc7VaO-n<1ks8XjnxT*pa?_?A63f#1*&G&-fTzf+80%7Q36h%D%ATdfRlB9e7F# zxoFguffLBvOy*&@(EAeVs}5pgR`Kjtyh|4ceQBqy-T0 zD{J6W#8KbM8m^X6pIn}oxl0sG8*`@DmQA5P=vWIrvuasM7U?mqFEVyciGzjp!nd1cF&9jhwTSo@GR{fp$zXf4#)qnpoCC?Dh-SL74Ei$CoI!rL zb){9}e)_j?voP<$k!>|CUZMKCUEEu@@Tk%uyOq8TA0<85I(0E4`-YAJaQH>ZTq{ZL zt%VA@G7-kI;Ef%dIY+TMe}(^Q7`LnY>%qpi`=6KOaFv5kal|+_f=bym)P@el*HL-- zJn_^bMCrlY;kAdaV`aJfy2q|y88@77Pkw3GJ1JH``c&&c!0Z9UP^$Dsx~|1V4V6z` z@_cTX_eg|-1;Ov@ZYduhYY!xqeL0$ABuqvr{F4OL9Dq7Nzi&#v`%{wzxfNC*3aJ^{ z32umZYV{x&1it+J&m_!8%@oQs^qYr+2Hq(3S4QYId-|Vb6EhHN)pJG3KbfviK_xwb zx;Z8m#v3R&3|w}kG*wh8hkM@}Pfu{o=ctCA+$pvNR6cE+`FlNUg`_wJ{9TDc{D)}(KLk6qM!^Ju!eB2*oQ&aPaAJYN zL`jsDKrjpRP+mi1!}@(3hHEo7Md8(#{#R{tT5Z;b1!u1e zd1HDvX`=gA?T#!zB+kxFzF?6Z*9Tn-$PSj65SQj6Jrp6;3xWGFu771|;3v|QIs8AxuA4$f0q+A13x*FBvCQB{MdsIo6~H5+KIk2hOnIX%JUJeeL~tO=qC=x|uS zSN1?Z3_6w1f?=8F^Nc2UblSmeZZJp}s(R|VqzqB6ut3;4l|0+1_5C1%5)^iCiqFUs zqTLuXycy1h7ud1bh)G{nTGH^tvZ|eahjsLm>qE0Il`>W-r4Lc;PTLELRnE^=y18)Mg zkUIQ!);*;EM&wZ0Q(pKUXL=jz&ag{K#Y-K+n;p9f0ze>p#(oVG9GZZCsdPyeMa*UoL?PTgnM`4>38ron`&Pn$SK7a!%EaKKRfR`T<6 zDJnHb?@E4-e!ArH8)3Wjii5xpv<Mef!qc?@NM50l;kuwJ@cixsEE5_W5U&Kvu`g9aMox^nQfU8>uS_vPH zUV}LC#gq)`V5azVj1Uh7E)^RH>Iv3Qdi1S1^|(p3V2)ao_b&3^=R9&j(ldhPWWo-4 z`ZvdheumtO!-7u?*y_w9<3G}hd=U9EQ*8%DRA5gVFQ+fJ9Cy(VCIK-lg^EX(E`&G zIFPUIt^^Y$_J1Irdb#M%NNT@a^-&)EXb1E6u${B}h5g*eZ#yfq<>EmJH{|M5$GE;! zr?p+u7-^UYI$)3;8ll!NVczCAPQH=u^yq+(KO!6_&OCt(4z<{7d-nnXqF#n04<1@Ez-t{lN zs6i}_b@I1XCmNcG8b!gT!m)I+B`qHZoqLMS*t(&>qHMMZa8qkOoMLB9Zjy=PIfmrR zV9ci}ZZ;{f8&xs{4hR%sQRxAcDq$R(>yFc*!^cUAKJcobS~JdUN)|*A^fFufc*QzG z33>LK+5FGIV;slR?Hlc!y*a4*j?c=QT%57PFLJ)METL5UQIj+qFxKZhAX1AuL6vq9wsht;P^kwH%c?yq_)^JM5N z(}*?C_zT|GaW{cnSvUbD>C!2N^F_@PxZ16*KmEa}Gev8VXjpJ4q5u6Z0y>X@MZ3#& zH1@xC{40zu;cT@tR`L@#f=RPHxGUdsTwF&IpL_yS{hrSz23>lr-fGkg83Du>hQfk? zim~lw=VXk52^X`iC^vMv2%`9&@hXmeZEjZGUDjWtPyH7CgI-G%6#UF8@9*sIfbe0NJM%&KYV8G za(@O9Tzr~#pW}ylIF?N|Q8F(iD}7ndda2**3%d4qmthSN zsXVED2Rf0^f1J(aw<*&vXo->L%j5(=ngz_w33SJuZ;1H1!aLqf@;fb|xP^p6vRo#} zfe5H`{P@2gcuU=5>D`f$fB&ZniwXvY1A=#&t{}VPZ9Aci59OUxyZ~`?^?$?-z$)0R z6Y<^FPRmdLbmrI~XKV}W`)Tk-f39zR#DL271gaaK6h&X=y0f8qZs9ho?%I*)b8v7Y zZv97PEQ0d&sw^LQ@qk8vPnIiIM_g}Ud-V|^D%tJbLC>CA& zKv((a4+hHRpzgW8gyHRD)d7cylm7TabU#x?oR>3`U|onOQDqvNRY`_7!8+o?2%Xw6 z(LYROvjn%;73{IlZq13f3N#&+C}@JXt~0K6lYGg)Z+ApoLrj zv#OCGSL{xJ1fI80YyKX)j_{2qceGzU;B>6P(v`W2a4Af!z5C6mXbmOGpa&(-<`*kI z?}~cIqARZl6FK*Q+r>xa`Q!%5RL7|OkGM$iO2xw7MD)Qo=4@YuS2xXX?eyui=h^1L z+RmQF^CaxPk7{gCx+X<5+^7c@ zYFIFC=WzHK$wGXL`9D0;37tdc<62xC?)g!;;_fK!M};4M`YoD}|CsYV*LiD}+?Fd> zVt%Vh;}}A1!{d8~RxX~JrRVrbh`VxhQ){2mPbIO#_h_owiy@B(^& zl;Wa{d7WD?&js$;g{#+oHitX~=`>ughh;t>jX&lQ*Ju}}-I4PBt!zkmcRh3%9M{+^ zvCVDQq?%~&)XGg-R2UQtvB>J9)sIdNIrF?gO6Kcr@gL^@a^@9p330ih$RXcu*`mv> zv}dr*Jj8WPT7*{-yDzT2A2LE#Gm~V~`5s;T)b_?ERmDOC zlmQ|Pc3E~Q`z?Pkx5H%cF3<)RGL-AVK2_DKb2t3o5;$U^j75x)$Zr z!V@t%j5(II=Pg%_U!UC*K-$q9(i3e_tObFdM?&&3oicz&T$lRMIrFj5aW)n#V87<`8K-X6BqF!l;Z}2BSV? zuZt1IoSxc$9Oe4AiT*73CIQa`ynnTCv$|$}M*_%g+)$Omtu@3nFu%X4+05yL`7`Yr z{mqSQVt`cF++!eqN8dYI`Ig7(n6OK%@?Q;`QV*jYBbJ{tfJgv|94kNZi&@U&L&0oa zhC88x&8iBK-4pyvj*-gM%iHkS#bEx2>r=Bea8J(oce-`!? zb>1`#%h^=#RYk3=@-HT%o=nlJBa(m-6Y%JNLGX^KP1uWm#&RrI^K+Y~VUFzXo@W;+ z(5TH|u8}u`e?SkaBm6&VSQj4(+D=CVh&(*5v;L^~svAT*<7$@2?G~ip=7qd?dnG*g zhWcIiR%lH0cBmsrPB}Gz&hgpPFj|(;qyHI5@~!o$nP6GPUbtP@g@(#3cZK40+*6n= z$lgX1&DXo_Sw(jOYl~?~k-RMj?I2t!Sj|fY^)(%IEqR@#sxv1Iz_HDcQUK*)VcU=> zm`Vz)FJZK&MCHu~5rn~?pXJ)SYGWhE_YA0ia{n3}V64P#7K%Ddo}O+lyc>}DX>gGv zlheTd*Pdw7@vHX=W5siK>Yt8WJPb?M+&l#-?$oWK6wKf2|gybkqZ1aVt| zt|c%Y6lGQVvyAbJ)%{PBR}M`5cTmO7JwdMVdTusVu=G_Ze1;;-{9zf#yN>{7B(B=% z&0-6%y_#RNjk{m^of*nG=1yFBG8U$Fg8{kgG*QsA>PhIA#W>smI@`oi)v5@H6ty_F z`E^+O>^<#QLyUN+l_9KH_rjr)R#clqe1U*(jG7=L;fCTGmro65;kMYWNx^lYT7{vr z@BPnR3bdMR`xVt15rlmI_w3Peo2R_kqVBc^6`)2NjB|rTR6EfOps2>t(J}Ir9WJ=m!18354u|$yLlmlP1 zK%vk>rby4*6-FZ=kkEP-PB?+OBURd)rruc|`<%-zGX(zNrtjMl;91<1|F6C8@M`LL z;zg=73q>g+Hb4mQ#ULQ4C?dTIhR{L}NbeL}N>_D?ehH_QN2F>(Dpl?0)jd0H)6@mlsSAd75n)a~XaI9a^I)Nm{vVmioe zB}-){aDl4P*it_%Qj$L5-lqy&}YF9E@R7Jop*ahhf3$;I9m%9UfN)Z2`Ox~@;n>4 zIU;(x_)uJ4x2A7C;I7LlgS1;`O3vLmrPGAW(Sh;#{g)5G8o5f+{>5vQxrf*obv6pZ zOE5+^OlRBrL9opf6b*sN;EK(`x_Je6qaMjy>c?l1@C1PX;Jtj{R6s9f5UEE*>iOkA z_TGw11VlukO=BSRpEyz2J}Dr-5(>S#u^qmaDttk8KIpeEUvk7IaY{v#P6rRVELdZc{Sq^w<@7M-npafjUx8~ShKG$Z}QyW zK)q2Y%}qL|_}erKiy4`o6LtP7P=6gtX26Qc?5fO0j19p)b|OIa!9fp&-+Yptl6#x( zc1Wm-^Jh=Z55hS+YApN>t3^lBj$eaI(Pk~|{&gC?8%MmU{B7ITTnP0d>%TytI55q5)&9r{+oKp3A4ne`L-<#1on*V7r-1I|1a*#f#Y!;&b z;v4!jHE4JiDT~Nw#Mq=ZM&I^^@Xd8v-Ua)rT#xCFfyK#^tI-<`IxX z%09)uvTvX6^44q8&K~F1PQbTFIqFJiVnQEnB4~;(QHz&8UmMoy*^>Q{FzjUhq_!Lj z`ku3Wi8p$9hF~dSm3|7`);W^#;JS@k^aVm2&6Q0?GJh#6%t5DzodoHH676NSTdgfJ zL3bPU>1LHGJR^gy`9I8vuHn5VNJ4x%tUkYm2^yRxa`N_UUx3g`qcZ#+K!gCJDO4yV zj-$>JzxsI)UUY*Lz59!)I9jJ{Wj z^;(-D-tj1%1Mi;i_mn)}&7a!Z?X_F`SYMFY(ADoau(Z=xpzZz^^%nVd9P&vIpQ=+=IbD;6l#Fd<4>=V;FIC{UXx2>ri=zu;8QCylOzG;-} z&1j_7@Oe`E28)Jmd&63-Ne-h6{g5J7rDf$-hdLkXSX8MgKV37M%dypqSM>_Q#PfiaWm*#2Fe8FK2j23FI`Qq(b1mPoLC|!Js3o zE?n;+{o=J`kxX8C8LkP5JD0jx!@uLPeXRx9$2gWqNv+6H3=P?NJ#ufLw~MC$2NZL@ zv2@YzEfW*wm%BgkKP=+5<&2~3!BFZd;W0t1kj6v$%r_w{n}%7jEj4=n8MU@W3IY7g zzGd=qX%V_hxfK%8tq;vvS63c{MAcx?dBYOPllsuz_3hW+RFJ>yggQrnve-Au8+S9a z8|B^rf>OD4&rsOswA~7hcK+Kn);SvYEqUo}NeAx$1qk7WuXlo8ocf!=-?3=ZG~gwbIbWDj7QQcfBwXD+07s_G=I9Ft zJx1IG>af#ZH0(Leg!ytJ7?n^dL2OJ1F2BxJE69}$6uWl4 z?gM&zc;0Y{`9XaAcp!;+Jn;v#?@T762+Z(804}Esv{!)BW7Renh;59&g{Y9ZC5Rg@ z&s}vucLzb?^LyAfn=P0UI}}{WV*B$RVvcE~sq7ET;ABxa*^o3X-W*6?! zV=&9#gmI>kYk6+n^+vjG^b?JniqI^K`cSr3B4!b^O{tC*?$Ict{Q(7piC3`50Qf}w z<Nh68DHN6OsoBTofaPl{Jw2MG6J9JH~nzBHU&GmfsICUdA2$5u3|M;4*^ z!t|laIF@nO7No*+v2bhpJ*-t3T(_+s`H|51Zo*f<#5AH1SD@Cg$G&@LZoSKNEE^-{ zmcsM7=EdVG>X-8KuOeog7wi8!Fgen^$DmF32FANo_Mtoo+ZZo~D`)eyn-MMp7f^TE z3=+eR7avi4509O`#~Sz5)0?0t;Mdt(Sosxt&0I>fD^CIWUTSkGzVCy z@;u+F&u+vs7Xm%fs20}Pb2cpzXS@#YD8?DWo-Yj2=bG|4y@w93^fHSwuB)FnB)%-X zbc@}vf*!|WAh3|wv>awa59g@pTEMdnfw>Zj(1e>%dQS|D+f>(7iHui&yPDXf`U4ui zVh^75f4eDL|FAutWBO$y(6-?n$2!SBH8i`?IFg+f;6BfV=@tCXt}CTBQ0zW`pJu>W zFFI=>oSc;)&S3D;RS?=*>N$L~GaImkfX@Y3abBRkjt&1`i_Lo&<;%Vjs(}B#sa)OM2&v(3b$?emn=k6k=_o zM`&!?`L0~l3+nWY`{V9?YzkmTj93^on&xEs9yj%1*+fhj0}_EL+{)kSVe{38HjcJ6 z?R-Watcwt{2~5lw@!jp-`-JLG;w4L?5;sL~Z=ylZbA0S!(0CaZ!R~(KLS&PuCoet2 z*Jw~y6KlA1C%ShNvOtu!&pY+ZY3b$1?{tdgoe6S=i$vwWBrIKT*a@! z@qx>NMFs3;W=aIPJ0@lkv;$MZcGh-&)LmtbW%eYJ^QUQtDuD1^+E%~}z#_-e8F3&4 z0$MDdv+~l<$a)J5d&55w@RR9+GiKX|i4jH`bpll)4p4y12Kmc|zfm}c;;h# zrdhF+3_{@3s))g~$PL`kK+_d&j|LTS{|3}OhQI3dV8U1`Jojce5me$;572gF98d9m z@0X^dgGkk(8;cPtTu!d{FieEDVb4T*Bx5k~0wp#&X7@!KR@LW`3K~IBO7s>ihIb5n z(;wcuFiWK86~vV}XA;yC#lrF9=wN8*o8ATr;gccaux`mD8fpWmRP83tC7+S09sT5F z4Otjl)nNjs7M$*xtvE044E^Zqz5!`WCdj$e64W{0LD48h>Mlz)3!-uy6!1jw_c_}y zoyWn|WBZ8;_CZiEmIWY{tO=V_5_Wtm?TxHk>nDayiwq|=ZGIjD-zh8~0}Ljce~=E! zJ_~g22)%L9Fe2;+)cHiq52=>rKGgp9tFOx6qcJCQ3w|uHX$N`ML7m%hX8?w&jq02i z3;~!+JqJBsh}~8l0$1OcHld%8sD-ax2G9piU&WG`JOaL1u_`h+)K9!pfVJ&Fo7sgD z7UAopTXP7N#O!ju0|vO{4h7WB_*^`Ry=G-1fo0PsKa9E4!IVbGNI zTCCN5Z_aq=55TL0b$}?oit9}I%Ye$`jm-`iyItvKi7L0Vni-F~%3SD`D@}wxI55)j zq!?u#Vfw=7oEA>EkKB3ok{|~LB7vv010Ra|BNGH^4YX7(>hyWv;o-Wr$5vdsghdxy z!JtnHv7M~iFivLR&+t8O&K>}NXCdi@SPsM-%R7Z#3Twd7-qyQgXLBK{QSQo}pshcbwhQD)jTXG(dmNSmHbfgeoDYQO z;}Xw`KHle+X0c64!}Cahuz~b4ENz=Wy1eG`gTzx5hS{)Mj&;DzG+v8?hA3}*0Fa+S z2x#y|)!vN5e1g_Ddi7`gNv&P%XUjguMfJp;rFc?<67`|AK*%+E^(J7;$S3XsBDl`4=G+|P5{4EnkxhQuuqYo`jkOSV zsGk$$$nSN;EW3KBu4;zN**G4G)j31HuyvAiDzAGOFp^N4ax>A$!ry*1wTrU|S2Fjs zy?nO~r1#0htvQVAS>>@iH{t6d&BUhD>ke?@)v_GDrxp-~*^3qb6|ja27GPN}R&)(X za21nL51S*KOdWaY#k^qxt&vUHeV(na(ZPdvH?2S3$oP=s)5nMa+J;y>X-88lAX@uE zPn^(Fn3nbVoL8AkbvmQ(hux;-?G%57;8W!oYmFBi?x`hz_E>Vv@>n7#`;<_uui_l8 zwSzRM(V6UqU?8-dLjv(I!^Ph~SXKmLU+;WX4L0tVFL_4*<1Kq%5TYZh`zo2h_N~G9 zNQ_ZvvtI$TIUDZlUHuQBnWn;>l}+R|D?lR_=iAY>qNaTNtli-BYk*2DB>hj#I^D~h zbGq{z^Qry-2Ee+i?e{7twyq~3qRGY~qVJ4-okS|IV(;*{n7Rji>LwBuiE|5@27}*A zs-#qG3lr<^UowSsEA9OLkb=SJNulVb23^c^LM)Z)BeM*KGvjn}<9X5x8o zga>+5+q{%4(M}Q-cWha-Gs@KvOnRfcYuM+lHZ#qfpVW$et#Z-#ooWAcS)$osxttNF zZs*W{V58PNTmGM?Q70pw&OI3nXFpUUzcDB3k)G8Rzcm z{c((7F^BYk2M=eIVs~Rh+?E`VlpGF9-=?z)MeQ}(Put&D9L31Ijw)_T`25{1?9Mhn z6vrJIkAj=;-IG-|7+h=-taxN3m5}?P|3yndi5_oldo;(Gc(hycJEqSTAjrd z9hC1~eIljcnR1wcd7p6*h}-bZ>)GMY8~n`&Uhqgr3erHhN96bbOX0PuSx}U1a~Oe? zTXRZ?5%}cuDZv-}!Ce8(L`lxhpNv?1C7~a`?f<2|vQUpa{0%eiyM!cqJJ+Ed zM+6r}x;B^d5+R~eqAK$RyKA$Zva+`mI3;(!&qj;DL_+>-qwv;HgQxN)PMQ{wjO+X> z*3%*u+Gfk8HLIxRzzJk|2l^S5zUsv+F<&dIS2O@rIG?bn$^f11$y{v7qK=r)}ozW7;$7V`u)BQgx_vj&1CW&+`9uGd@gt3a+= z0uK~sB!82gzR9wu>;!eq?T=j?t%@&|s(R zl=)~`#JKv?z1?%1{i&6hcW&AQbsDr4eWjonASEg-A|iqgG5oP-@tlA0@Gk*cNg$g_v#|i}9z&l+wr ze-Ucj)=6Wte);qXs~dcroSa$uIL7*i?C)-3fkk%Lt@D`3yS9C5@>FOkYxr5E^U&HQ zGCsc2veyE*dheT`0G*jjZxjhX-c3+Fe5C*6i95TNT(>pJi=$LH<8}zpg$ejU=+k*7 z438j|dLDpi85W*8aCP@6vWfBfdgtRoq?xJx6WW0b|3<-q!Wb)jN|@(P9kiD(ePVpx zJDPlj>3Hu>Wx?!8JHV-BAuxU7(~xAnHt_Wl-RW38FW{$F&g77!d4#&9QyX$+H6*QC zkc|;w<(bBYWA933b+ZJOQqD94?KiXZe6nW{P>5|_7r9X~p5Ne$+2p);(x>knGoZ!F zAN%R^;anQ19kABMTObr^U^yn>1g~ry&Sf`@0wcB_=4hEkfQ`Xg<3GRB4mi$wOci!4 zwB2oYTU=g`uX{C}nYMAp-|VN%l+iKoWH!TEwuh$nO3R?N|Bm$(dWQ+~lKN2))RlV- z{D(D72)9yUxsG!3X;W9^F60(F^X_{*$OiLABR4?6gP)nbg#&b<}O?2=z|=7Ox;IqYNn-ne|Xo9^A~_Zm@zN! zJcmCuNOs#Alyb(Lq6#q%p=@JS0h&Z z=O@XMSd9xw6;qqI?*a)L%6Ec97x8)Sza#p(rirbJA>ZyRiInGP$DB zS-no5KOeWqqhbRf7Hr8W0pzZx`-y44$H81$z|D|2XzSFQG7k5jA2qICy>1M6mR|V% zt1W+htw#H~tV_q7tN(IlDZxy|7irL6Jup7;wb%1>UPCXw@^QKPt6SQId{&m zLRte|_3U!~4k%svgte~4vb>6XFYSOhkOEl-f^-*28E+}e$7X61V6GsNNKUm#DhMmu zg(m!rx{3A3d4&cduGng0NvNsPd#FAA9MaCmA9l*4gW>sc_qA7y7*1(bw8rg;!rzv| z06yyG3nG36VjjbIU+2#YqXV@RTU2#ETk zLHg^Rq19zxa0#u+&TJ27T_mtIS$}jg>ClocC5}6ewJIj(8yrNO^m~IEO~OIo}q66ruD8_xyGcj}R@;-IvNj%R;J1 z|Ebg6Nypp&^?CK~KU{7%#zmue-HngOrs@yC%}d$m0(i?cULZfAlmJx*wgF!+R=njQ zfNy^K2m|VGgsqDx9`-|41J{{OCg}K!R8)emZkCM4-}kQ2awDmikUKvT*nl9~W}_c6 z4z!P>l*Wzv@_otZl44@YW6O7bR%9G)tozWux2R+6E7o_ge&eV7mwKTI>y@il8J$ld zsUt#C4Us(0`yN4F&^pKIKFy2X3)e&Gg*`iSqn~yTHHxs??%3X46z>-JmiuV8(h4DcQtAA$L_vFaB@wE{O*2z!)a}HN zdT%{!A0RH0|GaPVnIhKznTIJ=!X=hHb!#Ukqk-z7#}94!y+%D&%*%{F#?V4*7Z@Mw zPrTeEj5p_8Vw2TqAFcKP9fgO&32Ae=t!p=HmnSuzz{0G_F zH|=0_a+W1Rk?iy>FaEEtL+4Hn2mvRtPMz%Z2a(VZI$Za-Jjo8`v_dRC5+BFD^{6=GHK#4%(Il9zB1Zku=308D8^G}iOK+X&P4sBaX2L%G(aBsq9v?WLC6Kfm zL|J~%5#JzEGw!?S-SkJQ!^duP%U(FIUd(_p0#0&oNOCY2NdLxA!TxXkoEAM>a@n4- za*x-_pVzB)ZeU` zO#^4Jb)*vgnt{5fC*uX)cRyv&U&yjM2Ig|#K;^yez;Sb@rNwN?_y#HTVR)af^#mMazKgp6LJ=c zqRb^`2B!v$g#5^)!(Ob=#yQqaq1#E{A_H{KvIa{;0Kia`!+U}82Fu#ibY{;D| ze#o=K_|8{Dizv-igDIkpq zAbH`#xyjy~t&HJMSRKq?veR#fH4&##YPa;`taix3=%N^TOScST z=nfBkO(7f2%j%4(!K?>E9g}Hu6+ffAY22f!^>XVO8OujKj~$ zeQoA9CFL4Z4Ne&VmKM9`2t&41Vw-`kmS6EaYlvnG^FQqLP$t|a3EPew1Hd<6^{|!y zu)W5gxl8(6hm$&;F7g>Q=Cdw&>o};QqB7_oy(S$%dQeA2e$T!t9Io;x6TDD`kYZEZ zaJVu*kDORjmny-J?d8s!=RYW39ogyM9?FW_rJU;uEFVwzkULY-f3Mi|T0TzWe}lBA zH?a(5Nwyg||}nI}H()u(?6_>ASK4+x+uAp>LsB`7fVS+3XrXkd=J zG-eMD7Us)RPL^_v2VU1&soL^pEIAqC!@J#XR=bBn7icga0k~DH#GYvb+?A6Xan(~d zU}%6SGKDl7TiGHy;-M2&p5*EX3CD3Ec0PK;m^Becf_Uramvwd}j=V?gCn7hZfXUkV z+_E0cRI=h5)>AwDxsb)@-YV+BJOUaVj`sH>vXto6ZUve2P<4SLub(bK?eZAq-bBn? zB-lyRU)?+z)TCT5ONpRP@_MeM$VXHpe}C{-J2J@)a3p6Rhjd!l(`a+E{J=YiqH6^O zC_y`0cbjlKZw%+T>mnpZ)Iy0|lP~?aLo1)Y%CB_q_}Wo8Hz#>*Euf8_| z9%8|Hg+k&G6wl(%3A^LP@t)62x4ylLzvcQmYgYbH zydxEwm%K(_>g%6Wc4NK!CjNnf5{K0j+_=!@oit~NUe%k^Gg#8S5b7~c4Eag zS7Mc|GQBya38WYw-Mup4PN6Y$T<_|@i@o0(^Pw)^TJJD8x*rm;EqK{{o~Iez4XBRl zo$_=t-l(k&xVm}#goa%6NHEN;Qr-FExjtQ#x<{gQfN8aU$1?>qPwEB=v0%B)lx~qp zscW4Mj5sf@r~EJET>@1mYCUshzI<=)n=-WCo6Lv(%1>W%IwS(^F1RVbz6r?Z;yU*K z&g8krp1f0=zaPX${J5t71$Eehz6ng^EMxdV+RTe4pJKGFAJJ4wI5pNL<_(~f@{-hL z^y|B;33_FMi7w_56Y|MAA8|qYOECUTEdRuS%E_qR`1Dvs59IFqzkL5ztbIQ!Rg>b~#&VE~9 zXK7fx@9M;VoOht2x_X;eM*mB_p{u3rVH)&hmBog`s)3W4*x87(s0PQ;hMSKt0wxS% z8@%I`1q-r8?sJG+NYbO`{=vCTg%bkjls%IJ7H4s)J40k}0A{>78s+VMC6MgUtV4F_ zoe&PE%bJ4N6tWZ?WPulis*TG?8zmm|x#RauS+XA8ry)6#&nFMHWeu9>BfmAH{d=Wd z_S5QD3k8wP(IAWP^&~bC)3jCwQ?(CX zH2&8C^(81yGyoo3p>lCi>{X2Hvw@7N>cL%JzBfj;cHJP2qdd7}?5T-uRR(8``wX$*KZ92iA5Gh*EN^2|mL&*!%V=2&g9zMw^%liwRfY;7xwAMd>+7fN z=y!fCb=yhsz(LnP^}h_JwM)AjJQ}u({nOAJ^N<0I`Yj_*T!0d$pU>=0=fJ-?iJN~& ziTW;NGnLmqJJs0+6b|H=U<`KzUck16{gh{@P~kSMz`Ey($Wl^2k@nJ#gp6ha;-!ur zJ6#vP$j*;+TBq@cfrG~m2=Dg}jxOmxd#@3X1>af?-0jY2_O>bz8}J^Ry#q}%8bVW?$k|1axHPuZ znIcdsAN-QSa^CC&nnIJMUg9q*`@>h(c)0-71b4=?hh+Faphn6g1ccNc^)~y=^cl;AE)0qgw}*!Mq|UF zt{Eg{hkjOnrH9v-Y!~rQ3mBQWexCye{-wm4@c%lH%C9)H5s+xlamWPyw_3bHIH>MT z^kv#C$*%R5&#+zYtAyjdF%=bW{?E^4^s9;Mr%cTHuNo++U$5x)?6fd18Gz(%U|oPS zREOBaCvirU)i{|WXd65Kc4nM-^FLoyntIj1av>>?a1^lK_i=#=ecP0E0ME1j6Hhuj zjyIMh0KE&#WEO?Pd28BOSD&{0bn!+_C9L5KeRWC}j?`kk_-jrj{oL$_@(Xl_GQ%V!S@ zA`9n8S2+!ddAFa&xDF7h2OpA06zerg_f^<#cL%p(gP{>8~qEj7A}9`*90 zV>|@Kf|m{AlGmkDMsU>VXbuW7?B%g@2QIJzag$5-n!_k&QJ=nRWg`3CN40PJ(f0y+ zmUlC2DQ5V8uA=cmuRkeWb7JtnxhakH=~M3J5JSk>G6N=He*^3fl|z~*W6IzqrLdBP z!&uV$rbp|9H$r-#G0zhXgo-tds2gO(Y&jh*>+$$&3T}(Fzg2!L2%&K-xfanhJaFGq z0%1)DrK9+!dmdeuwbpi;VUH2ZC0+gm|GQ?L>@|iBwCJ z@!WV}05Ykt{G&NunJmetW7scv$_Gz)9b?fUwicqT?g-~2_cL2 z_$-HtYEmvg93v2e8RL)Zn@q~P?FPZJM15Um?^rEXvvkcr#P23HNu@!bynxE6ZlJzb zmT9@x6W?F%%|xdE<`xzhuk$+^5xsN9p|K|x`6y%%2~ao+H0QS*EVRbv7-(How!b7B zJ9#9_uzYOdJ9Yf=(!eGuBoJf4v9V)v$m2RiyTf9_|1i}||D_OQW-AJYjgQ3V=1QOAfeLT)7O!#m)+ zHwHIeaDaPiaIRf}S?x=g<2-QHtNK$ArKR^XSk%yB>a1P`8S9;2Nh{4`koe^LkvRT= zXU)h6&&SHs!}H~PhaqvM)A}pqFId)(UeCN^EB|Tb%Vw`Hr)`GG@Yg>6Pm&G7JDH#2 zy8;zG>`j(7-_EVO#L4<jq_{`hm@1CLtDo1xWEvY@a1^FIB_u zDv}8^ukR2G{DZB|+6$skcG3-N{cT)+{U?58;vb^&=r0n5CNDItZaGKxRos5@g!Oud zt-Rn)zfnhF!+iar?oz*oo@$io3TH~kE6seR=#>UfxpI$D$oa0#%27CbMPlQ#14Yz; z0c7CgLWz3Ny$~(K{7O38?y9l3$gx3Jz~mMA3}Ytt#^E8jwh8r@p)U+h);Sd!`|}&# z7HzpP)3X}bV3QDJCG-H~LwOL5GS=5;eu_tz>gtpl!(DNFI_ z7zAP8J3OkO*A5OBUL_kxqR3?b!7{DYJ=E$0Ay8iHYq$Z6~ z8U&4Igyin%S;nUdj~gHtudBTaYwdy$gltNI5O-gBfZpx&B3N{M)fQ8z-Lw2RhFjA!VZKJIYcwCyFMVsp`kso*t%fh-p8_8Sjhw69jNYxy z1BnH{9cpOX<=BAP@EWOHc#?+PcxxY@h7zZkk;Z#mzq9>?kH6FO|Ns8~8u))o1C8eL Yr`y4?r8>!C$KzI0(teD6WD)j%0K(&1`~Uy| diff --git a/conf.py b/conf.py index 7fce14050..7c81d2e07 100644 --- a/conf.py +++ b/conf.py @@ -109,11 +109,11 @@ # sphinxext-opengraph config ogp_site_url = "https://devguide.python.org/" ogp_site_name = "Python Developer's Guide" -ogp_image = "_static/og-image.png" +ogp_image = "_static/og-image-200x200.png" ogp_custom_meta_tags = [ - '', - '', - '', + '', + '', + '', ] # Strip the dollar prompt when copying code From 249242a238b71efb85720f78c0ba6204bc2b7f34 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 5 Dec 2022 22:10:52 +0200 Subject: [PATCH 013/538] Generate release cycle chart and CSV (#988) Co-authored-by: C.A.M. Gerlach --- .github/workflows/release-cycle.yml | 31 +++++++ Makefile | 16 +++- _static/devguide_overrides.css | 65 +++++++++++++++ _tools/generate_release_cycle.py | 108 ++++++++++++++++++++++++ conf.py | 1 + include/branches.csv | 4 +- include/end-of-life.csv | 2 +- include/release-cycle.json | 122 ++++++++++++++++++++++++++++ include/release-cycle.mmd | 49 +++++++++++ make.bat | 8 ++ requirements.txt | 3 +- versions.rst | 8 +- 12 files changed, 411 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/release-cycle.yml create mode 100644 _tools/generate_release_cycle.py create mode 100644 include/release-cycle.json create mode 100644 include/release-cycle.mmd diff --git a/.github/workflows/release-cycle.yml b/.github/workflows/release-cycle.yml new file mode 100644 index 000000000..8b676d78a --- /dev/null +++ b/.github/workflows/release-cycle.yml @@ -0,0 +1,31 @@ +name: Test release cycle + +on: [pull_request, push, workflow_dispatch] + +env: + FORCE_COLOR: 1 + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [windows-latest, ubuntu-latest] + + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-python@v4 + with: + python-version: "3" + + - name: Generate release cycle output + run: python -I -bb -X dev -X warn_default_encoding -W error _tools/generate_release_cycle.py + + - name: Check for differences + run: | + git add . + git status + git diff --staged + test $(git status --porcelain | wc -l) = 0 diff --git a/Makefile b/Makefile index b64aecc45..6e5ee1693 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ help: @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " check to run a check for frequent markup errors" + @echo " versions to update release cycle after changing release-cycle.json" .PHONY: clean clean: clean-venv @@ -66,7 +67,7 @@ ensure-venv: fi .PHONY: html -html: ensure-venv +html: ensure-venv versions $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." @@ -186,3 +187,16 @@ check: ensure-venv serve: @echo "The 'serve' target was removed, use 'htmlview' instead" \ "(see https://github.com/python/cpython/issues/80510)" + +include/branches.csv: include/release-cycle.json + $(PYTHON) _tools/generate_release_cycle.py + +include/end-of-life.csv: include/release-cycle.json + $(PYTHON) _tools/generate_release_cycle.py + +include/release-cycle.mmd: include/release-cycle.json + $(PYTHON) _tools/generate_release_cycle.py + +.PHONY: versions +versions: include/branches.csv include/end-of-life.csv include/release-cycle.mmd + @echo Release cycle data generated. diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css index 8cafebebf..c34f47133 100644 --- a/_static/devguide_overrides.css +++ b/_static/devguide_overrides.css @@ -5,3 +5,68 @@ width: 111px; height: 110px; } + +/* Release cycle chart */ +#python-release-cycle .mermaid .active0, +#python-release-cycle .mermaid .active1, +#python-release-cycle .mermaid .active2, +#python-release-cycle .mermaid .active3 { + fill: #00dd00; + stroke: darkgreen; +} + +#python-release-cycle .mermaid .done0, +#python-release-cycle .mermaid .done1, +#python-release-cycle .mermaid .done2, +#python-release-cycle .mermaid .done3 { + fill: orange; + stroke: darkorange; +} + +#python-release-cycle .mermaid .task0, +#python-release-cycle .mermaid .task1, +#python-release-cycle .mermaid .task2, +#python-release-cycle .mermaid .task3 { + fill: #007acc; + stroke: #004455; +} + +#python-release-cycle .mermaid .section0, +#python-release-cycle .mermaid .section2 { + fill: darkgrey; +} + +/* Set master colours */ +:root { + --mermaid-section1-3: white; + --mermaid-text-color: black; +} + +@media (prefers-color-scheme: dark) { + body[data-theme=auto] { + --mermaid-section1-3: black; + --mermaid-text-color: #ffffffcc; + } +} +body[data-theme=dark] { + --mermaid-section1-3: black; + --mermaid-text-color: #ffffffcc; +} + +#python-release-cycle .mermaid .section1, +#python-release-cycle .mermaid .section3 { + fill: var(--mermaid-section1-3); +} + +#python-release-cycle .mermaid .grid .tick text, +#python-release-cycle .mermaid .sectionTitle0, +#python-release-cycle .mermaid .sectionTitle1, +#python-release-cycle .mermaid .sectionTitle2, +#python-release-cycle .mermaid .sectionTitle3, +#python-release-cycle .mermaid .taskTextOutside0, +#python-release-cycle .mermaid .taskTextOutside1, +#python-release-cycle .mermaid .taskTextOutside2, +#python-release-cycle .mermaid .taskTextOutside3, +#python-release-cycle .mermaid .titleText { + fill: var(--mermaid-text-color); +} diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py new file mode 100644 index 000000000..7e9e69ad8 --- /dev/null +++ b/_tools/generate_release_cycle.py @@ -0,0 +1,108 @@ +"""Read in a JSON and generate two CSVs and a Mermaid file.""" +from __future__ import annotations + +import csv +import datetime as dt +import json + +MERMAID_HEADER = """ +gantt + dateFormat YYYY-MM-DD + title Python release cycle + axisFormat %Y +""".lstrip() + +MERMAID_SECTION = """ + section Python {version} + {release_status} :{mermaid_status} python{version}, {first_release},{eol} +""" # noqa: E501 + +MERMAID_STATUS_MAPPING = { + "feature": "", + "bugfix": "active,", + "security": "done,", + "end-of-life": "crit,", +} + + +def csv_date(date_str: str, now_str: str) -> str: + """Format a date for CSV.""" + if date_str > now_str: + # Future, add italics + return f"*{date_str}*" + return date_str + + +def mermaid_date(date_str: str) -> str: + """Format a date for Mermaid.""" + if len(date_str) == len("yyyy-mm"): + # Mermaid needs a full yyyy-mm-dd, so let's approximate + date_str = f"{date_str}-01" + return date_str + + +class Versions: + """For converting JSON to CSV and Mermaid.""" + + def __init__(self) -> None: + with open("include/release-cycle.json", encoding="UTF-8") as in_file: + self.versions = json.load(in_file) + self.sorted_versions = sorted( + self.versions.items(), + key=lambda k: [int(i) for i in k[0].split(".")], + reverse=True, + ) + + def write_csv(self) -> None: + """Output CSV files.""" + now_str = str(dt.datetime.utcnow()) + + versions_by_category = {"branches": {}, "end-of-life": {}} + headers = None + for version, details in self.sorted_versions: + row = { + "Branch": details["branch"], + "Schedule": f":pep:`{details['pep']}`", + "Status": details["status"], + "First release": csv_date(details["first_release"], now_str), + "End of life": csv_date(details["end_of_life"], now_str), + "Release manager": details["release_manager"], + } + headers = row.keys() + cat = "end-of-life" if details["status"] == "end-of-life" else "branches" + versions_by_category[cat][version] = row + + for cat, versions in versions_by_category.items(): + with open(f"include/{cat}.csv", "w", encoding="UTF-8", newline="") as file: + csv_file = csv.DictWriter(file, fieldnames=headers, lineterminator="\n") + csv_file.writeheader() + csv_file.writerows(versions.values()) + + def write_mermaid(self) -> None: + """Output Mermaid file.""" + out = [MERMAID_HEADER] + + for version, details in reversed(self.versions.items()): + v = MERMAID_SECTION.format( + version=version, + first_release=details["first_release"], + eol=mermaid_date(details["end_of_life"]), + release_status=details["status"], + mermaid_status=MERMAID_STATUS_MAPPING[details["status"]], + ) + out.append(v) + + with open( + "include/release-cycle.mmd", "w", encoding="UTF-8", newline="\n" + ) as f: + f.writelines(out) + + +def main() -> None: + versions = Versions() + versions.write_csv() + versions.write_mermaid() + + +if __name__ == "__main__": + main() diff --git a/conf.py b/conf.py index 7c81d2e07..df7dfbaff 100644 --- a/conf.py +++ b/conf.py @@ -10,6 +10,7 @@ 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx_copybutton', + 'sphinxcontrib.mermaid', 'sphinxext.opengraph', 'sphinxext.rediraffe', ] diff --git a/include/branches.csv b/include/branches.csv index 565f0e25e..bfec9da84 100644 --- a/include/branches.csv +++ b/include/branches.csv @@ -1,5 +1,5 @@ -Branch,Schedule,Status,First release,End-of-life,Release manager -main,:pep:`693`,features,*2023-10-02*,*2028-10*,Thomas Wouters +Branch,Schedule,Status,First release,End of life,Release manager +main,:pep:`693`,feature,*2023-10-02*,*2028-10*,Thomas Wouters 3.11,:pep:`664`,bugfix,2022-10-24,*2027-10*,Pablo Galindo Salgado 3.10,:pep:`619`,bugfix,2021-10-04,*2026-10*,Pablo Galindo Salgado 3.9,:pep:`596`,security,2020-10-05,*2025-10*,Łukasz Langa diff --git a/include/end-of-life.csv b/include/end-of-life.csv index 44bb3cc16..be9fe1b72 100644 --- a/include/end-of-life.csv +++ b/include/end-of-life.csv @@ -1,4 +1,4 @@ -Branch,Schedule,Status,First release,End-of-life,Release manager +Branch,Schedule,Status,First release,End of life,Release manager 3.6,:pep:`494`,end-of-life,2016-12-23,2021-12-23,Ned Deily 3.5,:pep:`478`,end-of-life,2015-09-13,2020-09-30,Larry Hastings 3.4,:pep:`429`,end-of-life,2014-03-16,2019-03-18,Larry Hastings diff --git a/include/release-cycle.json b/include/release-cycle.json new file mode 100644 index 000000000..df82e64ed --- /dev/null +++ b/include/release-cycle.json @@ -0,0 +1,122 @@ +{ + "3.12": { + "branch": "main", + "pep": 693, + "status": "feature", + "first_release": "2023-10-02", + "end_of_life": "2028-10", + "release_manager": "Thomas Wouters" + }, + "3.11": { + "branch": "3.11", + "pep": 664, + "status": "bugfix", + "first_release": "2022-10-24", + "end_of_life": "2027-10", + "release_manager": "Pablo Galindo Salgado" + }, + "3.10": { + "branch": "3.10", + "pep": 619, + "status": "bugfix", + "first_release": "2021-10-04", + "end_of_life": "2026-10", + "release_manager": "Pablo Galindo Salgado" + }, + "3.9": { + "branch": "3.9", + "pep": 596, + "status": "security", + "first_release": "2020-10-05", + "end_of_life": "2025-10", + "release_manager": "Łukasz Langa" + }, + "3.8": { + "branch": "3.8", + "pep": 569, + "status": "security", + "first_release": "2019-10-14", + "end_of_life": "2024-10", + "release_manager": "Łukasz Langa" + }, + "3.7": { + "branch": "3.7", + "pep": 537, + "status": "security", + "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" + } +} diff --git a/include/release-cycle.mmd b/include/release-cycle.mmd new file mode 100644 index 000000000..fc437ab59 --- /dev/null +++ b/include/release-cycle.mmd @@ -0,0 +1,49 @@ +gantt + dateFormat YYYY-MM-DD + title Python release cycle + axisFormat %Y + + section Python 2.6 + end-of-life :crit, python2.6, 2008-10-01,2013-10-29 + + section Python 3.0 + end-of-life :crit, python3.0, 2008-12-03,2009-06-27 + + section Python 3.1 + end-of-life :crit, python3.1, 2009-06-27,2012-04-09 + + section Python 2.7 + end-of-life :crit, python2.7, 2010-07-03,2020-01-01 + + section Python 3.2 + end-of-life :crit, python3.2, 2011-02-20,2016-02-20 + + section Python 3.3 + end-of-life :crit, python3.3, 2012-09-29,2017-09-29 + + section Python 3.4 + end-of-life :crit, python3.4, 2014-03-16,2019-03-18 + + section Python 3.5 + end-of-life :crit, python3.5, 2015-09-13,2020-09-30 + + section Python 3.6 + end-of-life :crit, python3.6, 2016-12-23,2021-12-23 + + section Python 3.7 + security :done, python3.7, 2018-06-27,2023-06-27 + + section Python 3.8 + security :done, python3.8, 2019-10-14,2024-10-01 + + section Python 3.9 + security :done, python3.9, 2020-10-05,2025-10-01 + + section Python 3.10 + bugfix :active, python3.10, 2021-10-04,2026-10-01 + + section Python 3.11 + bugfix :active, python3.11, 2022-10-24,2027-10-01 + + section Python 3.12 + feature : python3.12, 2023-10-02,2028-10-01 diff --git a/make.bat b/make.bat index 5fe9f98d7..432b7f361 100644 --- a/make.bat +++ b/make.bat @@ -223,6 +223,14 @@ goto end (see https://github.com/python/cpython/issues/80510) goto end +if "%1" == "versions" ( + %PYTHON% _tools/generate_release_cycle.py + if errorlevel 1 exit /b 1 + echo. + echo Release cycle data generated. + goto end +) + :end popd endlocal diff --git a/requirements.txt b/requirements.txt index e7831193e..f0397b9c4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ Sphinx==5.3.0 furo>=2022.6.4 -sphinx_copybutton>=0.3.3 sphinx-lint==0.6.7 +sphinx_copybutton>=0.3.3 +sphinxcontrib-mermaid sphinxext-opengraph>=0.7.1 sphinxext-rediraffe diff --git a/versions.rst b/versions.rst index c4e1b049f..2d08ac027 100644 --- a/versions.rst +++ b/versions.rst @@ -10,6 +10,12 @@ branch that accepts new features. The latest release for each Python version can be found on the `download page `_. +Python Release Cycle +==================== + +.. mermaid:: include/release-cycle.mmd + + Supported Versions ================== @@ -35,7 +41,7 @@ Unsupported Versions Status Key ========== -:features: new features, bugfixes, and security fixes are accepted. +:feature: new features, bugfixes, and security fixes are accepted. :prerelease: feature fixes, bugfixes, and security fixes are accepted for the upcoming feature release. :bugfix: bugfixes and security fixes are accepted, new binaries are still From c4d2e67d2aa0201703136dda4b04e2ef70a162c1 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 6 Dec 2022 11:20:55 +0200 Subject: [PATCH 014/538] Release cycle chart: show suggestion if JavaScript disabled (#997) --- versions.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/versions.rst b/versions.rst index 2d08ac027..c36f7e672 100644 --- a/versions.rst +++ b/versions.rst @@ -55,3 +55,16 @@ See also the :ref:`devcycle` page for more information about branches. By default, the end-of-life is scheduled 5 years after the first release, but can be adjusted by the release manager of each branch. All Python 2 versions have reached end-of-life. + +.. raw:: html + + From 89e6de9aeac1ee4d673f73f1be2737868e6c7d51 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 8 Dec 2022 16:24:36 +0200 Subject: [PATCH 015/538] Remove reference to unused Zulip chat (#1001) --- getting-started/getting-help.rst | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/getting-started/getting-help.rst b/getting-started/getting-help.rst index 456403a10..dce04a570 100644 --- a/getting-started/getting-help.rst +++ b/getting-started/getting-help.rst @@ -73,23 +73,6 @@ whereas ``#python`` is for questions concerning development *with* Python. .. _Libera.Chat: https://libera.chat/ -Zulip ------ - -An alternative to IRC is our own `Zulip`_ instance. There are different streams -for asking help with core development, as well as core developers' office -hour stream. It is preferred that you ask questions here first or schedule -an office hour, before posting to python-dev mailing list or filing bugs. - -.. warning:: - - This is no longer actively monitored by core devs. - Consider asking your questions in the relevant - :ref:`Discourse ` category instead. - -.. _Zulip: https://python.zulipchat.com - - Core Mentorship --------------- @@ -121,15 +104,6 @@ during office hours. +==================+===============================+================================================+ | Zachary Ware | See details link | Schedule at https://calendly.com/zware | +------------------+-------------------------------+------------------------------------------------+ -| Mariatta Wijaya | Thursdays 7PM - 8PM Pacific | In `Python's Zulip Chat`_, Core > Office | -| | (Vancouver, Canada Timezone) | Hour stream. A reminder will be posted to both | -| | | Zulip and `Mariatta's twitter`_ account | -| | | 24 hours before the start. | -+------------------+-------------------------------+------------------------------------------------+ - -.. _Python's Zulip Chat: https://python.zulipchat.com/login/#narrow/stream/116503-core/topic/Office.20Hour -.. _Mariatta's twitter: https://twitter.com/mariatta - File a Bug ---------- From 1cffabfddd3ac4985d50bceb52c57fe83bd31955 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 8 Dec 2022 20:46:15 +0200 Subject: [PATCH 016/538] Update link redirects (#1002) --- documentation/translating.rst | 8 ++++---- getting-started/git-boot-camp.rst | 6 +++--- getting-started/pull-request-lifecycle.rst | 8 ++++---- getting-started/setup-building.rst | 2 +- index.rst | 2 -- internals/compiler.rst | 2 +- testing/coverage.rst | 2 +- triage/github-bpo-faq.rst | 2 +- triage/labels.rst | 2 +- 9 files changed, 16 insertions(+), 18 deletions(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 74ca846f3..d5fffa0fa 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -103,7 +103,7 @@ in production; others are works in progress. .. _github_ar: https://github.com/Abdur-rahmaanJ/python-docs-ar .. _github_bn_in: https://github.com/python/python-docs-bn-in .. _github_es: https://github.com/python/python-docs-es -.. _github_fa: https://github.com/mmdbalkhi/python-docs-fa +.. _github_fa: https://github.com/ftg-iran/python-docs-fa .. _github_fr: https://github.com/python/python-docs-fr .. _github_hi_in: https://github.com/CuriousLearner/python-docs-hi-in .. _github_hu: https://github.com/python/python-docs-hu @@ -122,9 +122,9 @@ in production; others are works in progress. .. _mail_lt: https://mail.python.org/pipermail/doc-sig/2019-July/004138.html .. _mail_pl: https://mail.python.org/pipermail/doc-sig/2019-April/004106.html .. _mail_ru: https://mail.python.org/pipermail/doc-sig/2019-May/004131.html -.. _tx_pl: https://www.transifex.com/python-doc/python-newest/ -.. _tx_uk: https://www.transifex.com/python-doc/python-newest/ -.. _tx_zh_cn: https://www.transifex.com/python-doc/python-newest/ +.. _tx_pl: https://explore.transifex.com/python-doc/python-newest/ +.. _tx_uk: https://explore.transifex.com/python-doc/python-newest/ +.. _tx_zh_cn: https://explore.transifex.com/python-doc/python-newest/ .. _wiki_pt_br: https://python.org.br/traducao/ Starting a new translation diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index c2ca538df..efb49aee8 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -373,8 +373,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: @@ -552,7 +552,7 @@ 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``. -.. _Allow edits from maintainers: https://help.github.com/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork/ +.. _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 To edit an open pull request that targets ``main``: diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index fa6077d51..a53e97952 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -64,8 +64,8 @@ Here is a quick overview of how you can contribute to CPython: .. _create an issue: https://github.com/python/cpython/issues .. _CPython: https://github.com/python/cpython .. _use HTTPS: https://help.github.com/articles/which-remote-url-should-i-use/ -.. _Create Pull Request: https://help.github.com/articles/creating-a-pull-request/ -.. _comments on your Pull Request: https://help.github.com/articles/commenting-on-a-pull-request/ +.. _Create Pull Request: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request +.. _comments on your Pull Request: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/commenting-on-a-pull-request .. _pullrequest-steps: @@ -363,7 +363,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. @@ -398,7 +398,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 cd0f47c22..575a9ca6c 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -44,7 +44,7 @@ itself. git is easily available for all common operating systems. - **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 diff --git a/index.rst b/index.rst index 1f8a2ce2c..a96437f97 100644 --- a/index.rst +++ b/index.rst @@ -183,8 +183,6 @@ Key Resources * :PEP:`7` (Style Guide for C Code) * :PEP:`8` (Style Guide for Python Code) * `Issue tracker`_ - * `Meta tracker `_ (issue - tracker for the issue tracker) * :ref:`experts` * `Buildbot status`_ * Source code diff --git a/internals/compiler.rst b/internals/compiler.rst index 0e31e1be4..9d04c7148 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -690,7 +690,7 @@ References (https://legacy.python.org/workshops/1998-11/proceedings/papers/montanaro/montanaro.html) .. [#Bytecodehacks] Bytecodehacks Project - (http://bytecodehacks.sourceforge.net/bch-docs/bch/index.html) + (https://bytecodehacks.sourceforge.net/bch-docs/bch/index.html) .. [#CALL_ATTR] CALL_ATTR opcode (https://bugs.python.org/issue709744) diff --git a/testing/coverage.rst b/testing/coverage.rst index 48c928993..a574fb3e1 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -292,4 +292,4 @@ about 20 to 30 minutes on a modern computer. .. _issue tracker: https://github.com/python/cpython/issues .. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html -.. _lcov: http://ltp.sourceforge.net/coverage/lcov.php +.. _lcov: https://ltp.sourceforge.net/coverage/lcov.php diff --git a/triage/github-bpo-faq.rst b/triage/github-bpo-faq.rst index d69d04fc9..1027056ff 100644 --- a/triage/github-bpo-faq.rst +++ b/triage/github-bpo-faq.rst @@ -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"? =============================== diff --git a/triage/labels.rst b/triage/labels.rst index e749c700a..6b8a33e8c 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -357,7 +357,7 @@ automatically mark a task as complete if the other referenced issue is closed. More details in the `official GitHub documentation -`_. +`_. Superseder ---------- From f9f005a0b69f338b7ca2a90cb8c9429013408e69 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 8 Dec 2022 22:15:21 +0200 Subject: [PATCH 017/538] Update name to macOS (#995) --- advanced-tools/clang.rst | 2 +- core-developers/experts.rst | 2 +- getting-started/pull-request-lifecycle.rst | 2 +- getting-started/setup-building.rst | 8 ++++---- index.rst | 7 +++---- testing/coverage.rst | 2 +- testing/run-write-tests.rst | 2 +- 7 files changed, 12 insertions(+), 13 deletions(-) diff --git a/advanced-tools/clang.rst b/advanced-tools/clang.rst index d626c33ea..1f693fcae 100644 --- a/advanced-tools/clang.rst +++ b/advanced-tools/clang.rst @@ -110,7 +110,7 @@ After ``make install`` executes, the compilers will be installed in libclang_rt.lsan-x86_64.a libclang_rt.ubsan_cxx-x86_64.a libclang_rt.msan-x86_64.a libclang_rt.ubsan-x86_64.a -On Mac OS X, the libraries are installed in +On macOS, the libraries are installed in ``/usr/local/lib/clang/3.3/lib/darwin/``: .. code-block:: console diff --git a/core-developers/experts.rst b/core-developers/experts.rst index e7b80febc..ddacdf7f4 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -299,7 +299,7 @@ Cygwin jlt63^, stutzbach^ FreeBSD HP-UX Linux -Mac OS X ronaldoussoren, ned-deily +macOS ronaldoussoren, ned-deily NetBSD1 OS2/EMX aimacintyre^ Solaris/OpenIndiana jcea diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index a53e97952..bb685e21b 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -241,7 +241,7 @@ should do to help ensure that your pull request is accepted. ``patchcheck`` is a simple automated patch checklist that guides a developer through the common patch generation checks. To run ``patchcheck``: - On *UNIX* (including Mac OS X):: + On *UNIX* (including macOS):: make patchcheck diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 575a9ca6c..db6f3a17b 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -209,7 +209,7 @@ If you decide to :ref:`build-dependencies`, you will need to re-run both Once CPython is done building you will then have a working build that can be run in-place; ``./python`` on most machines (and what is used in all examples), ``./python.exe`` wherever a case-insensitive filesystem is used -(e.g. on OS X by default), in order to avoid conflicts with the ``Python`` +(e.g. on macOS by default), in order to avoid conflicts with the ``Python`` directory. There is normally no need to install your built copy of Python! The interpreter will realize where it is being run from and thus use the files found in the working copy. If you are worried @@ -326,7 +326,7 @@ Install dependencies ==================== This section explains how to install additional extensions (e.g. ``zlib``) -on :ref:`Linux ` and :ref:`macOs/OS X `. On Windows, +on :ref:`Linux ` and :ref:`macOS`. On Windows, extensions are already included and built automatically. .. _deps-on-linux: @@ -385,7 +385,7 @@ their dependencies:: lzma lzma-dev tk-dev uuid-dev zlib1g-dev -.. _MacOS: +.. _macOS: macOS and OS X -------------- @@ -610,7 +610,7 @@ every rule. The part of the standard library implemented in pure Python. ``Mac`` - Mac-specific code (e.g., using IDLE as an OS X application). + Mac-specific code (e.g., using IDLE as a macOS application). ``Misc`` Things that do not belong elsewhere. Typically this is varying kinds of diff --git a/index.rst b/index.rst index a96437f97..0ec2cfef9 100644 --- a/index.rst +++ b/index.rst @@ -27,7 +27,7 @@ instructions please see the :ref:`setup guide `. git clone https://github.com//cpython cd cpython -3. Build Python, on UNIX and Mac OS use:: +3. Build Python, on UNIX and macOS use:: ./configure --with-pydebug && make -j @@ -40,13 +40,13 @@ instructions please see the :ref:`setup guide `. See also :ref:`more detailed instructions `, :ref:`how to install and build dependencies `, and the platform-specific pages for :ref:`UNIX `, - :ref:`Mac OS `, and :ref:`Windows `. + :ref:`macOS`, and :ref:`Windows `. 4. :ref:`Run the tests `:: ./python -m test -j3 - On :ref:`most ` Mac OS X systems, replace :file:`./python` + On :ref:`most ` macOS systems, replace :file:`./python` with :file:`./python.exe`. On Windows, use :file:`python.bat`. 5. Create a new branch where your work for the issue will go, e.g.:: @@ -188,7 +188,6 @@ Key Resources * Source code * `Browse online `_ * `Snapshot of the *main* branch `_ - * `Daily OS X installer `_ * PEPs_ (Python Enhancement Proposals) * :ref:`help` * :ref:`developers` diff --git a/testing/coverage.rst b/testing/coverage.rst index a574fb3e1..49a2ff129 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -93,7 +93,7 @@ On Unix run:: source ../cpython-venv/bin/activate pip install coverage -On :ref:`most ` Mac OS X systems run:: +On :ref:`most ` macOS systems run:: ./python.exe -m venv ../cpython-venv source ../cpython-venv/bin/activate diff --git a/testing/run-write-tests.rst b/testing/run-write-tests.rst index b1813be9c..f9323463a 100644 --- a/testing/run-write-tests.rst +++ b/testing/run-write-tests.rst @@ -22,7 +22,7 @@ from the root directory of your checkout (after you have ./python -m test You may need to change this command as follows throughout this section. -On :ref:`most ` Mac OS X systems, replace :file:`./python` +On :ref:`most ` macOS systems, replace :file:`./python` with :file:`./python.exe`. On Windows, use :file:`python.bat`. If using Python 2.7, replace ``test`` with ``test.regrtest``. From 71e46f02e0c56b173b116b02e258aea365539634 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Fri, 9 Dec 2022 10:50:55 +0100 Subject: [PATCH 018/538] Use `:cpy-file:` throughout the Devguide (#984) * Use :cpy-file: throughout the Devguide. * Fix broken file paths. --- core-developers/experts.rst | 2 +- developer-workflow/c-api.rst | 4 +- developer-workflow/grammar.rst | 49 ++++++----- documentation/start-documenting.rst | 14 +-- getting-started/git-boot-camp.rst | 2 +- internals/compiler.rst | 131 +++++++++++++++------------- internals/exploring.rst | 18 ++-- 7 files changed, 114 insertions(+), 106 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index ddacdf7f4..dc918ab58 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -17,7 +17,7 @@ while any other issues can and should be decided by any committer. Developers can choose to follow labels, so if a label that they are following is added to an issue or pull request, they will be notified -automatically. The :file:`CODEOWNERS` file is also used to indicate +automatically. The :cpy-file:`.github/CODEOWNERS` file is also used to indicate maintainers that will be automatically added as reviewers to pull requests. Unless a name is followed by a '*', you should never assign an issue to diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index d51814a0f..3e6199f8e 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -101,12 +101,12 @@ C API Tests Tests for the public C API live in the ``_testcapi`` module. Functions named ``test_*`` are used as tests directly. Tests that need Python code (or are just easier to partially write in Python) -live in ``Lib/test``, mainly in :file:`Lib/test/test_capi.py`. +live in ``Lib/test``, mainly in :cpy-file:`Lib/test/test_capi`. Due to its size, the ``_testcapi`` module is defined in several source files. To add a new set of tests (or extract a set out of the monolithic -:file:`Modules/_testcapimodule.c`): +:cpy-file:`Modules/_testcapimodule.c`): - Create a C file named ``Modules/_testcapi/yourfeature.c`` diff --git a/developer-workflow/grammar.rst b/developer-workflow/grammar.rst index 7ff1ed12a..7d6b40993 100644 --- a/developer-workflow/grammar.rst +++ b/developer-workflow/grammar.rst @@ -8,7 +8,7 @@ Abstract ======== There's more to changing Python's grammar than editing -:file:`Grammar/python.gram`. Here's a checklist. +:cpy-file:`Grammar/python.gram`. Here's a checklist. .. note:: These instructions are for Python 3.9 and beyond. Earlier @@ -25,42 +25,45 @@ Checklist Note: sometimes things mysteriously don't work. Before giving up, try ``make clean``. -* :file:`Grammar/python.gram`: The grammar, with actions that build AST nodes. After changing - it, run ``make regen-pegen`` (or ``build.bat --regen`` on Windows), to - regenerate :file:`Parser/parser.c`. +* :cpy-file:`Grammar/python.gram`: The grammar, with actions that build AST nodes. + After changing it, run ``make regen-pegen`` (or ``build.bat --regen`` on Windows), + to regenerate :cpy-file:`Parser/parser.c`. (This runs Python's parser generator, ``Tools/peg_generator``). -* :file:`Grammar/Tokens` is a place for adding new token types. After - changing it, run ``make regen-token`` to regenerate :file:`Include/token.h`, - :file:`Parser/token.c`, :file:`Lib/token.py` and - :file:`Doc/library/token-list.inc`. If you change both ``python.gram`` and ``Tokens``, - run ``make regen-token`` before ``make regen-pegen``. On Windows, - ``build.bat --regen`` will regenerate both at the same time. +* :cpy-file:`Grammar/Tokens` is a place for adding new token types. After + changing it, run ``make regen-token`` to regenerate :cpy-file:`Include/token.h`, + :cpy-file:`Parser/token.c`, :cpy-file:`Lib/token.py` and + :cpy-file:`Doc/library/token-list.inc`. If you change both ``python.gram`` + and ``Tokens``, run ``make regen-token`` before ``make regen-pegen``. + On Windows, ``build.bat --regen`` will regenerate both at the same time. -* :file:`Parser/Python.asdl` may need changes to match the grammar. Then run ``make - regen-ast`` to regenerate :file:`Include/Python-ast.h` and :file:`Python/Python-ast.c`. +* :cpy-file:`Parser/Python.asdl` may need changes to match the grammar. + Then run ``make regen-ast`` to regenerate :cpy-file:`Include/Python-ast.h` + and :cpy-file:`Python/Python-ast.c`. -* :file:`Parser/tokenizer.c` contains the tokenization code. This is where you would - add a new type of comment or string literal, for example. +* :cpy-file:`Parser/tokenizer.c` contains the tokenization code. + This is where you would add a new type of comment or string literal, for example. -* :file:`Python/ast.c` will need changes to validate AST objects involved with the - grammar change. +* :cpy-file:`Python/ast.c` will need changes to validate AST objects + involved with the grammar change. -* :file:`Python/ast_unparse.c` will need changes to unparse AST objects involved with the - grammar change ("unparsing" is used to turn annotations into strings per :pep:`563`). +* :cpy-file:`Python/ast_unparse.c` will need changes to unparse AST + involved with the grammar change ("unparsing" is used to turn annotations + into strings per :pep:`563`). * The :ref:`compiler` has its own page. -* ``_Unparser`` in the :file:`Lib/ast.py` file may need changes to accommodate - any modifications in the AST nodes. +* ``_Unparser`` in the :cpy-file:`Lib/ast.py` file may need changes + to accommodate any modifications in the AST nodes. -* :file:`Doc/library/ast.rst` may need to be updated to reflect changes to AST nodes. +* :cpy-file:`Doc/library/ast.rst` may need to be updated to reflect changes + to AST nodes. * Add some usage of your new syntax to ``test_grammar.py``. * Certain changes may require tweaks to the library module :mod:`pyclbr`. -* :file:`Lib/tokenize.py` needs changes to match changes to the tokenizer. +* :cpy-file:`Lib/tokenize.py` needs changes to match changes to the tokenizer. * Documentation must be written! Specifically, one or more of the pages in - :file:`Doc/reference/` will need to be updated. + :cpy-file:`Doc/reference/` will need to be updated. diff --git a/documentation/start-documenting.rst b/documentation/start-documenting.rst index 8a0db2404..175c73c0a 100644 --- a/documentation/start-documenting.rst +++ b/documentation/start-documenting.rst @@ -101,11 +101,11 @@ You can also use ``make help`` to see a list of targets supported by you submit a :ref:`pull request `, so you should make sure that it runs without errors. -**On Windows**, a :file:`make.bat` batchfile tries to emulate :command:`make` -as closely as possible, but the venv target is not implemented, so you will -probably want to make sure you are working in a virtual environment before -proceeding, otherwise all dependencies will be automatically installed on your -system. +**On Windows**, the :cpy-file:`Doc/make.bat` batchfile tries to emulate +:command:`make` as closely as possible, but the venv target is not implemented, +so you will probably want to make sure you are working in a virtual environment +before proceeding, otherwise all dependencies will be automatically installed +on your system. When ready, run the following from the root of your :ref:`repository clone ` to build the output as HTML:: @@ -114,9 +114,9 @@ When ready, run the following from the root of your :ref:`repository clone make html You can also use ``make help`` to see a list of targets supported by -:file:`make.bat`. +:cpy-file:`Doc/make.bat`. -See also :file:`Doc/README.rst` for more information. +See also :cpy-file:`Doc/README.rst` for more information. Using sphinx-build ------------------ diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index efb49aee8..e29dc1e05 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -274,7 +274,7 @@ Exclude generated files from diff by default:: git config diff.generated.binary true The ``generated`` `attribute `_ is -defined in :file:`.gitattributes`, found in the repository root. +defined in :cpy-file:`.gitattributes`, found in the repository root. .. _push-changes: diff --git a/internals/compiler.rst b/internals/compiler.rst index 9d04c7148..7b5df7b87 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -11,10 +11,11 @@ Abstract In CPython, the compilation from source code to bytecode involves several steps: -1. Tokenize the source code (:file:`Parser/tokenizer.c`) -2. Parse the stream of tokens into an Abstract Syntax Tree (:file:`Parser/parser.c`) -3. Transform AST into a Control Flow Graph (:file:`Python/compile.c`) -4. Emit bytecode based on the Control Flow Graph (:file:`Python/compile.c`) +1. Tokenize the source code (:cpy-file:`Parser/tokenizer.c`) +2. Parse the stream of tokens into an Abstract Syntax Tree + (:cpy-file:`Parser/parser.c`) +3. Transform AST into a Control Flow Graph (:cpy-file:`Python/compile.c`) +4. Emit bytecode based on the Control Flow Graph (:cpy-file:`Python/compile.c`) The purpose of this document is to outline how these steps of the process work. @@ -32,9 +33,9 @@ unusual design (since its input is a stream of tokens rather than a stream of characters as is more common with PEG parsers). The grammar file for Python can be found in -:file:`Grammar/python.gram`. The definitions for literal tokens -(such as ``:``, numbers, etc.) can be found in :file:`Grammar/Tokens`. -Various C files, including :file:`Parser/parser.c` are generated from +:cpy-file:`Grammar/python.gram`. The definitions for literal tokens +(such as ``:``, numbers, etc.) can be found in :cpy-file:`Grammar/Tokens`. +Various C files, including :cpy-file:`Parser/parser.c` are generated from these (see :ref:`grammar`). @@ -55,7 +56,7 @@ specification of the AST nodes is specified using the Zephyr Abstract Syntax Definition Language (ASDL) [Wang97]_. The definition of the AST nodes for Python is found in the file -:file:`Parser/Python.asdl`. +:cpy-file:`Parser/Python.asdl`. Each AST node (representing statements, expressions, and several specialized types, like list comprehensions and exception handlers) is @@ -142,7 +143,7 @@ In general, unless you are working on the critical core of the compiler, memory management can be completely ignored. But if you are working at either the very beginning of the compiler or the end, you need to care about how the arena works. All code relating to the arena is in either -:file:`Include/Internal/pycore_pyarena.h` or :file:`Python/pyarena.c`. +:cpy-file:`Include/internal/pycore_pyarena.h` or :cpy-file:`Python/pyarena.c`. ``PyArena_New()`` will create a new arena. The returned ``PyArena`` structure will store pointers to all memory given to it. This does the bookkeeping of @@ -166,15 +167,16 @@ Source Code to AST The AST is generated from source code using the function ``_PyParser_ASTFromString()`` or ``_PyParser_ASTFromFile()`` -(from :file:`Parser/peg_api.c`) depending on the input type. +(from :cpy-file:`Parser/peg_api.c`) depending on the input type. -After some checks, a helper function in :file:`Parser/parser.c` begins applying +After some checks, a helper function in :cpy-file:`Parser/parser.c` begins applying production rules on the source code it receives; converting source code to tokens and matching these tokens recursively to their corresponding rule. The rule's corresponding rule function is called on every match. These rule functions follow the format :samp:`xx_rule`. Where *xx* is the grammar rule that the function handles and is automatically derived from -:file:`Grammar/python.gram` by :file:`Tools/peg_generator/pegen/c_generator.py`. +:cpy-file:`Grammar/python.gram` +:cpy-file:`Tools/peg_generator/pegen/c_generator.py`. Each rule function in turn creates an AST node as it goes along. It does this by allocating all the new nodes it needs, calling the proper AST node creation @@ -185,9 +187,9 @@ there are no more rules, an error is set and the parsing ends. The AST node creation helper functions have the name :samp:`_PyAST_{xx}` where *xx* is the AST node that the function creates. These are defined by the -ASDL grammar and contained in :file:`Python/Python-ast.c` (which is generated by -:file:`Parser/asdl_c.py` from :file:`Parser/Python.asdl`). This all leads to a -sequence of AST nodes stored in ``asdl_seq`` structs. +ASDL grammar and contained in :cpy-file:`Python/Python-ast.c` (which is +generated by :cpy-file:`Parser/asdl_c.py` from :cpy-file:`Parser/Python.asdl`). +This all leads to a sequence of AST nodes stored in ``asdl_seq`` structs. To demonstrate everything explained so far, here's the rule function responsible for a simple named import statement such as @@ -240,8 +242,8 @@ manner stated in the previous paragraphs. There are macros for creating and using ``asdl_xx_seq *`` types, where *xx* is a type of the ASDL sequence. Three main types are defined manually -- ``generic``, ``identifier`` and ``int``. These types are found in -:file:`Python/asdl.c` and its corresponding header file -:file:`Include/Internal/pycore_asdl.h`. Functions and macros +:cpy-file:`Python/asdl.c` and its corresponding header file +:cpy-file:`Include/internal/pycore_asdl.h`. Functions and macros for creating ``asdl_xx_seq *`` types are as follows: ``_Py_asdl_generic_seq_new(Py_ssize_t, PyArena *)`` @@ -252,9 +254,9 @@ for creating ``asdl_xx_seq *`` types are as follows: Allocate memory for an ``asdl_int_seq`` of the specified length In addition to the three types mentioned above, some ASDL sequence types are -automatically generated by :file:`Parser/asdl_c.py` and found in -:file:`Include/Internal/pycore_ast.h`. Macros for using both manually defined -and automatically generated ASDL sequence types are as follows: +automatically generated by :cpy-file:`Parser/asdl_c.py` and found in +:cpy-file:`Include/internal/pycore_ast.h`. Macros for using both manually +defined and automatically generated ASDL sequence types are as follows: ``asdl_seq_GET(asdl_xx_seq *, int)`` Get item held at a specific position in an ``asdl_xx_seq`` @@ -348,11 +350,12 @@ global). With that done, the second pass essentially flattens the CFG into a list and calculates jump offsets for final output of bytecode. The conversion process is initiated by a call to the function -``_PyAST_Compile()`` in :file:`Python/compile.c`. This function does both the -conversion of the AST to a CFG and outputting final bytecode from the CFG. +``_PyAST_Compile()`` in :cpy-file:`Python/compile.c`. This function does both +the conversion of the AST to a CFG and outputting final bytecode from the CFG. The AST to CFG step is handled mostly by two functions called by -``_PyAST_Compile()``; ``_PySymtable_Build()`` and ``compiler_mod()``. The former -is in :file:`Python/symtable.c` while the latter is in :file:`Python/compile.c`. +``_PyAST_Compile()``; ``_PySymtable_Build()`` and ``compiler_mod()``. +The former is in :cpy-file:`Python/symtable.c` while the latter is +:cpy-file:`Python/compile.c`. ``_PySymtable_Build()`` begins by entering the starting code block for the AST (passed-in) and then calling the proper :samp:`symtable_visit_{xx}` function @@ -362,7 +365,7 @@ as blocks are entered and exited using ``symtable_enter_block()`` and ``symtable_exit_block()``, respectively. Once the symbol table is created, it is time for CFG creation, whose -code is in :file:`Python/compile.c`. This is handled by several functions +code is in :cpy-file:`Python/compile.c`. This is handled by several functions that break the task down by various AST node types. The functions are all named :samp:`compiler_visit_{xx}` where *xx* is the name of the node type (such as ``stmt``, ``expr``, etc.). Each function receives a ``struct compiler *`` @@ -458,24 +461,24 @@ bytecode step of the compiler. Several pieces of code throughout Python depend on having correct information about what bytecode exists. First, you must choose a name and a unique identifier number. The official -list of bytecode can be found in :file:`Lib/opcode.py`. If the opcode is to +list of bytecode can be found in :cpy-file:`Lib/opcode.py`. If the opcode is to take an argument, it must be given a unique number greater than that assigned to -``HAVE_ARGUMENT`` (as found in :file:`Lib/opcode.py`). +``HAVE_ARGUMENT`` (as found in :cpy-file:`Lib/opcode.py`). -Once the name/number pair has been chosen and entered in :file:`Lib/opcode.py`, -you must also enter it into :file:`Doc/library/dis.rst`, and regenerate -:file:`Include/opcode.h` and :file:`Python/opcode_targets.h` by running +Once the name/number pair has been chosen and entered in :cpy-file:`Lib/opcode.py`, +you must also enter it into :cpy-file:`Doc/library/dis.rst`, and regenerate +:cpy-file:`Include/opcode.h` and :cpy-file:`Python/opcode_targets.h` by running ``make regen-opcode regen-opcode-targets``. With a new bytecode you must also change what is called the magic number for .pyc files. The variable ``MAGIC_NUMBER`` in -:file:`Lib/importlib/_bootstrap_external.py` contains the number. +:cpy-file:`Lib/importlib/_bootstrap_external.py` contains the number. Changing this number will lead to all .pyc files with the old ``MAGIC_NUMBER`` to be recompiled by the interpreter on import. Whenever ``MAGIC_NUMBER`` is -changed, the ranges in the ``magic_values`` array in :file:`PC/launcher.c` -must also be updated. Changes to :file:`Lib/importlib/_bootstrap_external.py` +changed, the ranges in the ``magic_values`` array in :cpy-file:`PC/launcher.c` +must also be updated. Changes to :cpy-file:`Lib/importlib/_bootstrap_external.py` will take effect only after running ``make regen-importlib``. Running this -command before adding the new bytecode target to :file:`Python/ceval.c` will +command before adding the new bytecode target to :cpy-file:`Python/ceval.c` will result in an error. You should only run ``make regen-importlib`` after the new bytecode target has been added. @@ -483,13 +486,13 @@ bytecode target has been added. regenerate the required files without requiring additional arguments. Finally, you need to introduce the use of the new bytecode. Altering -:file:`Python/compile.c` and :file:`Python/ceval.c` will be the primary places -to change. You must add the case for a new opcode into the 'switch' -statement in the ``stack_effect()`` function in :file:`Python/compile.c`. +:cpy-file:`Python/compile.c` and :cpy-file:`Python/ceval.c` will be the primary +places to change. You must add the case for a new opcode into the 'switch' +statement in the ``stack_effect()`` function in :cpy-file:`Python/compile.c`. If the new opcode has a jump target, you will need to update macros and -'switch' statements in :file:`Python/peephole.c`. If it affects a control +'switch' statements in :cpy-file:`Python/peephole.c`. If it affects a control flow or the block stack, you may have to update the ``frame_setlineno()`` -function in :file:`Objects/frameobject.c`. :file:`Lib/dis.py` may need +function in :cpy-file:`Objects/frameobject.c`. :cpy-file:`Lib/dis.py` may need an update if the new opcode interprets its argument in a special way (like ``FORMAT_VALUE`` or ``MAKE_FUNCTION``). @@ -511,9 +514,9 @@ Code Objects ============ The result of ``PyAST_CompileObject()`` is a ``PyCodeObject`` which is defined in -:file:`Include/code.h`. And with that you now have executable Python bytecode! +:cpy-file:`Include/code.h`. And with that you now have executable Python bytecode! -The code objects (byte code) are executed in :file:`Python/ceval.c`. This file +The code objects (byte code) are executed in :cpy-file:`Python/ceval.c`. This file will also need a new case statement for the new opcode in the big switch statement in ``_PyEval_EvalFrameDefault()``. @@ -532,12 +535,12 @@ Important Files asdl_c.py "Generate C code from an ASDL description." Generates - :file:`Python/Python-ast.c` and :file:`Include/Internal/pycore_ast.h`. + :cpy-file:`Python/Python-ast.c` and :cpy-file:`Include/internal/pycore_ast.h`. parser.c The new PEG parser introduced in Python 3.9. - Generated by :file:`Tools/peg_generator/pegen/c_generator.py` - from the grammar :file:`Grammar/python.gram`. Creates the AST from + Generated by :cpy-file:`Tools/peg_generator/pegen/c_generator.py` + from the grammar :cpy-file:`Grammar/python.gram`. Creates the AST from source code. Rule functions for their corresponding production rules are found here. @@ -547,12 +550,12 @@ Important Files pegen.c Contains helper functions which are used by functions in - :file:`Parser/parser.c` to construct the AST. Also contains helper + :cpy-file:`Parser/parser.c` to construct the AST. Also contains helper functions which help raise better error messages when parsing source code. pegen.h - Header file for the corresponding :file:`Parser/pegen.c`. Also contains + Header file for the corresponding :cpy-file:`Parser/pegen.c`. Also contains definitions of the ``Parser`` and ``Token`` structs. + Python/ @@ -560,15 +563,17 @@ Important Files Python-ast.c Creates C structs corresponding to the ASDL types. Also contains code for marshalling AST nodes (core ASDL types have - marshalling code in :file:`asdl.c`). "File automatically generated by - :file:`Parser/asdl_c.py`". This file must be committed separately - after every grammar change is committed since the ``__version__`` - value is set to the latest grammar change revision number. + marshalling code in :cpy-file:`Python/asdl.c`). "File automatically + generated by :cpy-file:`Parser/asdl_c.py`". This file must be + committed separately after every grammar change is committed since + the ``__version__`` value is set to the latest grammar change + revision number. asdl.c Contains code to handle the ASDL sequence type. Also has code to handle marshalling the core ASDL types, such as number and - identifier. Used by :file:`Python-ast.c` for marshalling AST nodes. + identifier. Used by :cpy-file:`Python/Python-ast.c` for marshalling + AST nodes. ast.c Used for validating the AST. @@ -599,46 +604,46 @@ Important Files Helpers for generating bytecode. opcode_targets.h - One of the files that must be modified if :file:`Lib/opcode.py` is. + One of the files that must be modified if :cpy-file:`Lib/opcode.py` is. + Include/ code.h - Header file for :file:`Objects/codeobject.c`; contains definition of + Header file for :cpy-file:`Objects/codeobject.c`; contains definition of ``PyCodeObject``. opcode.h - One of the files that must be modified if :file:`Lib/opcode.py` is. + One of the files that must be modified if :cpy-file:`Lib/opcode.py` is. - + Internal/ + + internal/ pycore_ast.h Contains the actual definitions of the C structs as generated by - :file:`Python/Python-ast.c`. - "Automatically generated by :file:`Parser/asdl_c.py`". + :cpy-file:`Python/Python-ast.c`. + "Automatically generated by :cpy-file:`Parser/asdl_c.py`". pycore_asdl.h - Header for the corresponding :file:`Python/ast.c` + Header for the corresponding :cpy-file:`Python/ast.c` pycore_ast.h - Declares ``_PyAST_Validate()`` external (from :file:`Python/ast.c`). + Declares ``_PyAST_Validate()`` external (from :cpy-file:`Python/ast.c`). pycore_symtable.h - Header for :file:`Python/symtable.c`. ``struct symtable`` and + Header for :cpy-file:`Python/symtable.c`. ``struct symtable`` and ``PySTEntryObject`` are defined here. pycore_parser.h - Header for the corresponding :file:`Parser/peg_api.c`. + Header for the corresponding :cpy-file:`Parser/peg_api.c`. pycore_pyarena.h - Header file for the corresponding :file:`Python/pyarena.c`. + Header file for the corresponding :cpy-file:`Python/pyarena.c`. + Objects/ codeobject.c Contains PyCodeObject-related code (originally in - :file:`Python/compile.c`). + :cpy-file:`Python/compile.c`). frameobject.c Contains the ``frame_setlineno()`` function which should determine diff --git a/internals/exploring.rst b/internals/exploring.rst index f27c150c0..b049159af 100644 --- a/internals/exploring.rst +++ b/internals/exploring.rst @@ -32,21 +32,21 @@ For builtin types, the typical layout is: * :file:`Objects/{}object.c` * :file:`Lib/test/test_{}.py` -* :file:`Doc/library/stdtypes.rst` +* :cpy-file:`Doc/library/stdtypes.rst` For builtin functions, the typical layout is: -* :file:`Python/bltinmodule.c` -* :file:`Lib/test/test_builtin.py` -* :file:`Doc/library/functions.rst` +* :cpy-file:`Python/bltinmodule.c` +* :cpy-file:`Lib/test/test_builtin.py` +* :cpy-file:`Doc/library/functions.rst` Some exceptions: -* builtin type ``int`` is at :file:`Objects/longobject.c` -* builtin type ``str`` is at :file:`Objects/unicodeobject.c` -* builtin module ``sys`` is at :file:`Python/sysmodule.c` -* builtin module ``marshal`` is at :file:`Python/marshal.c` -* Windows-only module ``winreg`` is at :file:`PC/winreg.c` +* builtin type ``int`` is at :cpy-file:`Objects/longobject.c` +* builtin type ``str`` is at :cpy-file:`Objects/unicodeobject.c` +* builtin module ``sys`` is at :cpy-file:`Python/sysmodule.c` +* builtin module ``marshal`` is at :cpy-file:`Python/marshal.c` +* Windows-only module ``winreg`` is at :cpy-file:`PC/winreg.c` Additional References From adc64917a7c34d9d299720f3f05a417a6841d097 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 11 Dec 2022 09:28:35 +0200 Subject: [PATCH 019/538] Ignore broken links and allow redirects (#1005) --- conf.py | 53 +++++++++++++++++----- getting-started/pull-request-lifecycle.rst | 2 +- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/conf.py b/conf.py index df7dfbaff..c899822f8 100644 --- a/conf.py +++ b/conf.py @@ -44,6 +44,30 @@ # Set to '' to prevent appending "documentation" to the site title html_title = "" +linkcheck_allowed_redirects = { + # Edit page + r"https://docs.google.com/document/d/.*/": r"https://docs.google.com/document/d/.*/edit", + # Canonical + r"https://docs.python.org/": r"https://docs.python.org/3/", + # Translations with country codes + r"https://docs.python.org/[a-z-]+/": r"https://docs.python.org/[a-z-]+/3/", + # Personal /my/ links redirect to login page + r"https://discuss.python.org/my/.*": r"https://discuss.python.org/login-preferences", + # Login page + r"https://github.com/python/core-workflow/issues/new.*": r"https://github.com/login.*", + # Archive redirect + r"https://github.com/python/cpython/archive/main.zip": r"https://codeload.github.com/python/cpython/zip/refs/heads/main", + # Blob to tree + r"https://github.com/python/cpython/blob/.*": r"https://github.com/python/cpython/tree/.*", + # HackMD shortcuts + r"https://hackmd.io/s/.*": r"https://hackmd.io/@.*", + # Read the Docs + r"https://virtualenv.pypa.io/": r"https://virtualenv.pypa.io/en/latest/", + r"https://www.sphinx-doc.org/": r"https://www.sphinx-doc.org/en/master/", + # Cookie consent + r"https://www.youtube.com/playlist.*": r"https://consent.youtube.com/ml.*", +} + # ignore linkcheck anchors for /#/$ANCHOR since it is used for # dynamic pages such as http://buildbot.python.org/all/#/console # http://www.sphinx-doc.org/en/stable/config.html?highlight=linkcheck#confval-linkcheck_anchors_ignore @@ -51,6 +75,24 @@ # match any anchor that starts with a '/' since this is an invalid HTML anchor r'\/.*', ] + +linkcheck_ignore = [ + # The voters repo is private and appears as a 404 + 'https://github.com/python/voters/', + # The python-core team link is private, redirects to login + 'https://github.com/orgs/python/teams/python-core', + # The Discourse groups are private unless you are logged in + 'https://discuss.python.org/groups/staff', + 'https://discuss.python.org/groups/moderators', + 'https://discuss.python.org/groups/admins', + # The crawler gets "Anchor not found" for GitHub anchors + r'https://github.com.+?#L\d+', + r'https://github.com/cli/cli#installation', + r'https://github.com/github/renaming#renaming-existing-branches', + # Discord doesn't allow robot crawlers: "403 Client Error: Forbidden" + r'https://support.discord.com/hc/en-us/articles/219070107-Server-Nicknames', +] + rediraffe_redirects = { "clang.rst": "advanced-tools/clang.rst", "coverity.rst": "advanced-tools/coverity.rst", @@ -90,17 +132,6 @@ "triaging.rst": "triage/triaging.rst", } -linkcheck_ignore = [ - # The voters repo is private and appears as a 404 - 'https://github.com/python/voters/', - # The python-core team link is private, redirects to login - 'https://github.com/orgs/python/teams/python-core', - # The Discourse groups are private unless you are logged in - 'https://discuss.python.org/groups/staff', - 'https://discuss.python.org/groups/moderators', - 'https://discuss.python.org/groups/admins', -] - intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), } diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index bb685e21b..e6be00c29 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -343,7 +343,7 @@ Here are the steps needed in order to sign the CLA: .. _PSF license: https://docs.python.org/dev/license.html#terms-and-conditions-for-accessing-or-otherwise-using-python .. _contributor agreement: https://www.python.org/psf/contrib/ .. _contributor form: https://www.python.org/psf/contrib/contrib-form/ -.. _Python Software Foundation: https://www.python.org/psf/ +.. _Python Software Foundation: https://www.python.org/psf-landing/ Submitting From 40955c4637b108821dea3eb8d46781868c5d0327 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 15 Dec 2022 09:31:25 +0200 Subject: [PATCH 020/538] Remove old Mac OS X (10.0-10.7) and OS X (10.8-10.11) info (#1006) * Remove old Mac OS X (10.0-10.7) and OS X (10.8-10.11) info * Change to Unix to follow our style guide https://devguide.python.org/documentation/style-guide/\#capitalization * List from first version auto dev tools were introduced Co-authored-by: C.A.M. Gerlach Co-authored-by: C.A.M. Gerlach --- getting-started/setup-building.rst | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index db6f3a17b..62a314643 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -145,7 +145,7 @@ checks that one should not skip. .. _unix-compiling: -UNIX +Unix ---- The core CPython interpreter only needs a C compiler to be built, @@ -334,7 +334,7 @@ extensions are already included and built automatically. Linux ----- -For UNIX based systems, we try to use system libraries whenever available. +For Unix-based systems, we try to use system libraries whenever available. This means optional components will only build if the relevant system headers are available. The best way to obtain the appropriate headers will vary by distribution, but the appropriate commands for some popular distributions @@ -385,12 +385,13 @@ their dependencies:: lzma lzma-dev tk-dev uuid-dev zlib1g-dev +.. _macOS and OS X: .. _macOS: -macOS and OS X --------------- +macOS +----- -For **macOS systems** (versions 10.12+) and **OS X 10.9 and later**, +For **macOS systems** (versions 10.9+), the Developer Tools can be downloaded and installed automatically; you do not need to download the complete Xcode application. @@ -401,21 +402,11 @@ If necessary, run the following:: This will also ensure that the system header files are installed into ``/usr/include``. -On **Mac OS X systems** (versions 10.0 - 10.7) and **OS X 10.8**, use the C -compiler and other development utilities provided by Apple's Xcode Developer -Tools. The Developer Tools are not shipped with Mac OS X. - -For these **older releases (versions 10.0 - 10.8)**, you will need to download either the -correct version of the Command Line Tools, if available, or install them from the -full Xcode app or package for that OS X release. Older versions may be -available either as a no-cost download through Apple's App Store or from -`the Apple Developer web site `_. - .. _Homebrew: https://brew.sh .. _MacPorts: https://www.macports.org -Also note that OS X does not include several libraries used by the Python +Also note that macOS does not include several libraries used by the Python standard library, including ``libzma``, so expect to see some extension module build failures unless you install local copies of them. As of OS X 10.11, Apple no longer provides header files for the deprecated system version of @@ -466,10 +457,10 @@ and ``make``:: $ make -s -j2 There will sometimes be optional modules added for a new release which -won't yet be identified in the OS level build dependencies. In those cases, +won't yet be identified in the OS-level build dependencies. In those cases, just ask for assistance on the core-mentorship list. -Explaining how to build optional dependencies on a UNIX based system without +Explaining how to build optional dependencies on a Unix-based system without root access is beyond the scope of this guide. For more details on various options and considerations for building, refer From e0fa2bd9a127c39b9cefbf2daabbb1b107fd5d1f Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Thu, 15 Dec 2022 10:07:07 -0700 Subject: [PATCH 021/538] Reformat "Important Files" section in `compiler.rst` (#1004) * Reformat the "Important file" section. * More reformatting. --- internals/compiler.rst | 180 +++++++++++++++++------------------------ 1 file changed, 76 insertions(+), 104 deletions(-) diff --git a/internals/compiler.rst b/internals/compiler.rst index 7b5df7b87..2785aab51 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -524,140 +524,112 @@ statement in ``_PyEval_EvalFrameDefault()``. Important Files =============== -+ Parser/ +* :cpy-file:`Parser/` + * :cpy-file:`Parser/Python.asdl`: ASDL syntax file. - Python.asdl - ASDL syntax file + * :cpy-file:`Parser/asdl.py`: Parser for ASDL definition files. + Reads in an ASDL description and parses it into an AST that describes it. - asdl.py - Parser for ASDL definition files. Reads in an ASDL description - and parses it into an AST that describes it. + * :cpy-file:`Parser/asdl_c.py`: Generate C code from an ASDL description. + Generates :cpy-file:`Python/Python-ast.c` and + :cpy-file:`Include/internal/pycore_ast.h`. - asdl_c.py - "Generate C code from an ASDL description." Generates - :cpy-file:`Python/Python-ast.c` and :cpy-file:`Include/internal/pycore_ast.h`. + * :cpy-file:`Parser/parser.c`: The new PEG parser introduced in Python 3.9. + Generated by :cpy-file:`Tools/peg_generator/pegen/c_generator.py` + from the grammar :cpy-file:`Grammar/python.gram`. Creates the AST from + source code. Rule functions for their corresponding production rules + are found here. - parser.c - The new PEG parser introduced in Python 3.9. - Generated by :cpy-file:`Tools/peg_generator/pegen/c_generator.py` - from the grammar :cpy-file:`Grammar/python.gram`. Creates the AST from - source code. Rule functions for their corresponding production rules - are found here. + * :cpy-file:`Parser/peg_api.c`: Contains high-level functions which are + used by the interpreter to create an AST from source code. - peg_api.c - Contains high-level functions which are used by the interpreter to - create an AST from source code . + * :cpy-file:`Parser/pegen.c`: Contains helper functions which are used + by functions in :cpy-file:`Parser/parser.c` to construct the AST. + Also contains helper functions which help raise better error messages + when parsing source code. - pegen.c - Contains helper functions which are used by functions in - :cpy-file:`Parser/parser.c` to construct the AST. Also contains helper - functions which help raise better error messages when parsing source - code. + * :cpy-file:`Parser/pegen.h`: Header file for the corresponding + :cpy-file:`Parser/pegen.c`. Also contains definitions of the ``Parser`` + and ``Token`` structs. - pegen.h - Header file for the corresponding :cpy-file:`Parser/pegen.c`. Also contains - definitions of the ``Parser`` and ``Token`` structs. +* :cpy-file:`Python/` + * :cpy-file:`Python/Python-ast.c`: Creates C structs corresponding to + the ASDL types. Also contains code for marshalling AST nodes (core + ASDL types have marshalling code in :cpy-file:`Python/asdl.c`). + "File automatically generated by :cpy-file:`Parser/asdl_c.py`". + This file must be committed separately after every grammar change + is committed since the ``__version__`` value is set to the latest + grammar change revision number. -+ Python/ + * :cpy-file:`Python/asdl.c`: Contains code to handle the ASDL sequence type. + Also has code to handle marshalling the core ASDL types, such as number + and identifier. Used by :cpy-file:`Python/Python-ast.c` for marshalling + AST nodes. - Python-ast.c - Creates C structs corresponding to the ASDL types. Also - contains code for marshalling AST nodes (core ASDL types have - marshalling code in :cpy-file:`Python/asdl.c`). "File automatically - generated by :cpy-file:`Parser/asdl_c.py`". This file must be - committed separately after every grammar change is committed since - the ``__version__`` value is set to the latest grammar change - revision number. + * :cpy-file:`Python/ast.c`: Used for validating the AST. - asdl.c - Contains code to handle the ASDL sequence type. Also has code - to handle marshalling the core ASDL types, such as number and - identifier. Used by :cpy-file:`Python/Python-ast.c` for marshalling - AST nodes. + * :cpy-file:`Python/ast_opt.c`: Optimizes the AST. - ast.c - Used for validating the AST. + * :cpy-file:`Python/ast_unparse.c`: Converts the AST expression node + back into a string (for string annotations). - ast_opt.c - Optimizes the AST. + * :cpy-file:`Python/ceval.c`: Executes byte code (aka, eval loop). - ast_unparse.c - Converts the AST expression node back into a string - (for string annotations). + * :cpy-file:`Python/compile.c`: Emits bytecode based on the AST. - ceval.c - Executes byte code (aka, eval loop). + * :cpy-file:`Python/symtable.c`: Generates a symbol table from AST. - compile.c - Emits bytecode based on the AST. + * :cpy-file:`Python/peephole.c`: Optimizes the bytecode. - symtable.c - Generates a symbol table from AST. + * :cpy-file:`Python/pyarena.c`: Implementation of the arena memory manager. - peephole.c - Optimizes the bytecode. + * :cpy-file:`Python/wordcode_helpers.h`: Helpers for generating bytecode. - pyarena.c - Implementation of the arena memory manager. + * :cpy-file:`Python/opcode_targets.h`: One of the files that must be + modified if :cpy-file:`Lib/opcode.py` is. - wordcode_helpers.h - Helpers for generating bytecode. +* :cpy-file:`Include/` + * :cpy-file:`Include/code.h`: Header file for :cpy-file:`Objects/codeobject.c`; + contains definition of ``PyCodeObject``. - opcode_targets.h - One of the files that must be modified if :cpy-file:`Lib/opcode.py` is. + * :cpy-file:`Include/opcode.h`: One of the files that must be modified if + :cpy-file:`Lib/opcode.py` is. -+ Include/ + * :cpy-file:`Include/internal/pycore_ast.h`: Contains the actual definitions + of the C structs as generated by :cpy-file:`Python/Python-ast.c`. + "Automatically generated by :cpy-file:`Parser/asdl_c.py`". - code.h - Header file for :cpy-file:`Objects/codeobject.c`; contains definition of - ``PyCodeObject``. + * :cpy-file:`Include/internal/pycore_asdl.h`: Header for the corresponding + :cpy-file:`Python/ast.c`. - opcode.h - One of the files that must be modified if :cpy-file:`Lib/opcode.py` is. + * :cpy-file:`Include/internal/pycore_ast.h`: Declares ``_PyAST_Validate()`` + external (from :cpy-file:`Python/ast.c`). - + internal/ + * :cpy-file:`Include/internal/pycore_symtable.h`: Header for + :cpy-file:`Python/symtable.c`. ``struct symtable`` and ``PySTEntryObject`` + are defined here. - pycore_ast.h - Contains the actual definitions of the C structs as generated by - :cpy-file:`Python/Python-ast.c`. - "Automatically generated by :cpy-file:`Parser/asdl_c.py`". + * :cpy-file:`Include/internal/pycore_parser.h`: Header for the + corresponding :cpy-file:`Parser/peg_api.c`. - pycore_asdl.h - Header for the corresponding :cpy-file:`Python/ast.c` + * :cpy-file:`Include/internal/pycore_pyarena.h`: Header file for the + corresponding :cpy-file:`Python/pyarena.c`. - pycore_ast.h - Declares ``_PyAST_Validate()`` external (from :cpy-file:`Python/ast.c`). +* :cpy-file:`Objects/` + * :cpy-file:`Objects/codeobject.c`: Contains PyCodeObject-related code + (originally in :cpy-file:`Python/compile.c`). - pycore_symtable.h - Header for :cpy-file:`Python/symtable.c`. ``struct symtable`` and - ``PySTEntryObject`` are defined here. + * :cpy-file:`Objects/frameobject.c`: Contains the ``frame_setlineno()`` + function which should determine whether it is allowed to make a jump + between two points in a bytecode. - pycore_parser.h - Header for the corresponding :cpy-file:`Parser/peg_api.c`. +* :cpy-file:`Lib/` + * :cpy-file:`Lib/opcode.py`: Master list of bytecode; if this file is + modified you must modify several other files accordingly + (see "`Introducing New Bytecode`_") - pycore_pyarena.h - Header file for the corresponding :cpy-file:`Python/pyarena.c`. - - -+ Objects/ - - codeobject.c - Contains PyCodeObject-related code (originally in - :cpy-file:`Python/compile.c`). - - frameobject.c - Contains the ``frame_setlineno()`` function which should determine - whether it is allowed to make a jump between two points in a bytecode. - -+ Lib/ - - opcode.py - Master list of bytecode; if this file is modified you must modify - several other files accordingly (see "`Introducing New Bytecode`_") - - importlib/_bootstrap_external.py - Home of the magic number (named ``MAGIC_NUMBER``) for bytecode - versioning. + * :cpy-file:`Lib/importlib/_bootstrap_external.py`: Home of the magic number + (named ``MAGIC_NUMBER``) for bytecode versioning. Known Compiler-related Experiments From 949c9dd09290724ea9b94c035ce2a07a6202a5cc Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Sat, 17 Dec 2022 17:19:42 -0800 Subject: [PATCH 022/538] Fix some typos (#1007) --- getting-started/setup-building.rst | 4 ++-- triage/triage-team.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 62a314643..60d0b93d5 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -98,7 +98,7 @@ You will only need to execute these steps once per machine: upstream For more information about these commands see -:ref:`Git Bootcamp and Cheat Sheat `. +:ref:`Git Bootcamp and Cheat Sheet `. If you did everything correctly, you should now have a copy of the code in the ``cpython`` directory and two remotes that refer to your own GitHub fork @@ -300,7 +300,7 @@ from the dropdown menus in the toolbar. If you need to change the build configuration or platform, build once with the ``build.bat`` script set to those options first before building with them in VS to ensure all files are rebuilt properly, - or you may encouter errors when loading modules that were not rebuilt. + or you may encounter errors when loading modules that were not rebuilt. Avoid selecting the ``PGInstrument`` and ``PGUpdate`` configurations, as these are intended for PGO builds and not for normal development. diff --git a/triage/triage-team.rst b/triage/triage-team.rst index 6bd530c05..c901d0d52 100644 --- a/triage/triage-team.rst +++ b/triage/triage-team.rst @@ -90,7 +90,7 @@ 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 devloper decides you are ready to gain the extra privileges on the +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. From c47a32a04fc822573f3614bebdc3b98415ebbfc9 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 22 Dec 2022 12:00:13 -0800 Subject: [PATCH 023/538] Add Shantanu Jain to the developer log --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 95d55c00f..f6ffffd0e 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Shantanu Jain,hauntsaninja,2022-12-19,, Kumar Aditya,kumaraditya303,2022-11-21,, Hugo van Kemenade,hugovk,2022-11-21,, Alex Waygood,AlexWaygood,2022-10-18,, From 353d41c2a9c12807d05f2c93b3618cee89d23341 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 23 Dec 2022 17:33:33 +0200 Subject: [PATCH 024/538] Fix a broken link (#1009) --- advanced-tools/gdb.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/advanced-tools/gdb.rst b/advanced-tools/gdb.rst index 1ce4049f4..cf84085d2 100644 --- a/advanced-tools/gdb.rst +++ b/advanced-tools/gdb.rst @@ -357,7 +357,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 From 8d36547ac60b51645c8cfa5d91d8346b4c1147fb Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 25 Dec 2022 01:03:36 -0500 Subject: [PATCH 025/538] Refine 'gaining commit privileges'. (#969) * Refine 'gaining commit privileges'. - Allow the audience to be anybody (not just an individual seeking commit privileges). Avoids use of second-person language. - Provide guidance for all involved. - Refer to the various actors directly, avoiding passive language. Use 'candidate', 'submitter', and 'approver' to represent the key actors. - Move the "cross-post" action into step 1 to indicate better the temporal positition of the action. - Summarize the confirmation criterion (2/3 vote) rather than make the reader go to the PEP, which basically indicates 2/3 vote. - Include the steering council email, because the submitter may not know it. - Normalize the initial approver actions. Previously, council was directed to be "asking for ... a reminder about the Code of Conduct and to report issues to the PSF WG". Now it's two requests and a reminder. - Hyperlink "python/voters" instead of the full URL. * Combine steps Co-authored-by: Ezio Melotti * Consolidate steps 5-8 into one. Co-authored-by: Ezio Melotti * Update number. Co-authored-by: Ezio Melotti * Link python-committers mailing list. Co-authored-by: Hugo van Kemenade * Remove unnecessary hostname. Co-authored-by: Hugo van Kemenade * Move cross-post instruction to step 1. * Auto number * Fix syntax. * Apply suggestions from code review Co-authored-by: C.A.M. Gerlach Co-authored-by: Ezio Melotti Co-authored-by: Hugo van Kemenade Co-authored-by: C.A.M. Gerlach --- core-developers/become-core-developer.rst | 54 ++++++++++++----------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index 1c8ef74e7..9887ffcf9 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -25,37 +25,39 @@ an official offer. How core developers come to that agreement are outlined in Gaining Commit Privileges ========================= -The steps to gaining commit privileges are: +After a candidate has demonstrated consistent contributions, commit privileges +are granted through these steps: -1. A core developer starts a poll in the - `Committers category`_ on the `Python Discourse`_ (``discuss.python.org``) +#. A core developer (submitter, usually the mentor) starts a poll in the + `Committers category`_ on the `Python Discourse`_ and cross-posts it to + the `python-committers mailing list`_. - Open for 7 days - Results shown upon close -2. The poll is announced on the `python-committers mailing list`_ -3. Wait for the poll to close and see if the results confirm your membership - as per the voting results required by :pep:`13` -4. The person who nominated you emails the steering council with your email - address and a request that the council either accept or reject the proposed - membership -5. Assuming the steering council does not object, a member of the council will - email you asking for: - - - Account details as required by - 🔒 https://github.com/python/voters/ - - Your preferred email address to - subscribe to the python-committers mailing list with - - A reminder about the `Code of Conduct`_ and to report issues to the PSF - Conduct WG - -6. Once you have provided the pertinent details, your various new privileges - will be turned on -7. Your details will be added to 🔒 https://github.com/python/voters/ -8. They will update the devguide to publicly list your team membership at - :ref:`developers` -9. An announcement email by the steering council member handling your new - membership will be sent to the Committers Discourse category +#. If the candidate receives at least two-thirds positive votes when the poll closes + (as per :pep:`13`), the submitter `emails the steering council + `_ with the candidate's email address + requesting that the council either accept or reject the proposed membership. + +#. Assuming the steering council does not object, a member of the council or delegate + (approver) will email the candidate: + + - A request for account details as required by + `🔒 python/voters `_ + - A request for the committer's preferred address for subscription to + the `python-committers mailing list`_ + - A reminder about the `Code of Conduct`_ and guidance on reporting issues + to the PSF Conduct WG + +#. Once the candidate has provided the pertinent details, the approver will: + + - enable the various new privileges; + - add the new committer's details to + `🔒 python/voters `_; + - update the devguide to publicly list the new committer's team membership + at :ref:`developers`; + - send an announcement email to the Committers Discourse category. .. _Code of Conduct: https://www.python.org/psf/conduct/ .. _Committers category: https://discuss.python.org/c/committers/5 From a4225c8ee130599f60a829a81ee4ddeb89af0cd2 Mon Sep 17 00:00:00 2001 From: Ege Akman Date: Sun, 25 Dec 2022 09:04:29 +0300 Subject: [PATCH 026/538] Update links and add GitHub Pages (python-docs-tr) (#1008) --- documentation/translating.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index d5fffa0fa..c1f0c5f70 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -74,7 +74,7 @@ in production; others are works in progress. | (zh-tw) | Josix Wang | | +-----------------+-------------------------------+----------------------------+ | Turkish (tr) | `Ege Akman (@egeakman) | `GitHub `_ | -| | `_ | | +| | `_ | `GH-Pages `_ | +-----------------+-------------------------------+----------------------------+ | Ukrainian (uk) | `Dmytro Kazanzhy (@kazanzhy) | `GitHub `_ | | | `_ | `Translations `_ | @@ -91,7 +91,7 @@ in production; others are works in progress. .. _gh_osdotsystem: https://github.com/Abdur-rahmaanJ .. _gh_zhsj: https://github.com/zhsj .. _gh_mattwang44: https://github.com/mattwang44 -.. _email_egeakman: mailto:egeakmanegeakman@hotmail.com +.. _gh_egeakman: https://github.com/egeakman .. _email_garade: mailto:garade@pm.me .. _email_kazanzhy: mailto:dkazanzhy@gmail.com .. _chat_pt_br: https://t.me/pybr_i18n @@ -100,6 +100,7 @@ in production; others are works in progress. .. _doc_pl: https://docs.python.org/pl/ .. _doc_zh_cn: https://docs.python.org/zh-cn/ .. _doc_zh_tw: https://docs.python.org/zh-tw/ +.. _gh_pages_tr: https://python.github.io/python-docs-tr/ .. _github_ar: https://github.com/Abdur-rahmaanJ/python-docs-ar .. _github_bn_in: https://github.com/python/python-docs-bn-in .. _github_es: https://github.com/python/python-docs-es @@ -113,7 +114,7 @@ in production; others are works in progress. .. _github_mr: https://github.com/sanketgarade/python-doc-mr .. _github_pl: https://github.com/python/python-docs-pl .. _github_pt_br: https://github.com/python/python-docs-pt-br -.. _github_tr: https://github.com/python-docs-tr/python-docs-tr +.. _github_tr: https://github.com/python/python-docs-tr .. _github_uk: https://github.com/python/python-docs-uk .. _github_zh_cn: https://github.com/python/python-docs-zh-cn .. _github_zh_tw: https://github.com/python/python-docs-zh-tw From cfe1bf02d0e0e3538aeda9b8d4cc5a52ebfe2438 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 25 Dec 2022 10:28:28 +0200 Subject: [PATCH 027/538] Add edit button (#1010) --- conf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/conf.py b/conf.py index c899822f8..29563db50 100644 --- a/conf.py +++ b/conf.py @@ -33,7 +33,10 @@ ] html_theme = 'furo' -html_theme_options = {} +html_theme_options = { + "source_repository": "https://github.com/python/devguide", + "source_branch": "main", +} html_static_path = ['_static'] html_css_files = [ 'devguide_overrides.css', From c0e1638018fa527d644bfa1a54eb9f85ece94fd0 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Sun, 25 Dec 2022 15:07:27 -0700 Subject: [PATCH 028/538] Fix remaining broken links. (#1013) Co-authored-by: C.A.M. Gerlach closes https://github.com/python/devguide/issues/681 --- developer-workflow/grammar.rst | 15 ++++++++------- internals/compiler.rst | 13 +++++-------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/developer-workflow/grammar.rst b/developer-workflow/grammar.rst index 7d6b40993..2ba18ec22 100644 --- a/developer-workflow/grammar.rst +++ b/developer-workflow/grammar.rst @@ -28,18 +28,19 @@ Note: sometimes things mysteriously don't work. Before giving up, try ``make cl * :cpy-file:`Grammar/python.gram`: The grammar, with actions that build AST nodes. After changing it, run ``make regen-pegen`` (or ``build.bat --regen`` on Windows), to regenerate :cpy-file:`Parser/parser.c`. - (This runs Python's parser generator, ``Tools/peg_generator``). + (This runs Python's parser generator, :cpy-file:`Tools/peg_generator`). * :cpy-file:`Grammar/Tokens` is a place for adding new token types. After - changing it, run ``make regen-token`` to regenerate :cpy-file:`Include/token.h`, - :cpy-file:`Parser/token.c`, :cpy-file:`Lib/token.py` and - :cpy-file:`Doc/library/token-list.inc`. If you change both ``python.gram`` - and ``Tokens``, run ``make regen-token`` before ``make regen-pegen``. + changing it, run ``make regen-token`` to regenerate + :cpy-file:`Include/internal/pycore_token.h`, :cpy-file:`Parser/token.c`, + :cpy-file:`Lib/token.py` and :cpy-file:`Doc/library/token-list.inc`. + If you change both ``python.gram`` and ``Tokens``, + run ``make regen-token`` before ``make regen-pegen``. On Windows, ``build.bat --regen`` will regenerate both at the same time. * :cpy-file:`Parser/Python.asdl` may need changes to match the grammar. - Then run ``make regen-ast`` to regenerate :cpy-file:`Include/Python-ast.h` - and :cpy-file:`Python/Python-ast.c`. + Then run ``make regen-ast`` to regenerate + :cpy-file:`Include/internal/pycore_ast.h` and :cpy-file:`Python/Python-ast.c`. * :cpy-file:`Parser/tokenizer.c` contains the tokenization code. This is where you would add a new type of comment or string literal, for example. diff --git a/internals/compiler.rst b/internals/compiler.rst index 2785aab51..a820ef260 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -490,7 +490,7 @@ Finally, you need to introduce the use of the new bytecode. Altering places to change. You must add the case for a new opcode into the 'switch' statement in the ``stack_effect()`` function in :cpy-file:`Python/compile.c`. If the new opcode has a jump target, you will need to update macros and -'switch' statements in :cpy-file:`Python/peephole.c`. If it affects a control +'switch' statements in :cpy-file:`Python/compile.c`. If it affects a control flow or the block stack, you may have to update the ``frame_setlineno()`` function in :cpy-file:`Objects/frameobject.c`. :cpy-file:`Lib/dis.py` may need an update if the new opcode interprets its argument in a special way (like @@ -514,7 +514,8 @@ Code Objects ============ The result of ``PyAST_CompileObject()`` is a ``PyCodeObject`` which is defined in -:cpy-file:`Include/code.h`. And with that you now have executable Python bytecode! +:cpy-file:`Include/cpython/code.h`. And with that you now have executable +Python bytecode! The code objects (byte code) are executed in :cpy-file:`Python/ceval.c`. This file will also need a new case statement for the new opcode in the big switch @@ -579,18 +580,14 @@ Important Files * :cpy-file:`Python/symtable.c`: Generates a symbol table from AST. - * :cpy-file:`Python/peephole.c`: Optimizes the bytecode. - * :cpy-file:`Python/pyarena.c`: Implementation of the arena memory manager. - * :cpy-file:`Python/wordcode_helpers.h`: Helpers for generating bytecode. - * :cpy-file:`Python/opcode_targets.h`: One of the files that must be modified if :cpy-file:`Lib/opcode.py` is. * :cpy-file:`Include/` - * :cpy-file:`Include/code.h`: Header file for :cpy-file:`Objects/codeobject.c`; - contains definition of ``PyCodeObject``. + * :cpy-file:`Include/cpython/code.h`: Header file for + :cpy-file:`Objects/codeobject.c`; contains definition of ``PyCodeObject``. * :cpy-file:`Include/opcode.h`: One of the files that must be modified if :cpy-file:`Lib/opcode.py` is. From 25d27c734c2a5f8c35cfb40db0385d69dbc03a12 Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Mon, 26 Dec 2022 19:28:47 -0300 Subject: [PATCH 029/538] Fix a ref markup syntax in markup.rst (#1014) * Fix a ref markup syntax in markup.rst * Add anchor for Additional Markup Constructors --- documentation/markup.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index 47172eb3b..45724a0fb 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -220,8 +220,8 @@ A directive is a generic block of explicit markup. Besides roles, it is one of the extension mechanisms of reST, and Sphinx makes heavy use of it. Basically, a directive consists of a name, arguments, options and content. (Keep -this terminology in mind, it is used in `:ref:`the next section -` describing custom +this terminology in mind, it is used in :ref:`the next section +` describing custom directives.) Looking at this example, :: @@ -287,6 +287,7 @@ There are some problems one commonly runs into while authoring reST documents: separated from the surrounding text by non-word characters, you have to use an escaped space to get around that. +.. _additional-markup-constructs: Additional Markup Constructs ============================ From fa2e8b0842172aa4a871ded92ad836a46b9dd4d0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 27 Dec 2022 18:44:23 +0200 Subject: [PATCH 030/538] Move 'moved to' link to the end (#1015) --- index.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/index.rst b/index.rst index 0ec2cfef9..7ed971adf 100644 --- a/index.rst +++ b/index.rst @@ -89,12 +89,6 @@ contributing to Python: * PEPs_ (Python Enhancement Proposals) * :ref:`gitbootcamp` -Status of Python branches -------------------------- - -Moved to :ref:`versions` - - .. _contributing: Contributing @@ -229,6 +223,11 @@ which includes all infrastructure used in the development of Python itself In general this means everyone is expected to be open, considerate, and respectful of others no matter what their position is within the project. +Status of Python branches +------------------------- + +Moved to :ref:`versions` + .. _contents: Full Table of Contents From d3099f1b625bcb97ddeebca0dcb41aa23385480e Mon Sep 17 00:00:00 2001 From: Ege Akman Date: Thu, 29 Dec 2022 10:48:41 +0300 Subject: [PATCH 031/538] Add Doc link to Turkish section (#1016) * Add Doc link to Turkish section * Add trailing `/` to URL. Co-authored-by: Ezio Melotti --- documentation/translating.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/translating.rst b/documentation/translating.rst index c1f0c5f70..19a8d72ec 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -75,6 +75,7 @@ in production; others are works in progress. +-----------------+-------------------------------+----------------------------+ | Turkish (tr) | `Ege Akman (@egeakman) | `GitHub `_ | | | `_ | `GH-Pages `_ | +| | | `Doc `_ | +-----------------+-------------------------------+----------------------------+ | Ukrainian (uk) | `Dmytro Kazanzhy (@kazanzhy) | `GitHub `_ | | | `_ | `Translations `_ | @@ -98,6 +99,7 @@ in production; others are works in progress. .. _doc_ja: https://docs.python.org/ja/ .. _doc_ko: https://docs.python.org/ko/ .. _doc_pl: https://docs.python.org/pl/ +.. _doc_tr: https://docs.python.org/tr/ .. _doc_zh_cn: https://docs.python.org/zh-cn/ .. _doc_zh_tw: https://docs.python.org/zh-tw/ .. _gh_pages_tr: https://python.github.io/python-docs-tr/ From 004d9a3e6c9362eeafe5a6f96fca312fde8faa1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jan 2023 09:50:35 +0200 Subject: [PATCH 032/538] Bump sphinx from 5.3.0 to 6.0.0 (#1017) Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 5.3.0 to 6.0.0. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v5.3.0...v6.0.0) --- updated-dependencies: - dependency-name: sphinx dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] 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 f0397b9c4..3370b57da 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Sphinx==5.3.0 +Sphinx==6.0.0 furo>=2022.6.4 sphinx-lint==0.6.7 sphinx_copybutton>=0.3.3 From ffc11002787029a4d7aeead50c7e79e97dd3a745 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Thu, 5 Jan 2023 14:04:34 -0800 Subject: [PATCH 033/538] Add hauntsaninja as tomllib maintainer (#1021) --- core-developers/experts.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index dc918ab58..4801d9df0 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -238,6 +238,7 @@ timeit tkinter gpolo^, serhiy-storchaka token tokenize meadori +tomllib hauntsaninja* trace abalkin traceback iritkatriel tracemalloc vstinner From 5f216af09b8b0d0e6c37df7f5da8640192aa2ea5 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 6 Jan 2023 09:48:06 -0800 Subject: [PATCH 034/538] Update `experts.rst` for Brett Cannon --- 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 4801d9df0..172107b57 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -317,7 +317,7 @@ Interest Area Maintainers ================== ========================================================== algorithms rhettinger* argument clinic larryhastings -ast/compiler benjaminp, brettcannon, 1st1, pablogsal, markshannon, isidentical, brandtbucher +ast/compiler benjaminp, 1st1, pablogsal, markshannon, isidentical, brandtbucher autoconf/makefiles Yhg1s* bsd issue tracker ezio-melotti @@ -325,7 +325,7 @@ buildbots zware, pablogsal bytecode benjaminp, 1st1, markshannon, brandtbucher context managers ncoghlan core workflow Mariatta, ezio-melotti, hugovk -coverity scan tiran, brettcannon, Yhg1s +coverity scan tiran, Yhg1s cryptography gpshead, dstufft data formats mdickinson database malemburg @@ -348,7 +348,7 @@ object model benjaminp, Yhg1s packaging tarekziade, malemburg, alexis^, merwok, dstufft, pfmoore pattern matching brandtbucher* peg parser gvanrossum, pablogsal, lysnikolaou -performance brettcannon, vstinner, serhiy-storchaka, 1st1, rhettinger, markshannon, brandtbucher +performance vstinner, serhiy-storchaka, 1st1, rhettinger, markshannon, brandtbucher pip ncoghlan, dstufft, pfmoore, Marcus.Smith^, pradyunsg py3 transition benjaminp release management tarekziade, malemburg, benjaminp, warsaw, From 2664a0020d4c65de3a4c94a0696e90a2508de26b Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Fri, 6 Jan 2023 19:44:43 +0000 Subject: [PATCH 035/538] Add barneygale to experts index (#1024) --- 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 172107b57..4bee9b6ef 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -169,7 +169,7 @@ os os.path serhiy-storchaka ossaudiodev parser benjaminp, pablogsal -pathlib +pathlib barneygale* pdb pickle avassalotti pickletools avassalotti From 7ec8be427f957d7ee84efa9581d883d35b26e760 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 10 Jan 2023 11:02:30 +0200 Subject: [PATCH 036/538] Helping with Documentation: Update old BPO info (#1025) Co-authored-by: C.A.M. Gerlach --- documentation/help-documenting.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/documentation/help-documenting.rst b/documentation/help-documenting.rst index c8e320ccd..0da669b35 100644 --- a/documentation/help-documenting.rst +++ b/documentation/help-documenting.rst @@ -37,10 +37,10 @@ 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 `docs@python.org `_ -mailing list. The `issue tracker`_ sends new documentation issues to this -mailing list, and, less frequently, the list receives some directly mailed bug -reports. The `docs-sig@python.org `_ -mailing list discusses the documentation toolchain, projects, and standards. +mailing list and the `Documentation category on the Python Discourse +`_, +where user issues are raised and documentation toolchain, projects, and standards +are discussed. Helping with documentation issues @@ -52,8 +52,9 @@ typos to unclear documentation and items lacking documentation. If you see a documentation issue that you would like to tackle, you can: -* check to see if there is a paperclip or `octocat`_ icon at the end of the - issue's title column. If there is, then someone has already created a pull +* check to see if there is pull request icon to the right of the issue's title, + or an open pull request listed under :guilabel:`Linked PRs` in the issue body. + If there is, then someone has already created a pull request for the issue. * leave a comment on the issue saying you are going to try and create a pull request and roughly how long you think you will take to do so (this allows From 333df12b0721f69c1071f894137e9cb5af7f5f48 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 15 Jan 2023 23:26:19 +0200 Subject: [PATCH 037/538] Make clear who can add labels on GitHub (#1032) --- triage/labels.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/triage/labels.rst b/triage/labels.rst index 6b8a33e8c..bcdd6bef5 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -5,7 +5,8 @@ GitHub Labels ============= -We're using labels on GitHub to categorize issues and pull requests. +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 `_. From 376def3198ad1441e5f75b1fa45d3efa3b9d8d4a Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Sun, 15 Jan 2023 21:51:28 +0000 Subject: [PATCH 038/538] Correct the description of generation thresholds in the gc docs (#1030) --- internals/garbage-collector.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index e79a74683..d76e72bcb 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -319,10 +319,15 @@ the same object survives another GC round in this new generation (generation 1) it will be moved to the last generation (generation 2) where it will be surveyed the least often. -Generations are collected when the number of objects that they contain reaches some -predefined threshold, which is unique for each generation and is lower the older -the generations are. These thresholds can be examined using the ``gc.get_threshold`` -function: +In order to decide when to run, the collector keeps track of the number of object +allocations and deallocations since the last collection. When the number of +allocations minus the number of deallocations exceeds ``threshold_0``, +collection starts. Initially only generation 0 is examined. If generation 0 has +been examined more than ``threshold_1`` times since generation 1 has been +examined, then generation 1 is examined as well. With generation 2, +things are a bit more complicated; see :ref:`gc-oldest-generation` for +more information. These thresholds can be examined using the +:func:`gc.get_threshold` function: .. code-block:: python @@ -369,6 +374,7 @@ specifically in a generation by calling ``gc.collect(generation=NUM)``. [..., <__main__.MyObj object at 0x7fbcc12a3400>, ...] +.. _gc-oldest-generation: Collecting the oldest generation -------------------------------- From 55b0c14bf1b39b502f4e1f89700a27cc88a98e62 Mon Sep 17 00:00:00 2001 From: EvanLai88 <95132480+EvanLai88@users.noreply.github.com> Date: Mon, 16 Jan 2023 12:08:06 +0800 Subject: [PATCH 039/538] Update `patchcheck` description (#1031) * Update path to patchcheck.py * Update path to reindent.py and clear deleted file * Link with `:cpy-file:` directly Co-authored-by: C.A.M. Gerlach Co-authored-by: C.A.M. Gerlach --- getting-started/pull-request-lifecycle.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index e6be00c29..de361d2a2 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -249,15 +249,14 @@ through the common patch generation checks. To run ``patchcheck``: .. code-block:: dosbatch - python.bat Tools\scripts\patchcheck.py + python.bat Tools\patchcheck\patchcheck.py The automated patch checklist runs through: * Are there any whitespace problems in Python files? - (using ``Tools/scripts/reindent.py``) + (using :cpy-file:`Tools/patchcheck/reindent.py`) * Are there any whitespace problems in C files? * Are there any whitespace problems in the documentation? - (using ``Tools/scripts/reindent-rst.py``) * Has the documentation been updated? * Has the test suite been updated? * Has an entry under ``Misc/NEWS.d/next`` been added? From 863f854a113fb8625029aba5046d2fa43abf8b57 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 16 Jan 2023 09:39:05 -0800 Subject: [PATCH 040/538] Start a chapter on 3.11 interpreter internals (#1028) Co-authored-by: C.A.M. Gerlach Co-authored-by: Hugo van Kemenade --- internals/index.rst | 1 + internals/interpreter.rst | 307 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 308 insertions(+) create mode 100644 internals/interpreter.rst diff --git a/internals/index.rst b/internals/index.rst index ce04c665c..161113560 100644 --- a/internals/index.rst +++ b/internals/index.rst @@ -8,4 +8,5 @@ CPython's Internals exploring parser compiler + interpreter garbage-collector diff --git a/internals/interpreter.rst b/internals/interpreter.rst new file mode 100644 index 000000000..5c5cfed03 --- /dev/null +++ b/internals/interpreter.rst @@ -0,0 +1,307 @@ +.. _interpreter: + +=============================== +The Bytecode Interpreter (3.11) +=============================== + +.. highlight:: c + +Preface +======= + +The CPython 3.11 bytecode interpreter (a.k.a. virtual machine) has a number of improvements over 3.10. +We describe the inner workings of the 3.11 interpreter here, with an emphasis on understanding not just the code but its design. +While the interpreter is forever evolving, and the 3.12 design will undoubtedly be different again, knowing the 3.11 design will help you understand future improvements to the interpreter. + +Introduction +============ + +The job of the bytecode interpreter, in :cpy-file:`Python/ceval.c`, is to execute Python code. +Its main input is a code object, although this is not a direct argument to the interpreter. +The interpreter is structured as a (recursive) function taking a thread state (``tstate``) and a stack frame (``frame``). +The function also takes an integer ``throwflag``, which is used by the implementation of ``generator.throw``. +It returns a new reference to a Python object (``PyObject *``) or an error indicator, ``NULL``. +Per :pep:`523`, this function is configurable by setting ``interp->eval_frame``; we describe only the default function, ``_PyEval_EvalFrameDefault()``. +(This function's signature has evolved and no longer matches what PEP 523 specifies; the thread state argument is added and the stack frame argument is no longer an object.) + +The interpreter finds the code object by looking in the stack frame (``frame->f_code``). +Various other items needed by the interpreter (e.g. globals and builtins) are also accessed via the stack frame. +The thread state stores exception information and a variety of other information, such as the recursion depth. +The thread state is also used to access per-interpreter state (``tstate->interp``) and per-runtime (i.e., truly global) state (``tstate->interp->runtime``). + +Note the slightly confusing terminology here. +"Interpreter" refers to the bytecode interpreter, a recursive function. +"Interpreter state" refers to state shared by threads, each of which may be running its own bytecode interpreter. +A single process may even host multiple interpreters, each with their own interpreter state, but sharing runtime state. +The topic of multiple interpreters is covered by several PEPs, notably :pep:`684`, :pep:`630`, and :pep:`554` (with more coming). +The current document focuses on the bytecode interpreter. + +Code objects +============ + +The interpreter uses a code object (``frame->f_code``) as its starting point. +Code objects contain many fields used by the interpreter, as well as some for use by debuggers and other tools. +In 3.11, the final field of a code object is an array of indeterminate length containing the bytecode, ``code->co_code_adaptive``. +(In previous versions the code object was a :class:`bytes` object, ``code->co_code``; it was changed to save an allocation and to allow it to be mutated.) + +Code objects are typically produced by the bytecode :ref:`compiler `, although they are often written to disk by one process and read back in by another. +The disk version of a code object is serialized using the :mod:`marshal` protocol. +Some code objects are pre-loaded into the interpreter using ``Tools/scripts/deepfreeze.py``, which writes ``Python/deepfreeze/deepfreeze.c``. + +Code objects are nominally immutable. +Some fields (including ``co_code_adaptive``) are mutable, but mutable fields are not included when code objects are hashed or compared. + +Instruction decoding +==================== + +The first task of the interpreter is to decode the bytecode instructions. +Bytecode is stored as an array of 16-bit code units (``_Py_CODEUNIT``). +Each code unit contains an 8-bit ``opcode`` and an 8-bit argument (``oparg``), both unsigned. +In order to make the bytecode format independent of the machine byte order when stored on disk, ``opcode`` is always the first byte and ``oparg`` is always the second byte. +Macros are used to extract the ``opcode`` and ``oparg`` from a code unit (``_Py_OPCODE(word)`` and ``_Py_OPARG(word)``). +Some instructions (e.g. ``NOP`` or ``POP_TOP``) have no argument -- in this case we ignore ``oparg``. + +A simple instruction decoding loop would look like this: + +.. code-block:: c + + _Py_CODEUNIT *first_instr = code->co_code_adaptive; + _Py_CODEUNIT *next_instr = first_instr; + while (1) { + _Py_CODEUNIT word = *next_instr++; + unsigned char opcode = _Py_OPCODE(word); + unsigned int oparg = _Py_OPARG(word); + switch (opcode) { + // ... A case for each opcode ... + } + } + +This format supports 256 different opcodes, which is sufficient. +However, it also limits ``oparg`` to 8-bit values, which is not. +To overcome this, the ``EXTENDED_ARG`` opcode allows us to prefix any instruction with one or more additional data bytes. +For example, this sequence of code units:: + + EXTENDED_ARG 1 + EXTENDED_ARG 0 + LOAD_CONST 2 + +would set ``opcode`` to ``LOAD_CONST`` and ``oparg`` to ``65538`` (i.e., ``0x1_00_02``). +The compiler should limit itself to at most three ``EXTENDED_ARG`` prefixes, to allow the resulting ``oparg`` to fit in 32 bits, but the interpreter does not check this. +A series of code units starting with zero to three ``EXTENDED_ARG`` opcodes followed by a primary opcode is called a complete instruction, to distinguish it from a single code unit, which is always two bytes. +The following loop, to be inserted just above the ``switch`` statement, will make the above snippet decode a complete instruction: + +.. code-block:: c + + while (opcode == EXTENDED_ARG) { + word = *next_instr++; + opcode = _Py_OPCODE(word); + oparg = (oparg << 8) | _Py_OPARG(word); + } + +For various reasons we'll get to later (mostly efficiency, given that ``EXTENDED_ARG`` is rare) the actual code is different. + +Jumps +===== + +Note that when the ``switch`` statement is reached, ``next_instr`` (the "instruction offset") already points to the next instruction. +Thus, jump instructions can be implemented by manipulating ``next_instr``: + +- An absolute jump (``JUMP_ABSOLUTE``) sets ``next_instr = first_instr + oparg``. +- A relative jump forward (``JUMP_FORWARD``) sets ``next_instr += oparg``. +- A relative jump backward sets ``next_instr -= oparg``. + +A relative jump whose ``oparg`` is zero is a no-op. + +Inline cache entries +==================== + +Some (specialized or specializable) instructions have an associated "inline cache". +The inline cache consists of one or more two-byte entries included in the bytecode array as additional words following the ``opcode`` /``oparg`` pair. +The size of the inline cache for a particular instruction is fixed by its ``opcode`` alone. +Moreover, the inline cache size for a family of specialized/specializable instructions (e.g., ``LOAD_ATTR``, ``LOAD_ATTR_SLOT``, ``LOAD_ATTR_MODULE``) must all be the same. +Cache entries are reserved by the compiler and initialized with zeros. +If an instruction has an inline cache, the layout of its cache can be described by a ``struct`` definition and the address of the cache is given by casting ``next_instr`` to a pointer to the cache ``struct``. +The size of such a ``struct`` must be independent of the machine architecture, word size and alignment requirements. +For 32-bit fields, the ``struct`` should use ``_Py_CODEUNIT field[2]``. +Even though inline cache entries are represented by code units, they do not have to conform to the ``opcode`` / ``oparg`` format. + +The instruction implementation is responsible for advancing ``next_instr`` past the inline cache. +For example, if an instruction's inline cache is four bytes (i.e., two code units) in size, the code for the instruction must contain ``next_instr += 2;``. +This is equivalent to a relative forward jump by that many code units. +(The proper way to code this is ``JUMPBY(n)``, where ``n`` is the number of code units to jump, typically given as a named constant.) + +Serializing non-zero cache entries would present a problem because the serialization (:mod:`marshal`) format must be independent of the machine byte order. + +More information about the use of inline caches :pep:`can be found in PEP 659 <659#ancillary-data>`. + +The evaluation stack +==================== + +Apart from unconditional jumps, almost all instructions read or write some data in the form of object references (``PyObject *``). +The CPython 3.11 bytecode interpreter is a stack machine, meaning that it operates by pushing data onto and popping it off the stack. +The stack is a pre-allocated array of object references. +For example, the "add" instruction (which used to be called ``BINARY_ADD`` in 3.10 but is now ``BINARY_OP 0``) pops two objects off the stack and pushes the result back onto the stack. +An interesting property of the CPython bytecode interpreter is that the stack size required to evaluate a given function is known in advance. +The stack size is computed by the bytecode compiler and is stored in ``code->co_stacksize``. +The interpreter uses this information to allocate stack. + +The stack grows up in memory; the operation ``PUSH(x)`` is equivalent to ``*stack_pointer++ = x``, whereas ``x = POP()`` means ``x = *--stack_pointer``. +There is no overflow or underflow check (except when compiled in debug mode) -- it would be too expensive, so we really trust the compiler. + +At any point during execution, the stack level is knowable based on the instruction pointer alone, and some properties of each item on the stack are also known. +In particular, only a few instructions may push a ``NULL`` onto the stack, and the positions that may be ``NULL`` are known. +A few other instructions (``GET_ITER``, ``FOR_ITER``) push or pop an object that is known to be an iterator. + +Instruction sequences that do not allow statically knowing the stack depth are deemed illegal. +The bytecode compiler never generates such sequences. +For example, the following sequence is illegal, because it keeps pushing items on the stack:: + + LOAD_FAST 0 + JUMP_BACKWARD 2 + +Do not confuse the evaluation stack with the call stack, which is used to implement calling and returning from functions. + +Error handling +============== + +When an instruction like ``BINARY_OP`` encounters an error, an exception is raised. +At this point, a traceback entry is added to the exception (by ``PyTraceBack_Here()``) and cleanup is performed. +In the simplest case (absent any ``try`` blocks), this results in the remaining objects being popped off the evaluation stack and their reference count decremented (if not ``NULL``) . +Then the interpreter function (``_PyEval_EvalFrameDefault()``) returns ``NULL``. + +However, if an exception is raised in a ``try`` block, the interpreter must jump to the corresponding ``except`` or ``finally`` block. +In 3.10 and before, there was a separate "block stack" which was used to keep track of nesting ``try`` blocks. +In 3.11, this mechanism has been replaced by a statically generated table, ``code->co_exceptiontable``. +The advantage of this approach is that entering and leaving a ``try`` block normally does not execute any code, making execution faster. +But of course, this table needs to be generated by the compiler, and decoded (by ``get_exception_handler``) when an exception happens. + +Exception table format +---------------------- + +The table is conceptually a list of records, each containing four variable-length integer fields (in a unique format, see below): + +- start: start of ``try`` block, in code units from the start of the bytecode +- length: size of the ``try`` block, in code units +- target: start of the first instruction of the ``except`` or ``finally`` block, in code units from the start of the bytecode +- depth_and_lasti: the low bit gives the "lasti" flag, the remaining bits give the stack depth + +The stack depth is used to clean up evaluation stack entries above this depth. +The "lasti" flag indicates whether, after stack cleanup, the instruction offset of the raising instruction should be pushed (as a ``PyLongObject *``). +For more information on the design, see :cpy-file:`Objects/exception_handling_notes.txt`. + +Each varint is encoded as one or more bytes. +The high bit (bit 7) is reserved for random access -- it is set for the first varint of a record. +The second bit (bit 6) indicates whether this is the last byte or not -- it is set for all but the last bytes of a varint. +The low 6 bits (bits 0-5) are used for the integer value, in big-endian order. + +To find the table entry (if any) for a given instruction offset, we can use bisection without decoding the whole table. +We bisect the raw bytes, at each probe finding the start of the record by scanning back for a byte with the high bit set, and then decode the first varint. +See ``get_exception_handler()`` in :cpy-file:`Python/ceval.c` for the exact code (like all bisection algorithms, the code is a bit subtle). + +The locations table +------------------- + +Whenever an exception is raised, we add a traceback entry to the exception. +The ``tb_lineno`` field of a traceback entry must be set to the line number of the instruction that raised it. +This field is computed from the locations table, ``co_linetable`` (this name is an understatement), using :c:func:`PyCode_Addr2Line`. +This table has an entry for every instruction rather than for every ``try`` block, so a compact format is very important. + +The full design of the 3.11 locations table is written up in :cpy-file:`Objects/locations.md`. +While there are rumors that this file is slightly out of date, it is still the best reference we have. +Don't be confused by :cpy-file:`Objects/lnotab_notes.txt`, which describes the 3.10 format. +For backwards compatibility this format is still supported by the ``co_lnotab`` property. + +The 3.11 location table format is different because it stores not just the starting line number for each instruction, but also the end line number, *and* the start and end column numbers. +Note that traceback objects don't store all this information -- they store the start line number, for backward compatibility, and the "last instruction" value. +The rest can be computed from the last instruction (``tb_lasti``) with the help of the locations table. +For Python code, a convenient method exists, :meth:`~codeobject.co_positions`, which returns an iterator of :samp:`({line}, {endline}, {column}, {endcolumn})` tuples, one per instruction. +There is also ``co_lines()`` which returns an iterator of :samp:`({start}, {end}, {line})` tuples, where :samp:`{start}` and :samp:`{end}` are bytecode offsets. +The latter is described by :pep:`626`; it is more compact, but doesn't return end line numbers or column offsets. +From C code, you have to call :c:func:`PyCode_Addr2Location`. + +Fortunately, the locations table is only consulted by exception handling (to set ``tb_lineno``) and by tracing (to pass the line number to the tracing function). +In order to reduce the overhead during tracing, the mapping from instruction offset to line number is cached in the ``_co_linearray`` field. + +Exception chaining +------------------ + +When an exception is raised during exception handling, the new exception is chained to the old one. +This is done by making the ``__context__`` field of the new exception point to the old one. +This is the responsibility of ``_PyErr_SetObject()`` in :cpy-file:`Python/errors.c` (which is ultimately called by all ``PyErr_Set*()`` functions). +Separately, if a statement of the form :samp:`raise {X} from {Y}` is executed, the ``__cause__`` field of the raised exception (:samp:`{X}`) is set to :samp:`{Y}`. +This is done by :c:func:`PyException_SetCause`, called in response to all ``RAISE_VARARGS`` instructions. +A special case is :samp:`raise {X} from None`, which sets the ``__cause__`` field to ``None`` (at the C level, it sets ``cause`` to ``NULL``). + +(TODO: Other exception details.) + +Python-to-Python calls +====================== + +The ``_PyEval_EvalFrameDefault()`` function is recursive, because sometimes the interpreter calls some C function that calls back into the interpreter. +In 3.10 and before, this was the case even when a Python function called another Python function: +The ``CALL`` instruction would call the ``tp_call`` dispatch function of the callee, which would extract the code object, create a new frame for the call stack, and then call back into the interpreter. +This approach is very general but consumes several C stack frames for each nested Python call, thereby increasing the risk of an (unrecoverable) C stack overflow. + +In 3.11, the ``CALL`` instruction special-cases function objects to "inline" the call. +When a call gets inlined, a new frame gets pushed onto the call stack and the interpreter "jumps" to the start of the callee's bytecode. +When an inlined callee executes a ``RETURN_VALUE`` instruction, the frame is popped off the call stack and the interpreter returns to its caller, +by popping a frame off the call stack and "jumping" to the return address. +There is a flag in the frame (``frame->is_entry``) that indicates whether the frame was inlined (set if it wasn't). +If ``RETURN_VALUE`` finds this flag set, it performs the usual cleanup and returns from ``_PyEval_EvalFrameDefault()`` altogether, to a C caller. + +A similar check is performed when an unhandled exception occurs. + +The call stack +============== + +Up through 3.10, the call stack used to be implemented as a singly-linked list of :c:type:`PyFrameObject` objects. +This was expensive because each call would require a heap allocation for the stack frame. +(There was some optimization using a free list, but this was not always effective, because frames are variable length.) + +In 3.11, frames are no longer fully-fledged objects. +Instead, a leaner internal ``_PyInterpreterFrame`` structure is used, which is allocated using a custom allocator, ``_PyThreadState_BumpFramePointer()``. +Usually a frame allocation is just a pointer bump, which improves memory locality. +The function ``_PyEvalFramePushAndInit()`` allocates and initializes a frame structure. + +Sometimes an actual ``PyFrameObject`` is needed, usually because some Python code calls :func:`sys._getframe` or an extension module calls :c:func:`PyEval_GetFrame`. +In this case we allocate a proper ``PyFrameObject`` and initialize it from the ``_PyInterpreterFrame``. +This is a pessimization, but fortunately happens rarely (as introspecting frames is not a common operation). + +Things get more complicated when generators are involved, since those don't follow the push/pop model. +(The same applies to async functions, which are implemented using the same infrastructure.) +A generator object has space for a ``_PyInterpreterFrame`` structure, including the variable-size part (used for locals and eval stack). +When a generator (or async) function is first called, a special opcode ``RETURN_GENERATOR`` is executed, which is responsible for creating the generator object. +The generator object's ``_PyInterpreterFrame`` is initialized with a copy of the current stack frame. +The current stack frame is then popped off the stack and the generator object is returned. +(Details differ depending on the ``is_entry`` flag.) +When the generator is resumed, the interpreter pushes the ``_PyInterpreterFrame`` onto the stack and resumes execution. +(There is more hairiness for generators and their ilk; we'll discuss these in a later section in more detail.) + +(TODO: Also frame layout and use, and "locals plus".) + +All sorts of variables +====================== + +The bytecode compiler determines the scope in which each variable name is defined, and generates instructions accordingly. +For example, loading a local variable onto the stack is done using ``LOAD_FAST``, while loading a global is done using ``LOAD_GLOBAL``. +The key types of variables are: + +- fast locals: used in functions +- (slow or regular) locals: used in classes and at the top level +- globals and builtins: the compiler does not distinguish between globals and builtins (though the specializing interpreter does) +- cells: used for nonlocal references + +(TODO: Write the rest of this section. Alas, the author got distracted and won't have time to continue this for a while.) + +Other topics +============ + +(TODO: Each of the following probably deserves its own section.) + +- co_consts, co_names, co_varnames, and their ilk +- How calls work (how args are transferred, return, exceptions) +- Generators, async functions, async generators, and ``yield from`` (next, send, throw, close; and await; and how this code breaks the interpreter abstraction) +- Eval breaker (interrupts, GIL) +- Tracing +- Setting the current lineno (debugger-induced jumps) +- Specialization, inline caches etc. From 9513ac82bb982a174bf697876ecd605e3b679fb2 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Wed, 18 Jan 2023 11:29:29 +0000 Subject: [PATCH 041/538] Use consistently 'gc_ref' in the garbage collector docs (#1029) --- internals/garbage-collector.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index d76e72bcb..ab6b35c7a 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -191,38 +191,38 @@ The GC then iterates over all containers in the first list and decrements by one this makes use of the ``tp_traverse`` slot in the container class (implemented using the C API or inherited by a superclass) to know what objects are referenced by each container. After all the objects have been scanned, only the objects that have -references from outside the “objects to scan” list will have ``gc_refs > 0``. +references from outside the “objects to scan” list will have ``gc_ref > 0``. .. figure:: /_static/python-cyclic-gc-2-new-page.png -Notice that having ``gc_refs == 0`` does not imply that the object is unreachable. -This is because another object that is reachable from the outside (``gc_refs > 0``) +Notice that having ``gc_ref == 0`` does not imply that the object is unreachable. +This is because another object that is reachable from the outside (``gc_ref > 0``) can still have references to it. For instance, the ``link_2`` object in our example -ended having ``gc_refs == 0`` but is referenced still by the ``link_1`` object that +ended having ``gc_ref == 0`` but is referenced still by the ``link_1`` object that is reachable from the outside. To obtain the set of objects that are really unreachable, the garbage collector re-scans the container objects using the ``tp_traverse`` slot; this time with a different traverse function that marks objects with -``gc_refs == 0`` as "tentatively unreachable" and then moves them to the +``gc_ref == 0`` as "tentatively unreachable" and then moves them to the tentatively unreachable list. The following image depicts the state of the lists in a moment when the GC processed the ``link_3`` and ``link_4`` objects but has not processed ``link_1`` and ``link_2`` yet. .. figure:: /_static/python-cyclic-gc-3-new-page.png -Then the GC scans the next ``link_1`` object. Because it has ``gc_refs == 1``, +Then the GC scans the next ``link_1`` object. Because it has ``gc_ref == 1``, the gc does not do anything special because it knows it has to be reachable (and is already in what will become the reachable list): .. figure:: /_static/python-cyclic-gc-4-new-page.png -When the GC encounters an object which is reachable (``gc_refs > 0``), it traverses +When the GC encounters an object which is reachable (``gc_ref > 0``), it traverses its references using the ``tp_traverse`` slot to find all the objects that are reachable from it, moving them to the end of the list of reachable objects (where -they started originally) and setting its ``gc_refs`` field to 1. This is what happens +they started originally) and setting its ``gc_ref`` field to 1. This is what happens to ``link_2`` and ``link_3`` below as they are reachable from ``link_1``. From the state in the previous image and after examining the objects referred to by ``link_1`` the GC knows that ``link_3`` is reachable after all, so it is moved back to the -original list and its ``gc_refs`` field is set to 1 so that if the GC visits it again, +original list and its ``gc_ref`` field is set to 1 so that if the GC visits it again, it will know that it's reachable. To avoid visiting an object twice, the GC marks all objects that have already been visited once (by unsetting the ``PREV_MASK_COLLECTING`` flag) so that if an object that has already been processed is referenced by some other @@ -431,7 +431,7 @@ of ``PyGC_Head`` discussed in the `Memory layout and object structure`_ section: ``PREV_MASK_COLLECTING`` and ``_PyGC_PREV_MASK_FINALIZED``. Between collections, the only flag that can be present is ``_PyGC_PREV_MASK_FINALIZED`` that indicates if an object has been already finalized. During collections ``_gc_prev`` is - temporarily used for storing a copy of the reference count (``gc_refs``), in + temporarily used for storing a copy of the reference count (``gc_ref``), in addition to two flags, and the GC linked list becomes a singly linked list until ``_gc_prev`` is restored. From de5fff89c27a80c5612fffc22fdb777b0e42a09f Mon Sep 17 00:00:00 2001 From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Fri, 20 Jan 2023 07:47:25 +0530 Subject: [PATCH 042/538] add experts index entries for deepfreeze, frozen modules and subinterpreters (#1033) * add Kumar Aditya to experts list * sort it * add Guido and Eric * Update core-developers/experts.rst --- core-developers/experts.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 4bee9b6ef..f48eaf7ea 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -285,6 +285,7 @@ Tools Tool Maintainers ================== =========== Argument Clinic larryhastings +Deepfreeze gvanrossum, kumaraditya303 PEG Generator gvanrossum, pablogsal, lysnikolaou ================== =========== @@ -334,6 +335,7 @@ documentation ezio-melotti, merwok, JulienPalard, willingc, hugovk emoji Mariatta extension modules encukou, ncoghlan filesystem giampaolo +frozen modules ericsnowcurrently, gvanrossum, kumaraditya303 f-strings ericvsmith* GUI i18n malemburg, merwok @@ -355,6 +357,7 @@ release management tarekziade, malemburg, benjaminp, warsaw, gvanrossum, anthonybaxter^, merwok, ned-deily, birkenfeld, JulienPalard str.format ericvsmith* +subinterpreters ericsnowcurrently, kumaraditya303 testing voidspace, ezio-melotti test coverage threads gpshead From abb135e21c5f2afca9f19afcc379268e1036165e Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 22 Jan 2023 23:40:22 -0800 Subject: [PATCH 043/538] Mention MicroPython and CircuitPython in Others. (#1035) --- index.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/index.rst b/index.rst index 7ed971adf..063dced4a 100644 --- a/index.rst +++ b/index.rst @@ -168,6 +168,11 @@ developers to work on them. Some major examples that may be of interest are: * Stackless_: A Python interpreter focused on providing lightweight microthreads while remaining largely compatible with CPython specific 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. +* CircuitPython_: A fork of MicroPython designed to simplify experimenting + and learning to code on low-cost microcontroller boards. Key Resources @@ -256,4 +261,6 @@ Full Table of Contents .. _Jython: https://www.jython.org/ .. _IronPython: https://ironpython.net/ .. _Stackless: https://github.com/stackless-dev/stackless/wiki/ +.. _MicroPython: https://micropython.org/ +.. _CircuitPython: https://circuitpython.org/ .. _Issue tracker: https://github.com/python/cpython/issues From ee80f058305935994ab1e8c38d250940d79f0ebc Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Tue, 24 Jan 2023 23:30:34 -0800 Subject: [PATCH 044/538] Update the Org Repository Policy per the 2022 PSC (#1036) This is a result of the discussion started by the 2022 Python Steering Council on https://discuss.python.org/t/new-python-organization-repository-policy/17376 and https://mail.python.org/archives/list/python-dev@python.org/message/FAASOMUNQZDJBCOTZK6I2KH55SDOONF6/. It is based on Petr's original text from the discuss thread, omitting any mention of the PSF Contributor Agreement (CLA) as discussion revealed that it may not make sense for all repos (see thread). It also adopts the suggestion from Joannah to have people discuss additions in our Committers forum before bringing an addition to the Python Steering Council. --- developer-workflow/development-cycle.rst | 45 +++++++++++++++++++----- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 593d61b95..851cd68f7 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -216,16 +216,43 @@ The source code is currently hosted on `GitHub Organization Repository Policy ------------------------------ -Within the `Python organization `_, repositories are expected to fall within these general categories: +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 (i.e. `CPython `_) +* Tooling and support around CPython development (e.g. `pyperformance `_, `Bedevere `_) +* Helpers and backports for Python/CPython features (e.g. `typing_extensions `_, `typeshed `_, `tzdata `_, `pythoncapi-compat `_) +* Organization-related repositories (e.g. the `Code of Conduct `_, `.github `_) +* Documentation and websites for all the above (e.g. `python.org repository `_, `PEPs `_, `Devguide `_, docs translations) +* Infrastructure for all the above (e.g. `docsbuild-scripts `_, `buildmaster-config `_) +* Discussions and notes around official development-related processes and events (e.g. `steering-council `_, `core-sprint `_) + +Before adding a new repository to the organization, open a discussion to seek consensus +in the `Committers Discourse category `_. +Once people are satisfied with that, ask the `Python steering council `_ +to grant permission. + +Note that several repositories remain in the organization for historic reasons, +and would probably not be appropriate to add today. + +Generally, new repositories should start their life under personal GitHub +accounts or other GitHub orgs. It is relatively easy to move a repository to +the organization once it is mature. For example, this would now apply to +experimental features like `asyncio `_, +`exceptiongroups `_, +and drafts of new guides and other documentation (e.g. `redistributor-guide +`_). + +General-use tools and libraries (e.g. `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 e.g. +`typeshed `_, +`tzdata `_, or +`pythoncapi-compat `_). -1. The reference implementation of Python and related repositories (i.e. `CPython `_) -2. Reference implementations of PEPs (e.g. `mypy `_) -3. Tooling and support around CPython and the language (e.g. `python.org repository `_) -4. PSF-related repositories (e.g. the `Code of Conduct `_) -5. PSF Infrastructure repositories (e.g. the `PSF Infrastructure Salt configurations `_) - -For any repository which does not explicitly and clearly fall under one of these categories, permission should be sought -from the `Python steering council `_. Organization Owner Policy ------------------------- From 5280184725496768af9360c571e9fbd9f06395ab Mon Sep 17 00:00:00 2001 From: Mana Date: Thu, 26 Jan 2023 21:07:41 +0800 Subject: [PATCH 045/538] Fix one character typo (#1039) * Fix one character typo * Fix label position in internals/parser.rst Co-authored-by: C.A.M. Gerlach Co-authored-by: Ezio Melotti Co-authored-by: C.A.M. Gerlach --- internals/parser.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internals/parser.rst b/internals/parser.rst index df5f23444..aa035c1a7 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -92,11 +92,11 @@ Key ideas PEG parser doesn't have a concept of "where the :exc:`SyntaxError` is". -Consequences or the ordered choice operator -------------------------------------------- - .. _consequences-of-ordered-choice: +Consequences of the ordered choice operator +------------------------------------------- + Although PEG may look like EBNF, its meaning is quite different. The fact that in PEG parsers alternatives are ordered (which is at the core of how PEG parsers work) has deep consequences, other than removing ambiguity. From 4f3b52077cf2be8aff1018bcbdbc6dc267001078 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 31 Jan 2023 11:56:38 -0800 Subject: [PATCH 046/538] Add Pradyun Gedam to the developer log --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index f6ffffd0e..53edf62b3 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Pradyun Gedam,pradyunsg,2023-01-30,, Shantanu Jain,hauntsaninja,2022-12-19,, Kumar Aditya,kumaraditya303,2022-11-21,, Hugo van Kemenade,hugovk,2022-11-21,, From bd1c5cd1efb3f05919897b0aea3bfe707eb7c879 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 06:54:07 +0100 Subject: [PATCH 047/538] Bump sphinx from 6.0.0 to 6.1.3 (#1040) Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 6.0.0 to 6.1.3. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v6.0.0...v6.1.3) --- updated-dependencies: - dependency-name: sphinx dependency-type: direct:production update-type: version-update:semver-minor ... 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 3370b57da..3b08c6b77 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Sphinx==6.0.0 +Sphinx==6.1.3 furo>=2022.6.4 sphinx-lint==0.6.7 sphinx_copybutton>=0.3.3 From 21d6d8d4b15c2b355ec170ae7dc523a621951dd3 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 1 Feb 2023 10:55:02 +0100 Subject: [PATCH 048/538] Generate the release cycle chart directly as SVG (#1034) Co-authored-by: C.A.M. Gerlach Co-authored-by: Hugo van Kemenade --- .github/workflows/release-cycle.yml | 31 ------ .gitignore | 11 +- Makefile | 12 +-- _static/devguide_overrides.css | 97 ++++++++--------- _tools/generate_release_cycle.py | 134 ++++++++++++++++-------- _tools/release_cycle_template.svg.jinja | 91 ++++++++++++++++ conf.py | 1 - include/branches.csv | 7 -- include/end-of-life.csv | 10 -- include/release-cycle.mmd | 49 --------- requirements.txt | 2 +- versions.rst | 17 +-- 12 files changed, 245 insertions(+), 217 deletions(-) delete mode 100644 .github/workflows/release-cycle.yml create mode 100644 _tools/release_cycle_template.svg.jinja delete mode 100644 include/branches.csv delete mode 100644 include/end-of-life.csv delete mode 100644 include/release-cycle.mmd diff --git a/.github/workflows/release-cycle.yml b/.github/workflows/release-cycle.yml deleted file mode 100644 index 8b676d78a..000000000 --- a/.github/workflows/release-cycle.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Test release cycle - -on: [pull_request, push, workflow_dispatch] - -env: - FORCE_COLOR: 1 - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [windows-latest, ubuntu-latest] - - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-python@v4 - with: - python-version: "3" - - - name: Generate release cycle output - run: python -I -bb -X dev -X warn_default_encoding -W error _tools/generate_release_cycle.py - - - name: Check for differences - run: | - git add . - git status - git diff --staged - test $(git status --porcelain | wc -l) = 0 diff --git a/.gitignore b/.gitignore index c74e78d0f..df4dc9415 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ __pycache__/ # Distribution / packaging .Python env/ +ENV/ venv/ build/ develop-eggs/ @@ -80,13 +81,13 @@ celerybeat-schedule # dotenv .env -# virtualenv -venv/ -ENV/ -venv/ - # Spyder project settings .spyderproject # Rope project settings .ropeproject + +# Generated CSV and SVG files +include/branches.csv +include/end-of-life.csv +include/release-cycle.svg diff --git a/Makefile b/Makefile index 6e5ee1693..d86ebf533 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ html: ensure-venv versions @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." .PHONY: dirhtml -dirhtml: ensure-venv +dirhtml: ensure-venv versions $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." @@ -189,14 +189,14 @@ serve: "(see https://github.com/python/cpython/issues/80510)" include/branches.csv: include/release-cycle.json - $(PYTHON) _tools/generate_release_cycle.py + $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py include/end-of-life.csv: include/release-cycle.json - $(PYTHON) _tools/generate_release_cycle.py + $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py -include/release-cycle.mmd: include/release-cycle.json - $(PYTHON) _tools/generate_release_cycle.py +include/release-cycle.svg: include/release-cycle.json + $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py .PHONY: versions -versions: include/branches.csv include/end-of-life.csv include/release-cycle.mmd +versions: venv include/branches.csv include/end-of-life.csv include/release-cycle.svg @echo Release cycle data generated. diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css index c34f47133..a93acbbff 100644 --- a/_static/devguide_overrides.css +++ b/_static/devguide_overrides.css @@ -7,66 +7,69 @@ } /* Release cycle chart */ -#python-release-cycle .mermaid .active0, -#python-release-cycle .mermaid .active1, -#python-release-cycle .mermaid .active2, -#python-release-cycle .mermaid .active3 { - fill: #00dd00; - stroke: darkgreen; + +.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); } -#python-release-cycle .mermaid .done0, -#python-release-cycle .mermaid .done1, -#python-release-cycle .mermaid .done2, -#python-release-cycle .mermaid .done3 { - fill: orange; - stroke: darkorange; +.release-cycle-chart .release-cycle-today-line { + stroke: var(--color-brand-primary); + stroke-width: 1.6px; } -#python-release-cycle .mermaid .task0, -#python-release-cycle .mermaid .task1, -#python-release-cycle .mermaid .task2, -#python-release-cycle .mermaid .task3 { - fill: #007acc; - stroke: #004455; +.release-cycle-chart .release-cycle-row-shade { + fill: var(--color-background-item); + opacity: 50%; } -#python-release-cycle .mermaid .section0, -#python-release-cycle .mermaid .section2 { - fill: darkgrey; +.release-cycle-chart .release-cycle-version-label { + fill: var(--color-foreground-primary); } -/* Set master colours */ -:root { - --mermaid-section1-3: white; - --mermaid-text-color: black; +.release-cycle-chart .release-cycle-blob { + stroke-width: 1.6px; + /* default colours, overriden below for individual statuses */ + fill: var(--color-background-primary); + stroke: var(--color-foreground-primary); } -@media (prefers-color-scheme: dark) { - body[data-theme=auto] { - --mermaid-section1-3: black; - --mermaid-text-color: #ffffffcc; - } +.release-cycle-chart .release-cycle-blob-label { + /* white looks good on both light & dark */ + fill: white; } -body[data-theme=dark] { - --mermaid-section1-3: black; - --mermaid-text-color: #ffffffcc; + +.release-cycle-chart .release-cycle-blob-label.release-cycle-blob-security, +.release-cycle-chart .release-cycle-blob-label.release-cycle-blob-bugfix { + /* but use black to improve contrast for lighter backgrounds */ + fill: black; +} + +.release-cycle-chart .release-cycle-blob.release-cycle-blob-end-of-life { + fill: #DD2200; + stroke: #FF8888; +} + +.release-cycle-chart .release-cycle-blob.release-cycle-blob-security { + fill: #FFDD44; + stroke: #FF8800; } -#python-release-cycle .mermaid .section1, -#python-release-cycle .mermaid .section3 { - fill: var(--mermaid-section1-3); +.release-cycle-chart .release-cycle-blob.release-cycle-blob-bugfix { + fill: #00DD22; + stroke: #008844; } -#python-release-cycle .mermaid .grid .tick text, -#python-release-cycle .mermaid .sectionTitle0, -#python-release-cycle .mermaid .sectionTitle1, -#python-release-cycle .mermaid .sectionTitle2, -#python-release-cycle .mermaid .sectionTitle3, -#python-release-cycle .mermaid .taskTextOutside0, -#python-release-cycle .mermaid .taskTextOutside1, -#python-release-cycle .mermaid .taskTextOutside2, -#python-release-cycle .mermaid .taskTextOutside3, -#python-release-cycle .mermaid .titleText { - fill: var(--mermaid-text-color); +.release-cycle-chart .release-cycle-blob.release-cycle-blob-feature { + fill: #2222EE; + stroke: #008888; } diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index 7e9e69ad8..59e9fcbbe 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -1,28 +1,12 @@ -"""Read in a JSON and generate two CSVs and a Mermaid file.""" +"""Read in a JSON and generate two CSVs and an SVG file.""" from __future__ import annotations +import argparse import csv import datetime as dt import json -MERMAID_HEADER = """ -gantt - dateFormat YYYY-MM-DD - title Python release cycle - axisFormat %Y -""".lstrip() - -MERMAID_SECTION = """ - section Python {version} - {release_status} :{mermaid_status} python{version}, {first_release},{eol} -""" # noqa: E501 - -MERMAID_STATUS_MAPPING = { - "feature": "", - "bugfix": "active,", - "security": "done,", - "end-of-life": "crit,", -} +import jinja2 def csv_date(date_str: str, now_str: str) -> str: @@ -33,23 +17,28 @@ def csv_date(date_str: str, now_str: str) -> str: return date_str -def mermaid_date(date_str: str) -> str: - """Format a date for Mermaid.""" +def parse_date(date_str: str) -> dt.date: if len(date_str) == len("yyyy-mm"): - # Mermaid needs a full yyyy-mm-dd, so let's approximate - date_str = f"{date_str}-01" - return date_str + # We need a full yyyy-mm-dd, so let's approximate + return dt.date.fromisoformat(date_str + "-01") + return dt.date.fromisoformat(date_str) class Versions: - """For converting JSON to CSV and Mermaid.""" + """For converting JSON to CSV and SVG.""" def __init__(self) -> None: with open("include/release-cycle.json", encoding="UTF-8") as in_file: self.versions = json.load(in_file) + + # Generate a few additional fields + for key, version in self.versions.items(): + version["key"] = key + version["first_release_date"] = parse_date(version["first_release"]) + version["end_of_life_date"] = parse_date(version["end_of_life"]) self.sorted_versions = sorted( - self.versions.items(), - key=lambda k: [int(i) for i in k[0].split(".")], + self.versions.values(), + key=lambda v: [int(i) for i in v["key"].split(".")], reverse=True, ) @@ -59,7 +48,7 @@ def write_csv(self) -> None: versions_by_category = {"branches": {}, "end-of-life": {}} headers = None - for version, details in self.sorted_versions: + for details in self.sorted_versions: row = { "Branch": details["branch"], "Schedule": f":pep:`{details['pep']}`", @@ -70,7 +59,7 @@ def write_csv(self) -> None: } headers = row.keys() cat = "end-of-life" if details["status"] == "end-of-life" else "branches" - versions_by_category[cat][version] = row + versions_by_category[cat][details["key"]] = row for cat, versions in versions_by_category.items(): with open(f"include/{cat}.csv", "w", encoding="UTF-8", newline="") as file: @@ -78,30 +67,85 @@ def write_csv(self) -> None: csv_file.writeheader() csv_file.writerows(versions.values()) - def write_mermaid(self) -> None: - """Output Mermaid file.""" - out = [MERMAID_HEADER] - - for version, details in reversed(self.versions.items()): - v = MERMAID_SECTION.format( - version=version, - first_release=details["first_release"], - eol=mermaid_date(details["end_of_life"]), - release_status=details["status"], - mermaid_status=MERMAID_STATUS_MAPPING[details["status"]], - ) - out.append(v) + def write_svg(self, today: str) -> None: + """Output SVG file.""" + env = jinja2.Environment( + loader=jinja2.FileSystemLoader("_tools/"), + autoescape=True, + lstrip_blocks=True, + trim_blocks=True, + undefined=jinja2.StrictUndefined, + ) + template = env.get_template("release_cycle_template.svg.jinja") + + # Scale. Should be roughly the pixel size of the font. + # All later sizes are multiplied by this, so you can think of all other + # numbers being multiples of the font size, like using `em` units in + # CSS. + # (Ideally we'd actually use `em` units, but SVG viewBox doesn't take + # those.) + SCALE = 18 + + # Width of the drawing and main parts + DIAGRAM_WIDTH = 46 + LEGEND_WIDTH = 7 + RIGHT_MARGIN = 0.5 + + # Height of one line. If you change this you'll need to tweak + # some positioning numbers in the template as well. + LINE_HEIGHT = 1.5 + + first_date = min(ver["first_release_date"] for ver in self.sorted_versions) + last_date = max(ver["end_of_life_date"] for ver in self.sorted_versions) + + def date_to_x(date: dt.date) -> float: + """Convert datetime.date to an SVG X coordinate""" + num_days = (date - first_date).days + total_days = (last_date - first_date).days + ratio = num_days / total_days + x = ratio * (DIAGRAM_WIDTH - LEGEND_WIDTH - RIGHT_MARGIN) + return x + LEGEND_WIDTH + + def year_to_x(year: int) -> float: + """Convert year number to an SVG X coordinate of 1st January""" + return date_to_x(dt.date(year, 1, 1)) + + def format_year(year: int) -> str: + """Format year number for display""" + return f"'{year % 100:02}" with open( - "include/release-cycle.mmd", "w", encoding="UTF-8", newline="\n" + "include/release-cycle.svg", "w", encoding="UTF-8", newline="\n" ) as f: - f.writelines(out) + template.stream( + SCALE=SCALE, + diagram_width=DIAGRAM_WIDTH, + diagram_height=(len(self.sorted_versions) + 2) * LINE_HEIGHT, + years=range(first_date.year, last_date.year + 1), + LINE_HEIGHT=LINE_HEIGHT, + versions=list(reversed(self.sorted_versions)), + today=dt.datetime.strptime(today, "%Y-%m-%d").date(), + year_to_x=year_to_x, + date_to_x=date_to_x, + format_year=format_year, + ).dump(f) def main() -> None: + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument( + "--today", + default=str(dt.date.today()), + metavar=" YYYY-MM-DD", + help="Override today for testing", + ) + args = parser.parse_args() + versions = Versions() versions.write_csv() - versions.write_mermaid() + versions.write_svg(args.today) if __name__ == "__main__": diff --git a/_tools/release_cycle_template.svg.jinja b/_tools/release_cycle_template.svg.jinja new file mode 100644 index 000000000..5d39d307a --- /dev/null +++ b/_tools/release_cycle_template.svg.jinja @@ -0,0 +1,91 @@ + + + + {% for version in versions %} + {% set y = loop.index * LINE_HEIGHT %} + + {% if loop.index % 2 %} + + + {% endif %} + {% endfor %} + + {% for year in years %} + + {{ format_year(year) }} + + {% if not loop.last %} + + {% endif %} + {% endfor %} + + {% for version in versions %} + {% set y = loop.index * LINE_HEIGHT %} + + + + Python {{ version.key }} + + + + {% set start_x = date_to_x(version.first_release_date) %} + {% set end_x = date_to_x(version.end_of_life_date) %} + {% set mid_x = (start_x + end_x) / 2 %} + + + {{ version.status }} + + {% endfor %} + + + + diff --git a/conf.py b/conf.py index 29563db50..849538be7 100644 --- a/conf.py +++ b/conf.py @@ -10,7 +10,6 @@ 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx_copybutton', - 'sphinxcontrib.mermaid', 'sphinxext.opengraph', 'sphinxext.rediraffe', ] diff --git a/include/branches.csv b/include/branches.csv deleted file mode 100644 index bfec9da84..000000000 --- a/include/branches.csv +++ /dev/null @@ -1,7 +0,0 @@ -Branch,Schedule,Status,First release,End of life,Release manager -main,:pep:`693`,feature,*2023-10-02*,*2028-10*,Thomas Wouters -3.11,:pep:`664`,bugfix,2022-10-24,*2027-10*,Pablo Galindo Salgado -3.10,:pep:`619`,bugfix,2021-10-04,*2026-10*,Pablo Galindo Salgado -3.9,:pep:`596`,security,2020-10-05,*2025-10*,Łukasz Langa -3.8,:pep:`569`,security,2019-10-14,*2024-10*,Łukasz Langa -3.7,:pep:`537`,security,2018-06-27,*2023-06-27*,Ned Deily diff --git a/include/end-of-life.csv b/include/end-of-life.csv deleted file mode 100644 index be9fe1b72..000000000 --- a/include/end-of-life.csv +++ /dev/null @@ -1,10 +0,0 @@ -Branch,Schedule,Status,First release,End of life,Release manager -3.6,:pep:`494`,end-of-life,2016-12-23,2021-12-23,Ned Deily -3.5,:pep:`478`,end-of-life,2015-09-13,2020-09-30,Larry Hastings -3.4,:pep:`429`,end-of-life,2014-03-16,2019-03-18,Larry Hastings -3.3,:pep:`398`,end-of-life,2012-09-29,2017-09-29,"Georg Brandl, Ned Deily (3.3.7+)" -3.2,:pep:`392`,end-of-life,2011-02-20,2016-02-20,Georg Brandl -3.1,:pep:`375`,end-of-life,2009-06-27,2012-04-09,Benjamin Peterson -3.0,:pep:`361`,end-of-life,2008-12-03,2009-06-27,Barry Warsaw -2.7,:pep:`373`,end-of-life,2010-07-03,2020-01-01,Benjamin Peterson -2.6,:pep:`361`,end-of-life,2008-10-01,2013-10-29,Barry Warsaw diff --git a/include/release-cycle.mmd b/include/release-cycle.mmd deleted file mode 100644 index fc437ab59..000000000 --- a/include/release-cycle.mmd +++ /dev/null @@ -1,49 +0,0 @@ -gantt - dateFormat YYYY-MM-DD - title Python release cycle - axisFormat %Y - - section Python 2.6 - end-of-life :crit, python2.6, 2008-10-01,2013-10-29 - - section Python 3.0 - end-of-life :crit, python3.0, 2008-12-03,2009-06-27 - - section Python 3.1 - end-of-life :crit, python3.1, 2009-06-27,2012-04-09 - - section Python 2.7 - end-of-life :crit, python2.7, 2010-07-03,2020-01-01 - - section Python 3.2 - end-of-life :crit, python3.2, 2011-02-20,2016-02-20 - - section Python 3.3 - end-of-life :crit, python3.3, 2012-09-29,2017-09-29 - - section Python 3.4 - end-of-life :crit, python3.4, 2014-03-16,2019-03-18 - - section Python 3.5 - end-of-life :crit, python3.5, 2015-09-13,2020-09-30 - - section Python 3.6 - end-of-life :crit, python3.6, 2016-12-23,2021-12-23 - - section Python 3.7 - security :done, python3.7, 2018-06-27,2023-06-27 - - section Python 3.8 - security :done, python3.8, 2019-10-14,2024-10-01 - - section Python 3.9 - security :done, python3.9, 2020-10-05,2025-10-01 - - section Python 3.10 - bugfix :active, python3.10, 2021-10-04,2026-10-01 - - section Python 3.11 - bugfix :active, python3.11, 2022-10-24,2027-10-01 - - section Python 3.12 - feature : python3.12, 2023-10-02,2028-10-01 diff --git a/requirements.txt b/requirements.txt index 3b08c6b77..3724519a8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ Sphinx==6.1.3 furo>=2022.6.4 +jinja2 sphinx-lint==0.6.7 sphinx_copybutton>=0.3.3 -sphinxcontrib-mermaid sphinxext-opengraph>=0.7.1 sphinxext-rediraffe diff --git a/versions.rst b/versions.rst index c36f7e672..fd28b3f85 100644 --- a/versions.rst +++ b/versions.rst @@ -13,8 +13,8 @@ version can be found on the `download page `_ Python Release Cycle ==================== -.. mermaid:: include/release-cycle.mmd - +.. raw:: html + :file: include/release-cycle.svg Supported Versions ================== @@ -55,16 +55,3 @@ See also the :ref:`devcycle` page for more information about branches. By default, the end-of-life is scheduled 5 years after the first release, but can be adjusted by the release manager of each branch. All Python 2 versions have reached end-of-life. - -.. raw:: html - - From 000776a2cd353808fd0d4d4f79ae8b9382df95cf Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 8 Feb 2023 15:38:50 +0200 Subject: [PATCH 049/538] Use sphinx-notfound-page to create a 404 page matching the theme (#1042) --- conf.py | 4 ++++ requirements.txt | 1 + 2 files changed, 5 insertions(+) diff --git a/conf.py b/conf.py index 849538be7..ba5422f51 100644 --- a/conf.py +++ b/conf.py @@ -7,6 +7,7 @@ extensions = [ 'custom_roles', + 'notfound.extension', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx_copybutton', @@ -140,6 +141,9 @@ todo_include_todos = True +# sphinx-notfound-page +notfound_urls_prefix = "/" + # sphinxext-opengraph config ogp_site_url = "https://devguide.python.org/" ogp_site_name = "Python Developer's Guide" diff --git a/requirements.txt b/requirements.txt index 3724519a8..d8fb7ac3d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,7 @@ Sphinx==6.1.3 furo>=2022.6.4 jinja2 sphinx-lint==0.6.7 +sphinx-notfound-page sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 sphinxext-rediraffe From 7059ba0e7432637d725ba6967c77a3715ffdfc03 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 8 Feb 2023 16:21:02 +0200 Subject: [PATCH 050/538] Restore #what-s-new-and-news-entries anchor (#1046) --- core-developers/committing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/committing.rst b/core-developers/committing.rst index be223ba83..831d1aa07 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -74,8 +74,8 @@ to enter the public source tree. Ask yourself the following questions: be added as well. Changes that affect only documentation generally do not require a ``NEWS`` entry. (See the following section for more information.) - .. _news-entry: +.. _what-s-new-and-news-entries: Updating NEWS and What's New in Python -------------------------------------- From c272354f055c828d65dd47b7358810f94b7e3c50 Mon Sep 17 00:00:00 2001 From: Eclips4 <80244920+Eclips4@users.noreply.github.com> Date: Fri, 10 Feb 2023 09:29:43 +0300 Subject: [PATCH 051/538] Add information about local time (#1047) --- core-developers/committing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-developers/committing.rst b/core-developers/committing.rst index 831d1aa07..74c10bbf1 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -120,8 +120,8 @@ for what was affected (e.g. ``Misc/NEWS.d/next/Library`` for changes relating to the standard library). The file name itself should be in the format ``.gh-issue-..rst``: -* ```` is today's date joined with a hyphen (``-``) to the current - time, in the ``YYYY-MM-DD-hh-mm-ss`` format (e.g. ``2017-05-27-16-46-23``). +* ```` is today's date joined with a hyphen (``-``) to your current + local time, in the ``YYYY-MM-DD-hh-mm-ss`` format (e.g. ``2017-05-27-16-46-23``). * ```` is the issue number the change is for (e.g. ``12345`` for ``gh-issue-12345``). * ```` is a unique string to guarantee that the file name is From 94d08ef1c277df2ee922b5d67993736b752a782e Mon Sep 17 00:00:00 2001 From: Satish Mishra <7506satish@gmail.com> Date: Fri, 10 Feb 2023 18:50:14 +0530 Subject: [PATCH 052/538] Use Wayback Machine link for defunct Victor Stinner's guide #1048 (#1050) --- 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 60d0b93d5..ecf374d93 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -314,7 +314,7 @@ You can run the build of Python you've compiled with: See the `PCBuild readme`_ for more details on what other software is necessary and how to build. -.. _Victor Stinner's guide: https://cpython-core-tutorial.readthedocs.io/en/latest/build_cpython_windows.html +.. _Victor Stinner's guide: https://web.archive.org/web/20220907075854/https://cpython-core-tutorial.readthedocs.io/en/latest/build_cpython_windows.html .. _Visual Studio: https://visualstudio.microsoft.com/ .. _PCBuild readme: https://github.com/python/cpython/blob/main/PCbuild/readme.txt .. _Git for Windows download from the official Git website: https://git-scm.com/download/win From 39dcbb7b9361f33d246bd8fe4238a301f0bdba70 Mon Sep 17 00:00:00 2001 From: Satish Mishra <7506satish@gmail.com> Date: Sat, 11 Feb 2023 13:54:57 +0530 Subject: [PATCH 053/538] Update gdb & Victor's guide links, and fix voters link ignore (#1051) * [PATCH]#1044 fixing victor stinner's guide link * fixed conf.py and advanced-tools/gdb.rst link issues * changes made in gbd.rst --- advanced-tools/gdb.rst | 2 +- conf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/advanced-tools/gdb.rst b/advanced-tools/gdb.rst index cf84085d2..81bdb5201 100644 --- a/advanced-tools/gdb.rst +++ b/advanced-tools/gdb.rst @@ -21,7 +21,7 @@ GDB 7 and later =============== In gdb 7, support for `extending gdb with Python -`_ was +`_ was added. When CPython is built you will notice a ``python-gdb.py`` file in the root directory of your checkout. Read the module docstring for details on how to use the file to enhance gdb for easier debugging of a CPython process. diff --git a/conf.py b/conf.py index ba5422f51..52c637480 100644 --- a/conf.py +++ b/conf.py @@ -81,7 +81,7 @@ linkcheck_ignore = [ # The voters repo is private and appears as a 404 - 'https://github.com/python/voters/', + 'https://github.com/python/voters', # The python-core team link is private, redirects to login 'https://github.com/orgs/python/teams/python-core', # The Discourse groups are private unless you are logged in From 80cd8942fd952b9493346ba2f4804ce0e2f470bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Rom=C3=A1n?= Date: Fri, 17 Feb 2023 00:02:24 -0800 Subject: [PATCH 054/538] Update instructions for building on macOS (#1052) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update instructions for building on macOS Signed-off-by: César Román * Fix WARNING: Literal block expected; none found. getting-started/setup-building.rst:420 * Apply suggestions from code review Co-authored-by: C.A.M. Gerlach * Install and use openssl@1.1 with Homebrew * Apply suggestions from code review Co-authored-by: C.A.M. Gerlach * Restore Python 3.10+ PKG_CONFIG_PATH * Update following text to match revised macOS building language --------- Signed-off-by: César Román Co-authored-by: C.A.M. Gerlach --- getting-started/setup-building.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index ecf374d93..15e094ae2 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -413,36 +413,36 @@ Apple no longer provides header files for the deprecated system version of OpenSSL which means that you will not be able to build the ``_ssl`` extension. One solution is to install these libraries from a third-party package manager, like Homebrew_ or MacPorts_, and then add the appropriate paths -for the header and library files to your ``configure`` command. For example, +for the header and library files to your ``configure`` command. -with **Homebrew**:: +For example, with **Homebrew**, install the dependencies:: $ brew install pkg-config openssl@1.1 xz gdbm tcl-tk -For Python 3.10 and newer:: +Then, for Python 3.10 and newer, run ``configure``:: $ CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ LDFLAGS="-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" \ PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \ ./configure --with-pydebug \ - --with-openssl=$(brew --prefix openssl) + --with-openssl="$(brew --prefix openssl@1.1)" -For Python versions 3.9 through 3.7:: +Or, for Python 3.7 through 3.9:: - $ CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ + $ export PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig"; \ + CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ - PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \ ./configure --with-pydebug \ - --with-openssl=$(brew --prefix openssl@1.1) \ + --with-openssl="$(brew --prefix openssl@1.1)" \ --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ --with-tcltk-includes="$(pkg-config --cflags tcl tk)" -and ``make``:: +And finally, run ``make``:: $ make -s -j2 -or **MacPorts**:: +Alternatively, with **MacPorts**:: $ sudo port install pkgconfig openssl xz gdbm From f04b23c019f342cdda6812a432cecfff6beb3a34 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 23 Feb 2023 09:25:18 +0200 Subject: [PATCH 055/538] Append a hash ?digest to CSS files for cache-busting (#1054) Co-authored-by: C.A.M. Gerlach --- conf.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 52c637480..2c1add6c3 100644 --- a/conf.py +++ b/conf.py @@ -1,6 +1,8 @@ +import hashlib import os import sys import time +from pathlib import Path # Location of custom extensions. sys.path.insert(0, os.path.abspath(".") + "/_extensions") @@ -32,6 +34,14 @@ '.github', ] +def _asset_hash(path: os.PathLike[str]) -> str: + """Append a `?digest=` to an url based on the file content.""" + full_path = (Path(html_static_path[0]) / path).resolve() + digest = hashlib.sha1(full_path.read_bytes()).hexdigest() + + return f"{path}?digest={digest}" + + html_theme = 'furo' html_theme_options = { "source_repository": "https://github.com/python/devguide", @@ -39,7 +49,7 @@ } html_static_path = ['_static'] html_css_files = [ - 'devguide_overrides.css', + _asset_hash('devguide_overrides.css'), ] html_logo = "_static/python-logo.svg" html_favicon = "_static/favicon.png" From e44744226856ed65f57f08c8bb30ce1cdc9a0b5d Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 27 Feb 2023 21:07:25 -0800 Subject: [PATCH 056/538] Retire from parser expertise. --- 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 f48eaf7ea..de70eb292 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -168,7 +168,7 @@ optparse mitsuhiko os os.path serhiy-storchaka ossaudiodev -parser benjaminp, pablogsal +parser pablogsal pathlib barneygale* pdb pickle avassalotti From 99ccd28dd15f62317c418ad50058e8348a02ac8d Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 1 Mar 2023 15:46:52 -0800 Subject: [PATCH 057/538] Add Carl Meyer to the developer log --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 53edf62b3..bedfbdf69 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Carl Meyer,carljm,2023-02-28,, Pradyun Gedam,pradyunsg,2023-01-30,, Shantanu Jain,hauntsaninja,2022-12-19,, Kumar Aditya,kumaraditya303,2022-11-21,, From e2fc6f3e482d47c7a691cadfecaee48573491a13 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 3 Mar 2023 10:32:19 +0200 Subject: [PATCH 058/538] Automatically edit PRs with link to RTD preview (#1061) --- .github/workflows/documentation-links.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/documentation-links.yml diff --git a/.github/workflows/documentation-links.yml b/.github/workflows/documentation-links.yml new file mode 100644 index 000000000..d95cbd3ab --- /dev/null +++ b/.github/workflows/documentation-links.yml @@ -0,0 +1,17 @@ +name: Read the Docs PR preview +on: + pull_request_target: + types: + - opened + +permissions: + pull-requests: write + +jobs: + documentation-links: + runs-on: ubuntu-latest + steps: + - uses: readthedocs/actions/preview@v1 + with: + project-slug: "cpython-devguide" + single-version: "true" From 10996fe2d7c999fb6d0903a047c30c50793484a0 Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Mon, 6 Mar 2023 14:21:00 -0600 Subject: [PATCH 059/538] Overhaul Building the Documentation section for clarity (GH-1038) * Overhaul Building the Documentation section for clarity * Apply suggestions and further clarifications from Hugo Co-authored-by: Hugo van Kemenade --- documentation/start-documenting.rst | 128 +++++++++++++++++----------- 1 file changed, 79 insertions(+), 49 deletions(-) diff --git a/documentation/start-documenting.rst b/documentation/start-documenting.rst index 175c73c0a..592059bf7 100644 --- a/documentation/start-documenting.rst +++ b/documentation/start-documenting.rst @@ -64,79 +64,109 @@ Building the documentation .. highlight:: bash -The toolset used to build the docs is written in Python and is called Sphinx_. -Sphinx is maintained separately and is not included in this tree. Also needed -are blurb_, a tool to create :file:`Misc/NEWS` on demand; and -python-docs-theme_, the Sphinx theme for the Python documentation. +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. -To build the documentation, follow the instructions from one of the sections -below. You can view the documentation after building the HTML by pointing -a browser at the file :file:`Doc/build/html/index.html`. +.. note:: -You are expected to have installed the latest stable version of -Sphinx_ and blurb_ on your system or in a virtualenv_ (which can be -created using ``make venv``), so that the Makefile can find the -``sphinx-build`` command. You can also specify the location of -``sphinx-build`` with the ``SPHINXBUILD`` :command:`make` variable. + 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. -.. _building-using-make: +.. _doc-create-venv: + +Create a virtual environment +---------------------------- -Using make / make.bat ---------------------- +.. _doc-create-venv-unix: -**On Unix**, run the following from the root of your :ref:`repository clone -` to build the output as HTML:: +**On Unix platforms** that support :program:`make` +(including Linux, macOS and BSD), +you can create a new :mod:`venv` with the required dependencies using:: - cd Doc make venv - make html -or alternatively ``make -C Doc/ venv html``. ``htmlview`` can be used -instead of ``html`` to conveniently open the docs in a browser once the -build completes. +Building the docs with :program:`make` will automatically use this environment +without you having to activate it. + +.. _doc-create-venv-windows: + +**On Windows**, or if not using :program:`make`, +`create a new virtual environment `__ manually. +Always be sure to `activate this environment `__ +before building the documentation. + + +.. _building-using-make: +.. _using-make-make-bat: +.. _doc-build-make: + +Build using make / make.bat +--------------------------- -You can also use ``make help`` to see a list of targets supported by -:command:`make`. Note that ``make check`` is automatically run when -you submit a :ref:`pull request `, so you should make -sure that it runs without errors. +A Unix ``Makefile`` is provided, :cpy-file:`Doc/Makefile`, +along with a :cpy-file:`Doc/make.bat` batch file for Windows +that attempts to emulate it as closely as practical. -**On Windows**, the :cpy-file:`Doc/make.bat` batchfile tries to emulate -:command:`make` as closely as possible, but the venv target is not implemented, -so you will probably want to make sure you are working in a virtual environment -before proceeding, otherwise all dependencies will be automatically installed -on your system. +.. important:: -When ready, run the following from the root of your :ref:`repository clone -` to build the output as HTML:: + The Windows ``make.bat`` batch file lacks a ``make venv`` target. + Instead, it automatically installs any missing dependencies + into the currently activated environment (or the base Python, if none). + Make sure the environment you :ref:`created above ` + is `activated `__ before running ``make.bat``. + +To build the docs as HTML, run:: - cd Doc make html -You can also use ``make help`` to see a list of targets supported by -:cpy-file:`Doc/make.bat`. +.. tip:: Substitute ``htmlview`` for ``html`` to open the docs in a web browser + once the build completes. + +To check the docs for common errors with `Sphinx Lint`_ +(which is run on all :ref:`pull requests `), use:: + + make check + +To list other supported :program:`make` targets, run:: + + make help + +See :cpy-file:`Doc/README.rst` for more information. + + +.. _using-sphinx-build: +.. _doc-build-sphinx: + +Build using Sphinx directly +--------------------------- + +Advanced users may want to invoke Sphinx directly, +to pass specialized options or to handle specific use cases. -See also :cpy-file:`Doc/README.rst` for more information. +Make sure the environment you :ref:`created above ` +is `activated `__. +Then, install the documentation requirements, :cpy-file:`Doc/requirements.txt`. +Using pip:: -Using sphinx-build ------------------- + python -m pip install --upgrade -r requirements.txt -Sometimes we directly want to execute the sphinx-build tool instead of through -``make`` (although the latter is still the preferred way). In this case, you can -use the following command line from the ``Doc`` directory (make sure to install -Sphinx_, blurb_ and python-docs-theme_ packages from PyPI):: +Finally, directly invoke Sphinx with:: - sphinx-build -b . build/ + python -m sphinx -b html . build/html -where ```` is one of html, text, latex, or htmlhelp (for explanations -see the make targets above). +To use a different `Sphinx builder`_, +replace ``html`` above with the desired builder ``name``. .. _docutils: https://docutils.sourceforge.io/ -.. _python-docs-theme: https://pypi.org/project/python-docs-theme/ .. _Sphinx: https://www.sphinx-doc.org/ -.. _virtualenv: https://virtualenv.pypa.io/ -.. _blurb: https://pypi.org/project/blurb/ +.. _Sphinx builder: https://www.sphinx-doc.org/en/master/usage/builders/index.html +.. _Sphinx Lint: https://github.com/sphinx-contrib/sphinx-lint +.. _venv-activate: https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#activating-a-virtual-environment +.. _venv-create: https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment Style Guide From 2c4e25520295e07642133137459a3a889b3f7519 Mon Sep 17 00:00:00 2001 From: Carl Meyer Date: Wed, 8 Mar 2023 15:15:46 -0700 Subject: [PATCH 060/538] add carljm to experts index (#1063) --- core-developers/experts.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index de70eb292..ccff8d1bf 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -85,7 +85,7 @@ codeop collections rhettinger* collections.abc rhettinger*, stutzbach^ colorsys -compileall +compileall carljm concurrent.futures pitrou, brianquinlan, gpshead* configparser ambv* contextlib ncoghlan, 1st1 @@ -97,7 +97,7 @@ crypt jafo^* csv smontanaro (inactive) ctypes theller (inactive), abalkin, amauryfa, meadori curses Yhg1s -dataclasses ericvsmith* +dataclasses ericvsmith*, carljm datetime abalkin, pganssle dbm decimal facundobatista, rhettinger, mdickinson @@ -184,7 +184,7 @@ profile pstats pty Yhg1s* pwd -py_compile +py_compile carljm pyclbr isidentical pydoc queue rhettinger* @@ -245,7 +245,7 @@ tracemalloc vstinner tty Yhg1s* turtle gregorlingl^, willingc types 1st1 -typing gvanrossum, Fidget-Spinner, JelleZijlstra*, AlexWaygood* +typing gvanrossum, Fidget-Spinner, JelleZijlstra*, AlexWaygood*, carljm unicodedata malemburg, ezio-melotti unittest voidspace*, ezio-melotti, rbtcollins, gpshead unittest.mock voidspace* @@ -318,12 +318,12 @@ Interest Area Maintainers ================== ========================================================== algorithms rhettinger* argument clinic larryhastings -ast/compiler benjaminp, 1st1, pablogsal, markshannon, isidentical, brandtbucher +ast/compiler benjaminp, 1st1, pablogsal, markshannon, isidentical, brandtbucher, carljm autoconf/makefiles Yhg1s* bsd issue tracker ezio-melotti buildbots zware, pablogsal -bytecode benjaminp, 1st1, markshannon, brandtbucher +bytecode benjaminp, 1st1, markshannon, brandtbucher, carljm context managers ncoghlan core workflow Mariatta, ezio-melotti, hugovk coverity scan tiran, Yhg1s @@ -350,7 +350,7 @@ object model benjaminp, Yhg1s packaging tarekziade, malemburg, alexis^, merwok, dstufft, pfmoore pattern matching brandtbucher* peg parser gvanrossum, pablogsal, lysnikolaou -performance vstinner, serhiy-storchaka, 1st1, rhettinger, markshannon, brandtbucher +performance vstinner, serhiy-storchaka, 1st1, rhettinger, markshannon, brandtbucher, carljm pip ncoghlan, dstufft, pfmoore, Marcus.Smith^, pradyunsg py3 transition benjaminp release management tarekziade, malemburg, benjaminp, warsaw, From 378800a007a2c596c615b4333db205121aef7cb6 Mon Sep 17 00:00:00 2001 From: Paul Hoffman Date: Sat, 11 Mar 2023 18:22:26 -0800 Subject: [PATCH 061/538] Remove stray single quote (#1064) --- documentation/markup.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index 45724a0fb..b142e497b 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -81,7 +81,7 @@ Be aware of some restrictions of this markup: These restrictions may be lifted in future versions of the docutils. -reST also allows for custom "interpreted text roles"', which signify that the +reST also allows for custom "interpreted text roles", which signify that the enclosed text should be interpreted in a specific way. Sphinx uses this to provide semantic markup and cross-referencing of identifiers, as described in the appropriate section. The general syntax is ``:rolename:`content```. From 5803a0213b5d43ee63b2ac227f12c1cf8816e1d7 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Tue, 14 Mar 2023 09:50:47 -0400 Subject: [PATCH 062/538] Don't force column widths in versions.rst (#1041) Setting `:widths:` for individual columns leads to weird wrapping, as some columns are too narrow. Just setting the table to 100% width and letting Sphinx figure out the distribution, OTOH, looks fine. Let the software be smart. Signed-off-by: FeRD (Frank Dana) --- versions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/versions.rst b/versions.rst index fd28b3f85..5225d1560 100644 --- a/versions.rst +++ b/versions.rst @@ -23,7 +23,7 @@ Dates shown in *italic* are scheduled and can be adjusted. .. csv-table:: :header-rows: 1 - :widths: 5, 5, 15, 15, 12, 40 + :width: 100% :file: include/branches.csv .. Remember to update main branch in the paragraph above too @@ -34,7 +34,7 @@ Unsupported Versions .. csv-table:: :header-rows: 1 - :widths: 5, 5, 15, 15, 12, 40 + :width: 100% :file: include/end-of-life.csv From 4e6e10fca10f865c93b525a810ad9163366e546b Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Thu, 16 Mar 2023 23:25:29 +0800 Subject: [PATCH 063/538] Overhaul the labels page to reflect current GH labeling practice (#930) * Update the triage/labels.rst page. * Remove duplicate label. * Use the `:gh-label:` role. * Use the `:cpy-file:` role. * (Re)move (mostly) BPO-related info. * Apply suggestions from code review Co-authored-by: C.A.M. Gerlach * Apply suggestions from code review Co-authored-by: C.A.M. Gerlach Co-authored-by: Hugo van Kemenade * Fix miss-islington link markup. * Add more ref targets to prevent link rotting. Co-authored-by: C.A.M. Gerlach Co-authored-by: Hugo van Kemenade * Add other two ref targets to the "Type labels" section. * Address remaining review comments. * Apply more suggestions from code review. Co-authored-by: C.A.M. Gerlach * Rephrase sentence as suggested in a review comment. * Rewrap a few long lines. * Restore and move the `Assignees` sub-section. * Fix typo. Co-authored-by: Hugo van Kemenade * Fix "triager" capitalization. Co-authored-by: Hugo van Kemenade * Document the `automerge` label. * Remove obsolete note/comment. * Minor grammar/punctuation/phrasing fixes. Co-authored-by: C.A.M. Gerlach * Final tweaks. Co-authored-by: C.A.M. Gerlach --------- Co-authored-by: C.A.M. Gerlach Co-authored-by: Hugo van Kemenade --- getting-started/pull-request-lifecycle.rst | 4 +- getting-started/setup-building.rst | 1 + triage/issue-tracker.rst | 47 +- triage/labels.rst | 483 +++++---------------- triage/triage-team.rst | 28 +- triage/triaging.rst | 17 +- 6 files changed, 181 insertions(+), 399 deletions(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index de361d2a2..5b4469e2b 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -402,6 +402,9 @@ on how to properly add the co-author info. See also :ref:`Applying a Patch to Git `. + +.. _reviewing-prs: + Reviewing ========= @@ -427,7 +430,6 @@ thus iterate until a satisfactory solution has emerged. .. _how-to-review-a-pull-request: - How to Review a Pull Request ---------------------------- diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 15e094ae2..d07db3bfe 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -577,6 +577,7 @@ support. For editors and tools which the core developers have felt some special comment is needed for coding *in* Python, see :ref:`resources`. +.. _build-directory-structure: Directory structure =================== diff --git a/triage/issue-tracker.rst b/triage/issue-tracker.rst index 976cf1891..889d71e9a 100644 --- a/triage/issue-tracker.rst +++ b/triage/issue-tracker.rst @@ -84,16 +84,44 @@ The submission form has only two fields that you need to fill: information as appropriate). In particular, *what version of Python* you were using. -Understanding the issue's progress and status ---------------------------------------------- - -There is a number of additional fields like **Assignees**, **Labels**, -**Projects**, and **Milestone**. Those are filled by triagers and core -developers, this is covered in the :ref:`triaging` page. You don't need +You can tag someone, with :samp:`@{username}` in a comment, +if you think the issue should be brought to their attention. +Use the :ref:`experts` to know who wants to be +tagged or assigned for specific areas. + +There are a number of additional fields like **Assignees**, **Labels**, +and **Projects**. Those are filled by triagers and core +developers and are covered in the :ref:`triaging` page. You don't need to worry about those when reporting issues as a Python user. -You will automatically receive an update each time an action is taken on -the bug, unless you changed your GitHub notification settings. +Adding special links +-------------------- + +The following abbreviations can be used in a comment to generate a link: + +* :samp:`GH-{NNN}`: to link to another issue or PR; +* :samp:`PEP-{NNN}`: to link to a specific PEP; +* :samp:`BPO-{NNN}`: to link to a bugs.python.org issue; + +See also the `list of autolinks supported by GitHub `_. + +Following issues +---------------- + +If you want to subscribe yourself to an issue, click the :guilabel:`🔔 Subscribe` +button in the sidebar. Similarly, if you were tagged by somebody else but +decided this issue is not for you, click the :guilabel:`🔕 Unsubscribe` +button in the sidebar. Note that you are automatically subscribed to +issues you created. + +Tracking dependencies and duplicates +------------------------------------ + +It is possible to use `checklists`_ to track dependencies or, +in case of meta-issues, to link to the other related issues. + +By writing :samp:`Duplicate of #{NNN}` in a comment, you can +`mark issues and PRs as duplicates `_. Disagreement With a Resolution on the Issue Tracker @@ -128,4 +156,7 @@ reason either as ``complete`` or ``not planned``. .. _devguide repo: https://github.com/python/devguide/issues .. _Roundup: https://roundup.sourceforge.io/ .. _Python Discourse: https://discuss.python.org/ +.. _autolinks: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/autolinked-references-and-urls +.. _checklists: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/about-task-lists +.. _duplicates: https://docs.github.com/en/issues/tracking-your-work-with-issues/marking-issues-or-pull-requests-as-a-duplicate .. _Core Development Discourse category: https://discuss.python.org/c/core-dev/23 diff --git a/triage/labels.rst b/triage/labels.rst index bcdd6bef5..4b2e6b40e 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -11,405 +11,144 @@ 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 `_. -General purpose labels -====================== -:gh-label:`type-behavior` - Used for issues/PRs that address unintentional behavior, but do not - pose significant security concerns. Generally, bugfixes will be attached - to a specific issue where the unintended behavior was first reported. +.. _general-purpose-labels: +.. _Type: +.. _labels-type: -:gh-label:`type-documentation` - Used for issues/PRs that exclusively involve changes to - the documentation. Documentation includes ``*.rst`` files, docstrings, - and code comments. +Type labels +=========== -:gh-label:`type-enhancement` - Used for issues/PRs that provide additional functionality - or capabilities beyond the existing specifications. +These labels are used to specify the type of issue: -:gh-label:`type-performance` - Used for issues/PRs that provide performance optimizations. +* :gh-label:`type-bug`: for unexpected behaviors, bugs, or exceptions + (not hard crashes). +* :gh-label:`type-crash`: for hard crashes of the interpreter, possibly with a + core dump. +* :gh-label:`type-feature`: for feature requests or enhancements. + The `Ideas Discourse category`_ can be used to discuss enhancements + before filing an issue. +* :gh-label:`type-security`: for security issues. + See also `Reporting security issues in Python`_. -:gh-label:`type-security` - Used for issues/PRs that involve critical security issues. Less severe - security concerns can instead use the type-bugfix label. -:gh-label:`type-tests` - Used for issues/PRs that exclusively involve changes to the tests. +.. _Component: +.. _labels-component: -:gh-label:`OS-Mac` / :gh-label:`OS-Windows` - Used for issues/PRs involving changes which only have an effect upon - a specific operating system. +Component labels +================ -:gh-label:`spam` - Used for issues/PRs that don't include enough eggs or bacon. +These labels are mostly used to specify which :ref:`part of the codebase +` is affected by the issue/PR: -Labels specific to issues -========================= +* :gh-label:`stdlib`: for standard library modules in the :cpy-file:`Lib` + directory (written in Python). +* :gh-label:`extension-modules`: for standard library modules in the + :cpy-file:`Modules` directory (written in C). +* :gh-label:`interpreter-core`: for changes related to the interpreter core in + the :cpy-file:`Objects`, :cpy-file:`Python`, :cpy-file:`Grammar`, + and :cpy-file:`Parser` dirs (written mostly in C). +* :gh-label:`docs`: for documentation in the :cpy-file:`Doc` directory + (written in :ref:`reStructuredText `), docstrings, and code comments. +* :gh-label:`tests`: for tests in the :cpy-file:`Lib/test` directory + (written in Python) and other changes related to tests, :mod:`unittest`, + or :mod:`doctest`. -Priority --------- -:gh-label:`release-blocker` - The highest priority of an issue. If unaddressed, will cause the - release manager to hold releasing a new version of Python. +Expert labels +============= -:gh-label:`deferred-blocker` - A release blocker that was pushed one or more releases into the - future. Possibly a temporary workaround was employed, or the version - of Python the issue is affecting is still in alpha or beta stages - of development. +These labels are used to specify the area of expertise required to address +the issue/PR. This includes both specific modules/packages and generic +interest areas. -Component ---------- +Adding these labels is also a way to notify the relevant experts, since +they are encouraged to subscribe to them. Depending on the label, +this might also automatically add the issue to a GitHub project. -:gh-label:`library` - Used for issues involving Python modules in the ``Lib/`` dir. +You can see the `full list of expert labels on GitHub +`_. -:gh-label:`docs` - Used for issues involving documentation in the ``Doc/`` dir. -:gh-label:`interpreter-core` - Used for issues in interpreter core (``Objects/``, ``Python/``, - ``Grammar/``, and ``Parser/`` dirs). +OS labels +========= -:gh-label:`extension-modules` - Used for issues involving C modules in the ``Modules/`` dir. +These labels are used to specify which operating systems are affected. +Since most issues either affect all systems or are specific to Unix, +the only available labels are :gh-label:`OS-windows`, :gh-label:`OS-mac`, +and :gh-label:`OS-freebsd`. -:gh-label:`tests` - Used for issues involving only Python's regression test suite, i.e. - files in the ``Lib/test/`` dir. -Other ------ +Version labels +============== -:gh-label:`new` - Denotes that the issue hasn't been looked at by triagers or core - developers yet. +These labels are used to indicate which versions of Python are affected. +The available version labels (with the form :samp:`3.{N}`) are updated +whenever new major releases are created or retired. -:gh-label:`easy` - Denotes that the issue is a good candidate for a newcomer to address. +See also :ref:`the branch status page ` +for a list of active branches. -Labels specific to PRs -====================== +.. _Keywords: +.. _Other: +.. _Priority: +.. _labels-other: + +Other labels +============ -:gh-label:`DO-NOT-MERGE` - Used on PRs to prevent miss-islington from being able - to automatically merge the pull request. This label is appropriate when a PR - has a non-trivial conflict with the branch it is being merged into. - -:gh-label:`expert-asyncio` - Used for PRs which involve changes to the asyncio module - or other asynchronous frameworks that utilize it. - -:gh-label:`invalid` - Used manually for PRs that do not meet basic requirements and - automatically added by bedevere when PR authors attempt to merge maintenance - branches into the main branch. During events such as the October - Hacktoberfest, this label will prevent the PR from counting toward the - author's contributions. - -needs backport to X.Y - For example, :gh-label:`needs backport to 3.11`. - Used for PRs which are appropriate to backport to - branches prior to main. Generally, backports to the maintenance branches - are primarily bugfixes and documentation clarifications. Backports to the - security branches are strictly reserved for PRs involving security fixes, such as - crashes, privilege escalation, and DoS. The use of this label will cause - miss-islington to attempt to automatically merge the PR into the branches - specified. - -:gh-label:`skip issue` - Used for PRs which involve trivial changes, such as typo fixes, - comment changes, and section rephrases. The majority of PRs require - an issue to be attached to, but if there are no code changes and the - section being modified retains the same meaning, this label might be - appropriate. - -:gh-label:`skip news` - Similar to the skip issue label, this label is used for PRs which - involve trivial changes, backports, or already have a relevant news entry - in another PR. Any potentially impactful changes should have a - corresponding news entry, but for trivial changes it's commonly at the - discretion of the PR author if they wish to opt-out of making one. - -:gh-label:`sprint` - Used for PRs authored during an in-person sprint, such as - at PyCon, EuroPython, or other official Python events. The label is - used to prioritize the review of those PRs during the sprint. - -:gh-label:`stale` - Used for PRs that include changes which are no longer relevant, or when the - author hasn't responded to feedback in a long period of time, or when the - reviewer is unresponsive. This label helps core developers quickly identify - PRs that are candidates for closure or require a ping to the author or - reviewer. - -:gh-label:`awaiting review` - Used for PRs that haven't been reviewed by anyone yet. - -:gh-label:`awaiting core review` - Used when the PR is authored by a core developer or when a non-core - developer has reviewed the PR, even if they requested changes. - Note that reviewers could have been added manually by a triager or core - developer, or included automatically through use of the `CODEOWNERS - `_ - file. - -:gh-label:`awaiting changes` - A reviewer required changes to proceed with the PR. - -:gh-label:`awaiting change review` - The PR author made requested changes, and they are waiting for review. - -:gh-label:`awaiting merge` - The PR has been approved by a core developer and is ready to merge. - -:gh-label:`test-with-buildbots` - Used on PRs to test the latest commit with the buildbot fleet. Generally for - PRs with large code changes requiring more testing before merging. This - may take multiple hours to complete. Triagers can also stop a stuck build - using the web interface. +* :gh-label:`triaged`: for issue has been accepted as valid by a triager. +* :gh-label:`easy`: for issues that are considered easy. +* :gh-label:`build`/:gh-label:`performance`: for issues related + to the build process or performance, respectively. +* :gh-label:`release-blocker`/:gh-label:`deferred-blocker`: for issues/PRs + that, unless fixed, will hold the current or next release respectively. + Triagers may set these labels for issues that must be fixed before a release, + and the :ref:`branch's release manager ` + will review them and determine if they indeed qualify, + removing or retaining the label as appropriate. +* :gh-label:`pending`: for issues/PRs that will be closed unless further + feedback is provided. +* :gh-label:`stale`: for issues/PRs that have been inactive for a while. +* :gh-label:`sprint`: for easier filtering of issues/PRs being worked on + during official sprints. +.. _GitHub Labels for PRs: .. _github-pr-labels: -GitHub Labels for PRs -===================== - -An important component of triaging PRs for the CPython repo involves -appropriately categorizing them through the usage of labels. For this -purpose we're using :ref:`gh-labels`. - -Applying labels for Issues -========================== - -The major elements found in an issue report include: - -* Classification (including *Title*) - Metadata that lets us categorize - the issue. Apart from the *Title* field, we use some *type-*, *component-*, and - *version-* specific labels. -* Process - These fields indicate the state of the issue and its progress - toward resolution. The fields are *Status* (open/closed), *Assignees*, - *Comment*, as well as *priority-* and *keyword-* specific labels. -* Messages -* History - -Title ------ -A brief description of the issue. Review whether the title is too generic or -specifies an incorrect term or library. - -(Optional) Add a prefix at the start of the title to indicate the module, e.g. -IDLE, doc, or asyncio. - -Type ----- -Describes the type of issue. If an issue does not fit within any -specific type, please do not set a type. - -+----------------+----------------------------------------------------------+ -| Type | Description | -+================+==========================================================+ -| behavior | Unexpected behavior, result, or exception. Most bugs | -| | will have this type. This group also includes compile | -| | errors, and crashers. | -+----------------+----------------------------------------------------------+ -| enhancement | Issues that propose the addition of new functionality, | -| | such as new functions, classes, modules, or even new | -| | arguments for existing functions. Also used for | -| | improvements in the documentation, test suite and | -| | other refactorings. A good place to discuss enhancements | -| | prior to filing an issue is the | -| | `Ideas Discourse category`_. | -+----------------+----------------------------------------------------------+ -| performance | Situations where too much time is necessary to complete | -| | the task. For example, a common task now takes | -| | significantly longer to complete. This group also | -| | includes resource usage (e.g. too much memory needed) | -| | issues. | -+----------------+----------------------------------------------------------+ -| security | Issues that might have security implications. Report | -| | security vulnerabilities using the procedure found in | -| | the `Reporting security issues in Python`_ page on the | -| | python.org website. | -+----------------+----------------------------------------------------------+ - -Stage ------ -A needed next action to advance the issue. The *stage* on GitHub issues is -determined by presence of a linked PR and whether the issue is still open -or closed. It is the PR that holds code review-related labels. - -Components ----------- -The area or Python library affected by the issue. A single issue can apply -multiple component labels. - -One or more components may be selected for an issue: - -+-------------------+------------------------------------------------------+ -| Component | Description | -+===================+======================================================+ -| Documentation | The documentation in Doc_ (source used to build HTML | -| | docs for https://docs.python.org/). | -+-------------------+------------------------------------------------------+ -| Extension Modules | C modules in Modules_. | -+-------------------+------------------------------------------------------+ -| Interpreter Core | The interpreter core. | -| | The built-in objects in `Objects`_, the `Python`_, | -| | `Grammar`_ and `Parser`_ dirs. | -+-------------------+------------------------------------------------------+ -| Library (Lib) | Python modules in Lib_. | -+-------------------+------------------------------------------------------+ -| Tests | The unittest framework in `Lib/unittest`_ | -| | The doctest framework `Lib/doctest.py`_. | -| | The CPython tests in `Lib/test`_. | -| | The test runner in `Lib/test/regrtest.py`_. | -| | The test support utilities in `Lib/test/support`_. | -+-------------------+------------------------------------------------------+ - -Versions --------- -The known versions of Python that the issue affects and should be fixed for. - -Thus if an issue for a new feature is assigned for e.g., Python 3.8 but is not -applied before Python 3.8.0 is released, this label should be updated to say -``python-3.9`` as the version and drop ``python-3.8``. - -Priority --------- -What is the severity and urgency? - -+------------------+--------------------------------------------------------+ -| Priority | Description | -+==================+========================================================+ -| normal | The default value for most issues filed. | -+------------------+--------------------------------------------------------+ -| deferred blocker | The issue will not hold up the next release, *n*. It | -| | will be promoted to a *release blocker* for the | -| | following release, *n+1*. | -+------------------+--------------------------------------------------------+ -| release blocker | The issue **must** be fixed before *any* release is | -| | made, e.g., will block the next release even if it is | -| | an alpha release. | -+------------------+--------------------------------------------------------+ - -As a guideline, whether a bug is a *release blocker* for the current -:ref:`release schedule ` is decided by the release manager. -Triagers may recommend this priority and should notify the release manager by -tagging them in a comment using ``@username``. If needed, consult the -:ref:`release schedule ` and the release's associated PEP for the -release manager's name. - -Keywords --------- -Various informational flags about the issue. Multiple values are possible. - -+---------------+------------------------------------------------------------+ -| Keyword | Description | -+===============+============================================================+ -| easy | Fixing the issue should not take longer than a day for | -| | someone new to contributing to Python to solve. | -+---------------+------------------------------------------------------------+ - -Nosy List ---------- -A list of people who may be interested in an issue. - -This used to be a feature of the old issue tracker. On GitHub issues the -same effect is achieved by tagging people in a comment using ``@username``. - -It is acceptable to tag someone to if you think the issue should be brought to -their attention. Use the :ref:`experts` to know who wants to be added to the -nosy list for issues targeting specific areas. - -If you want to subscribe yourself to an issue, click the *🔔 Subscribe* -button in the sidebar. Similarly, if you were tagged by somebody else but -decided this issue is not for you, you might click the *🔕 Unsubscribe* -button in the sidebar. - -Assignees ---------- -Who is expected to take the next step in resolving the issue. - -It is acceptable to assign an issue to someone if the issue cannot move -forward without their help, e.g., they need to make a technical decision to -allow the issue to move forward. Also consult the :ref:`experts` as certain -stdlib modules should always be assigned to a specific person. - -Note that in order to assign an issue to someone, that person **must** be -a team member, likely a Triager or a core developer. - -Dependencies ------------- -The issue requires the listed issue(s) to be resolved first before it can move -forward. This is achieved using checkbox lists in the initial issue description -comment. Long story short, if you add this:: - - - [x] #739 - - [ ] https://github.com/octo-org/octo-repo/issues/740 - - [ ] Add delight to the experience when all tasks are complete :tada: - -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 -`_. - -Superseder ----------- -The issue is a duplicate of the listed issue(s). To make GitHub mark -an issue as duplicate, write "Duplicate of #xxxx" in a comment. - -Status ------- - -+---------------+------------------------------------------------------------+ -| Status | Description | -+===============+============================================================+ -| open | Issue is not resolved. | -+---------------+------------------------------------------------------------+ -| closed | The issue has been resolved (somehow). | -+---------------+------------------------------------------------------------+ - -Linked pull requests --------------------- -A link might be added manually using the cog icon next to this field. -Most commonly though, if the PR includes "Fixes #xxx" in its description, -the link will be added automatically. - -Generating Special Links in a Comment -===================================== -Using the following abbreviations in a comment will automatically generate -a link to relevant web pages. - -+-------------------------------------------------------------+-------------------------------------------------------+ -| Comment abbreviation | Description | -+=============================================================+=======================================================+ -| ``#``, | Links to the tracker issue or PR ```` (they | -| ``GH-`` | share the same sequence of integers on GitHub). | -+-------------------------------------------------------------+-------------------------------------------------------+ -| ``BPO-`` | Links to the old bug tracker at bugs.python.org. | -+-------------------------------------------------------------+-------------------------------------------------------+ -| a 10-, 11-, 12-, or 40-digit hex ```` | Indicates a Git changeset identifier and | -| | generates a link to changeset ```` on GitHub. | -+-------------------------------------------------------------+-------------------------------------------------------+ - -.. _Doc: https://github.com/python/cpython/tree/main/Doc/ -.. _Grammar: https://github.com/python/cpython/tree/main/Grammar/ -.. _Lib: https://github.com/python/cpython/tree/main/Lib/ -.. _Lib/doctest.py: https://github.com/python/cpython/blob/main/Lib/doctest.py -.. _Lib/test: https://github.com/python/cpython/tree/main/Lib/test/ -.. _Lib/test/regrtest.py: https://github.com/python/cpython/blob/main/Lib/test/regrtest.py -.. _Lib/test/support: https://github.com/python/cpython/tree/main/Lib/test/support/ -.. _Lib/unittest: https://github.com/python/cpython/tree/main/Lib/unittest/ -.. _Modules: https://github.com/python/cpython/tree/main/Modules/ -.. _Objects: https://github.com/python/cpython/tree/main/Objects/ -.. _Parser: https://github.com/python/cpython/tree/main/Parser/ -.. _Python: https://github.com/python/cpython/tree/main/Python/ +Labels specific to PRs +====================== + +The following labels only apply to :ref:`Pull Requests `. +They are either set automatically by bots, or added by humans +to trigger specific bot behaviors. + +* :gh-label:`automerge`: for automatically merging PRs approved + by a core dev once all CI checks pass. +* :gh-label:`DO-NOT-MERGE`: for PRs that shouldn't be merged in their current + state. It also prevents `miss-islington`_ from being able to automatically + merge the PR. +* :samp:`needs backport to {X.Y}`: used to indicate which branches the PR + should be backported to. Once the PR is merged, ``miss-islington`` will + automatically attempt to create backport PRs for the versions indicated + by these labels. + See also :ref:`the status of the Python branches ` for a list + of branches and the type of PRs that can be backported to them. +* :gh-label:`skip issue`: for trivial changes (such as typo fixes, comment + changes, and section rephrases) that don't require a corresponding issue. +* :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 + 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`_ + to indicate the stage of a PR and should not be applied manually. + + .. _Reporting security issues in Python: https://www.python.org/dev/security/ .. _Ideas Discourse category: https://discuss.python.org/c/ideas/6 +.. _miss-islington: https://github.com/python/miss-islington +.. _bedevere: https://github.com/python/bedevere/#pr-state-machine diff --git a/triage/triage-team.rst b/triage/triage-team.rst index c901d0d52..a3e703595 100644 --- a/triage/triage-team.rst +++ b/triage/triage-team.rst @@ -16,15 +16,11 @@ needed, to other repos such as devguide and core-workflow. Responsibilities include: -* PR/issue management - - Reviewing PRs - - Assisting contributors - - Notifying appropriate core developers -* Applying appropriate labels to PRs/Issues - - Skip news - - Skip issue - - Good first issue - - Other categorizations +* Classifying issues and PRs +* Applying appropriate :ref:`labels ` to issues/PRs +* Notifying appropriate core developers +* :ref:`Reviewing PRs ` +* Assisting contributors Although triagers have the power to close PRs, they should generally not do so without first consulting a core developer. By having triagers and core developers work together, @@ -43,12 +39,12 @@ following: - PRs proposing changes that have been rejected by Python core developers elsewhere (e.g. in an issue or a PEP rejection notice) -If a triager has any doubt about whether to close a PR, they should consult a core -developer before taking any action. +If a triager has any doubt about whether to close a PR, +they should consult a core developer before taking any action. -Triagers can also make use of the ``invalid`` and ``stale`` labels to suggest that a -PR may be suitable for closure. For more information, see the -:ref:`GitHub PR labels ` section. +Triagers can also make use of the :gh-label:`pending` and :gh-label:`stale` +labels to suggest that a PR may be suitable for closure. +For more information, see the entries in the :ref:`labels-other` section. Note that it is of paramount importance to treat every contributor to the Python project kindly and with respect. Regardless of whether they're entirely new @@ -69,8 +65,8 @@ more repositories than just CPython. When you have consistently shown the ability to properly help triage issues without guidance, you may request that you -be given the "Triager" role on the :ref:`issue tracker `. You can make the request -to any core developer. If they decide you are ready +be given the "Triager" role on the :ref:`issue tracker `. +You can make the request to any core developer. If they decide you are ready to gain the extra privileges on the tracker they will then act as a mentor to you until you are ready to do things entirely on your own. There is no set rule as to how many issues you need to have helped with before or how long you have diff --git a/triage/triaging.rst b/triage/triaging.rst index 0fcb7f588..9e0a62155 100644 --- a/triage/triaging.rst +++ b/triage/triaging.rst @@ -24,9 +24,22 @@ Checklist for Triaging * If the issue is clearly invalid (unrelated to CPython, duplicate, spam, etc), you can close it as "not planned". -.. Remove note once python/core-workflow#460 is implemented +Assignees +--------- -.. note:: Some of these fields can only be set/edited by core developers. +This field indicates who is expected to take the next step in resolving +the issue. + +It is acceptable to assign an issue to someone if the issue cannot move +forward without their help; e.g., they need to make a technical decision on +how to proceed. Also consult the :ref:`experts` as certain +stdlib modules should always be assigned to a specific person. + +Note that in order to assign an issue to someone, that person **must** be +a team member, likely a triager or a core developer. + +.. The Assignees subsection was copied from the labels.rst page in #930. + For consistency, the other fields mentioned above should be documented too. .. _helptriage: From d3a9a8a4d5e54b2a1aabbd9559ee7cbea3454585 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 21 Mar 2023 17:46:20 -0700 Subject: [PATCH 064/538] Add Barney Gale as a core dev --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index bedfbdf69..d89e0992a 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Barney Gale,barneygale,2023-03-21,, Carl Meyer,carljm,2023-02-28,, Pradyun Gedam,pradyunsg,2023-01-30,, Shantanu Jain,hauntsaninja,2022-12-19,, From d731241fe9e719bb695b6551ae26bc0ca0ad2e5c Mon Sep 17 00:00:00 2001 From: Atsuo Ishimoto Date: Tue, 28 Mar 2023 22:21:55 +0900 Subject: [PATCH 065/538] Add Atsuo Ishimoto to the Japanese translation team --- documentation/translating.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 19a8d72ec..8f4ad8a73 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -36,7 +36,11 @@ in production; others are works in progress. | Italian (it) | | `mail `_ | +-----------------+-------------------------------+----------------------------+ | Japanese (ja) | `Kinebuchi Tomohiko | `GitHub `_ | -| | (@cocoatomo) `_| `Doc `_ | +| | (@cocoatomo) | `Doc `_ | +| | `_, | | +| | `Atsuo Ishimoto | | +| | (@atsuoishimoto) | | +| | `_ | | +-----------------+-------------------------------+----------------------------+ | Korean (ko) | | `GitHub `_ | | | | `Doc `_ | @@ -83,6 +87,7 @@ in production; others are works in progress. .. _article_pt_br: https://rgth.co/blog/python-ptbr-cenario-atual/ .. _gh_cocoatomo: https://github.com/cocoatomo +.. _gh_atsuoishimoto: https://github.com/atsuoishimoto .. _gh_gbtami: https://github.com/gbtami .. _gh_kushal: https://github.com/Kushal997-das .. _gh_maciek: https://github.com/m-aciek From c1d0c96ecf470a1c7e2a019b6f37e38075a41b56 Mon Sep 17 00:00:00 2001 From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Sat, 1 Apr 2023 10:27:08 +0530 Subject: [PATCH 066/538] Add experts for runtime lifecycle management (#1068) --- core-developers/experts.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index ccff8d1bf..5b864defe 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -356,6 +356,7 @@ py3 transition benjaminp release management tarekziade, malemburg, benjaminp, warsaw, gvanrossum, anthonybaxter^, merwok, ned-deily, birkenfeld, JulienPalard +runtime lifecycle ericsnowcurrently, kumaraditya303, zooba str.format ericvsmith* subinterpreters ericsnowcurrently, kumaraditya303 testing voidspace, ezio-melotti From 79e1a1f2961ba0882d5f0274f7c8876e36ca5dff Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 5 Apr 2023 23:27:51 +0300 Subject: [PATCH 067/538] Python 3.10 now only accepts security fixes (#1073) --- 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 df82e64ed..b310429e5 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -18,7 +18,7 @@ "3.10": { "branch": "3.10", "pep": 619, - "status": "bugfix", + "status": "security", "first_release": "2021-10-04", "end_of_life": "2026-10", "release_manager": "Pablo Galindo Salgado" From 4d5e7d4dad580303352267b7ba61b41789747b2c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 17 Apr 2023 04:04:16 -0600 Subject: [PATCH 068/538] Rename expert labels to topic labels (#1076) * Rename expert labels to topic labels * Alphabetise sections * Update wording Co-authored-by: C.A.M. Gerlach * Add reST target for 'Topic labels' --------- Co-authored-by: C.A.M. Gerlach --- triage/labels.rst | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/triage/labels.rst b/triage/labels.rst index 4b2e6b40e..89637509e 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -54,11 +54,22 @@ These labels are mostly used to specify which :ref:`part of the codebase (written in Python) and other changes related to tests, :mod:`unittest`, or :mod:`doctest`. +OS labels +========= -Expert labels -============= +These labels are used to specify which operating systems are affected. +Since most issues either affect all systems or are specific to Unix, +the only available labels are :gh-label:`OS-windows`, :gh-label:`OS-mac`, +and :gh-label:`OS-freebsd`. + + +.. _Expert labels: +.. _Topic labels: + +Topic labels +============ -These labels are used to specify the area of expertise required to address +These labels are used to denote the specific topic area, if any, of the issue/PR. This includes both specific modules/packages and generic interest areas. @@ -66,17 +77,8 @@ Adding these labels is also a way to notify the relevant experts, since 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 expert labels on GitHub -`_. - - -OS labels -========= - -These labels are used to specify which operating systems are affected. -Since most issues either affect all systems or are specific to Unix, -the only available labels are :gh-label:`OS-windows`, :gh-label:`OS-mac`, -and :gh-label:`OS-freebsd`. +You can see the `full list of topic labels on GitHub +`_. Version labels From 0c57537b1f73cb134264a6d4a8c940324de36d64 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 19 Apr 2023 17:12:59 +0200 Subject: [PATCH 069/538] PEP 689: Add docs for unstable C API (#1060) Add docs for unstable C API (PEP 689) Co-authored-by: C.A.M. Gerlach Co-authored-by: Ezio Melotti --- developer-workflow/c-api.rst | 133 +++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 12 deletions(-) diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index 3e6199f8e..daa694814 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -4,18 +4,20 @@ Changing Python's C API ======================= -The C API is divided into three sections: +The C API is divided into these tiers: 1. The internal, private API, available with ``Py_BUILD_CORE`` defined. Ideally declared in ``Include/internal/``. Any API named with a leading underscore is also considered private. -2. The public C API, available when ``Python.h`` is included normally. +2. The Unstable C API, identified by the ``PyUnstable_`` name prefix. + Ideally declared in :cpy-file:`Include/cpython/` along with the general public API. +3. The “general” public C API, available when :cpy-file:`Include/Python.h` is included normally. Ideally declared in ``Include/cpython/``. -3. The Limited API, available with ``Py_LIMITED_API`` defined. +4. The Limited C API, available with :c:macro:`Py_LIMITED_API` defined. Ideally declared directly under ``Include/``. -Each section has higher stability & maintenance requirements, and you will -need to think about more issues when you add or change definitions in it. +Each tier has different stability and maintenance requirements to consider +when you add or change definitions in it. The compatibility guarantees for public C API are explained in the user documentation, ``Doc/c-api/stable.rst`` (:ref:`python:stable`). @@ -29,6 +31,11 @@ for building CPython itself, as indicated by a macro like ``Py_BUILD_CORE``. While internal API can be changed at any time, it's still good to keep it stable: other API or other CPython developers may depend on it. +For users, internal API is sometimes the best workaround for a thorny problem +--- though those use cases should be discussed on the +`C API Discourse category `_ +or an issue so we can try to find a supported way to serve them. + With PyAPI_FUNC or PyAPI_DATA ----------------------------- @@ -36,6 +43,7 @@ With PyAPI_FUNC or PyAPI_DATA Functions or structures in ``Include/internal/`` defined with ``PyAPI_FUNC`` or ``PyAPI_DATA`` are internal functions which are exposed only for specific use cases like debuggers and profilers. +Ideally, these should be migrated to the :ref:`unstable-capi`. With the extern keyword @@ -53,14 +61,18 @@ Private names -------------- Any API named with a leading underscore is also considered internal. -There are two main use cases for using such names rather than putting the -definition in ``Include/internal/`` (or directly in a ``.c`` file): +There is currently only one main use case for using such names rather than +putting the definition in :cpy-file:`Include/internal/` (or directly in a ``.c`` file): + +* Internal helpers for other public APIs, which users should not call directly. + +Note that historically, underscores were used for APIs that are better served by +the :ref:`unstable-capi`: + +* “provisional” APIs, included in a Python release to test real-world + usage of new APIs; +* APIs for very specialized uses like JIT compilers. -* Internal helpers for other public API; users should not use these directly; -* “Provisional” API, included in a Python release to test real-world usage - of new API. Such names should be renamed when stabilized; preferably with - a macro aliasing the old name to the new one. - See :pep:`"Finalizing the API" in PEP 590 <590#finalizing-the-api>` for an example. Internal API Tests ------------------ @@ -134,6 +146,103 @@ When moving existing tests, feel free to replace ``TestError`` with ``PyExc_AssertionError`` unless actually testing custom exceptions. +.. _unstable-capi: + +Unstable C API +============== + +The unstable C API tier is meant for extensions that need tight integration +with the interpreter, like debuggers and JIT compilers. +Users of this tier may need to change their code with every minor release. + +In many ways, this tier is like the general C API: + +- it's available when ``Python.h`` is included normally, +- it should be defined in :cpy-file:`Include/cpython/`, +- it requires tests, so we don't break it unintentionally +- it requires docs, so both we and the users, + can agree on the expected behavior, +- it is tested and documented in the same way. + +The differences are: + +- Names of functions structs, macros, etc. start with the ``PyUnstable_`` + prefix. This defines what's in the unstable tier. +- The unstable API can change in minor versions, without any deprecation + period. +- A stability note appears in the docs. + This happens automatically, based on the name + (via :cpy-file:`Doc/tools/extensions/c_annotations.py`). + +Despite being “unstable”, there are rules to make sure third-party code can +use this API reliably: + +* Changes and removals can be done in minor releases + (:samp:`3.{x}.0`, including Alphas and Betas for :samp:`3.{x}.0`). +* Adding a new unstable API *for an existing feature* is allowed even after + Beta feature freeze, up until the first Release Candidate. + Consensus on the `Core Development Discourse `_ + is needed in the Beta period. +* Backwards-incompatible changes should make existing C callers fail to compile. + For example, arguments should be added/removed, or a function should be + renamed. +* When moving an API into or out of the Unstable tier, the old name + should continue to be available (but deprecated) until an incompatible + change is made. In other words, while we're allowed to break calling code, + we shouldn't break it *unnecessarily*. + + +Moving an API from the public tier to Unstable +---------------------------------------------- + +* Expose the API under its new name, with the ``PyUnstable_`` prefix. +* Make the old name an alias (e.g. a ``static inline`` function calling the + new function). +* Deprecate the old name, typically using :c:macro:`Py_DEPRECATED`. +* Announce the change in the "What's New". + +The old name should continue to be available until an incompatible change is +made. Per Python’s backwards compatibility policy (:pep:`387`), +this deprecation needs to last at least two releases +(modulo Steering Council exceptions). + +The rules are relaxed for APIs that were introduced in Python versions +before 3.12, when the official Unstable tier was added. +You can make an incompatible change (and remove the old name) +as if the function was already part of the Unstable tier +for APIs introduced before Python 3.12 that are either: + +* Documented to be less stable than default. +* Named with a leading underscore. + +Moving an API from the private tier to unstable +----------------------------------------------- + +* Expose the API under its new name, with the ``PyUnstable_`` prefix. +* If the old name is documented, or widely used externally, + make it an alias and deprecate it (typically with :c:macro:`Py_DEPRECATED`). + It should continue to be available until an incompatible change is made, + as if it was previously public. + + This applies even to underscored names. Python wasn't always strict with + the leading underscore. +* Announce the change in What's New. + +Moving an API from unstable to public +------------------------------------- + +* Expose the API under its new name, without the ``PyUnstable_`` prefix. +* Make the old ``PyUnstable_*`` name be an alias (e.g. a ``static inline`` + function calling the new function). +* Announce the change in What's New. + +The old name should remain available until the +new public name is deprecated or removed. +There's no need to deprecate the old name (it was unstable to begin with), +but there's also no need to break working code just because some function +is now ready for a wider audience. + + Limited API =========== From 9d7562adb8f3313bb4bff78901b005fa767fc031 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 21 Apr 2023 07:03:43 -0700 Subject: [PATCH 070/538] Add C.A.M. Gerlach to the core developers list (#1083) --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index d89e0992a..2939f8e5d 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +C.A.M. Gerlach,CAM-Gerlach,2023-04-19,, Barney Gale,barneygale,2023-03-21,, Carl Meyer,carljm,2023-02-28,, Pradyun Gedam,pradyunsg,2023-01-30,, From 80c93e6dec8b8b288b1c37ba9039c6b0b7d66cf8 Mon Sep 17 00:00:00 2001 From: gantanikhilraj <112814295+gantanikhilraj@users.noreply.github.com> Date: Mon, 24 Apr 2023 10:01:16 +0530 Subject: [PATCH 071/538] Removed "automerge" label (#1082) --- triage/labels.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/triage/labels.rst b/triage/labels.rst index 89637509e..95e84558b 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -127,8 +127,6 @@ The following labels only apply to :ref:`Pull Requests `. They are either set automatically by bots, or added by humans to trigger specific bot behaviors. -* :gh-label:`automerge`: for automatically merging PRs approved - by a core dev once all CI checks pass. * :gh-label:`DO-NOT-MERGE`: for PRs that shouldn't be merged in their current state. It also prevents `miss-islington`_ from being able to automatically merge the PR. From 3978ed338410d05eb93c0a751b757288dcee5b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 25 Apr 2023 01:50:04 +0200 Subject: [PATCH 072/538] Document auto-merge (#1084) --- core-developers/committing.rst | 3 +- getting-started/git-boot-camp.rst | 69 ++++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 21 deletions(-) diff --git a/core-developers/committing.rst b/core-developers/committing.rst index 74c10bbf1..256fda9d1 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -191,7 +191,8 @@ Seeing active branches If you use ``git branch``, then you will see a :ref:`list of branches `. The only branch that receives new features is ``main``, the in-development branch. The other branches receive only -bug fixes or security fixes. +bug fixes or security fixes. In almost all cases the fixes should first +originate on ``main`` and then be ported back to older branches. .. _branch-merge: diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index e29dc1e05..e27c4b06a 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -461,37 +461,66 @@ Accepting and Merging a Pull Request ------------------------------------ Pull requests can be accepted and merged by a Python Core Developer. +You can read more about what to look for before accepting a change +:ref:`here `. -1. At the bottom of the pull request page, click the ``Squash and merge`` - button. +All pull requests have required checks that need to pass before a change +can be merged. After a change was accepted by at least one core +developer review, you can schedule an automatic merge of the change by +clicking the gray ``Enable auto-merge (squash)`` button. You will find +it at the bottom of the pull request page. The auto-merge will only +happen if all the required checks pass. -2. Replace the reference to GitHub pull request ``#NNNN`` with ``GH-NNNN``. - If the title is too long, the pull request number can be added to the - message body. +If all required checks are already finished on a PR you're reviewing, +in place of the gray ``Enable auto-merge`` button you will find a green +``Squash and merge`` button. -3. Adjust and clean up the commit message. +In either case, adjust and clean up the commit message. - Example of good commit message:: +Here's an example of a **good** commit message:: - gh-12345: Improve the spam module (GH-777) + gh-12345: Improve the spam module (GH-777) - * Add method A to the spam module - * Update the documentation of the spam module + * Add method A to the spam module + * Update the documentation of the spam module - Example of bad commit message:: +Here's an example of a **bad** commit message:: - gh-12345: Improve the spam module (#777) + gh-12345: Improve the spam module (#777) - * Improve the spam module - * merge from main - * adjust code based on review comment - * rebased + * Improve the spam module + * merge from main + * adjust code based on review comment + * rebased - .. note:: - `How to Write a Git Commit Message `_ - is a nice article describing how to write a good commit message. +The bad example contains bullet points that are a direct effect of the +PR life cycle, while being irrelevant to the final change. -4. Press the ``Confirm squash and merge`` button. +.. note:: + `How to Write a Git Commit Message `_ + is a nice article describing how to write a good commit message. + +Finally, press the ``Confirm squash and merge`` button. + +Cancelling an Automatic Merge +----------------------------- + +If you notice a problem with a pull request that was accepted and where +auto-merge was enabled, you can still cancel the workflow before GitHub +automatically merges the change. + +Press the gray "Disable auto-merge" button on the bottom of the +pull request page to disable automatic merging entirely. This is the +recommended approach. + +To pause automatic merging, apply the "DO-NOT-MERGE" label to the PR or +submit a review requesting changes. The latter will put an "awaiting +changes" label on the PR, which pauses the auto-merge similarly to +"DO-NOT-MERGE". After the author submits a fix, re-requests review, and +receives a new accepting review, auto-merge will complete. + +Note that pushing new changes after the auto-merge flow was enabled +does **NOT** stop it. Backporting Merged Changes -------------------------- From 83ab46999c198e5ddd833ae9832a76f117af8919 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 24 Apr 2023 18:57:28 -0600 Subject: [PATCH 073/538] Minor corrections to instructions regarding automerge (#1085) --- getting-started/git-boot-camp.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index e27c4b06a..6332a8f59 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -465,11 +465,12 @@ You can read more about what to look for before accepting a change :ref:`here `. All pull requests have required checks that need to pass before a change -can be merged. After a change was accepted by at least one core -developer review, you can schedule an automatic merge of the change by +can be merged. At any point, a core developer can schedule an automatic merge +of the change by clicking the gray ``Enable auto-merge (squash)`` button. You will find it at the bottom of the pull request page. The auto-merge will only -happen if all the required checks pass. +happen if all the required checks pass, but the PR does not need to have been +approved for a successful auto-merge to take place. If all required checks are already finished on a PR you're reviewing, in place of the gray ``Enable auto-merge`` button you will find a green @@ -516,8 +517,9 @@ recommended approach. To pause automatic merging, apply the "DO-NOT-MERGE" label to the PR or submit a review requesting changes. The latter will put an "awaiting changes" label on the PR, which pauses the auto-merge similarly to -"DO-NOT-MERGE". After the author submits a fix, re-requests review, and -receives a new accepting review, auto-merge will complete. +"DO-NOT-MERGE". After the author submits a fix and re-requests review, you can +resume the auto-merge process either by submitting an approving review or by +dismissing your previous review that requested changes. Note that pushing new changes after the auto-merge flow was enabled does **NOT** stop it. From f99c19e7f62fda7320363b75d48b052f6259dc50 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Wed, 26 Apr 2023 10:48:34 -0600 Subject: [PATCH 074/538] Add willingc as asyncio expert and update motivation entry (#1086) --- core-developers/experts.rst | 2 +- core-developers/motivations.rst | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 5b864defe..75b599b66 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -62,7 +62,7 @@ argparse array ast benjaminp, pablogsal, isidentical asynchat josiahcarlson, giampaolo*, stutzbach^ -asyncio 1st1, asvetlov, gvanrossum, graingert, kumaraditya303 +asyncio 1st1, asvetlov, gvanrossum, graingert, kumaraditya303, willingc asyncore josiahcarlson, giampaolo*, stutzbach^ atexit audioop serhiy-storchaka diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index 1c813730d..625c763d9 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -259,15 +259,15 @@ participating in the CPython core development process: .. topic:: Carol Willing (United States) - * Noteable: ``__ (Technical Evangelist) + * Noteable: ``__ (VP Engineering) * Personal site: `Willing Consulting `_ * `Extended bio `__ - * Project Jupyter (Steering Council, Core Team for JupyterHub/Binder) + * Project Jupyter (Software Council, Core Team for JupyterHub/Binder) * Python Software Foundation (Fellow) Carol is focused on Python's usage in education and scientific research. - She is interested in organizational development, operational workflows, - and sustainability of open source projects. + She is interested in distributed computing, organizational development, + operational workflows, and sustainability of open source projects. .. _goals-of-the-motivations-page: From b852b8ae20f8fc6a1bf42e9d4f6bb482e713bfc1 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 30 Apr 2023 15:52:37 +0300 Subject: [PATCH 075/538] Experts Index: Remove deleted modules (#1088) --- core-developers/experts.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 75b599b66..5eed53021 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -61,15 +61,12 @@ aifc bitdancer argparse array ast benjaminp, pablogsal, isidentical -asynchat josiahcarlson, giampaolo*, stutzbach^ asyncio 1st1, asvetlov, gvanrossum, graingert, kumaraditya303, willingc -asyncore josiahcarlson, giampaolo*, stutzbach^ atexit audioop serhiy-storchaka base64 bdb binascii -binhex bisect rhettinger* builtins bz2 @@ -115,7 +112,6 @@ fcntl Yhg1s filecmp fileinput fnmatch -formatter fractions mdickinson ftplib giampaolo* functools rhettinger* @@ -135,7 +131,6 @@ idlelib kbkaiser (inactive), terryjreedy*, serwy (inactive), taleinat imaplib imghdr -imp importlib brettcannon inspect 1st1 io benjaminp, stutzbach^ @@ -205,7 +200,6 @@ shlex shutil tarekziade, giampaolo signal gpshead site -smtpd giampaolo smtplib sndhdr socket gpshead @@ -220,7 +214,6 @@ stringprep struct mdickinson, meadori subprocess astrand^ (inactive), giampaolo, gpshead* sunau -symbol symtable benjaminp sys sysconfig FFY00 From f419cacae23eb5c4cb8e3c2eb213478526c58081 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 1 May 2023 08:30:22 -0700 Subject: [PATCH 076/538] Add link to Brandt's talk about the interpreter (#1089) (TODO: The video links to an older version; update when PyCon 2023 video is online.) --- internals/interpreter.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internals/interpreter.rst b/internals/interpreter.rst index 5c5cfed03..68d5017d2 100644 --- a/internals/interpreter.rst +++ b/internals/interpreter.rst @@ -13,6 +13,13 @@ The CPython 3.11 bytecode interpreter (a.k.a. virtual machine) has a number of i We describe the inner workings of the 3.11 interpreter here, with an emphasis on understanding not just the code but its design. While the interpreter is forever evolving, and the 3.12 design will undoubtedly be different again, knowing the 3.11 design will help you understand future improvements to the interpreter. +Other sources +------------- + +* Brandt Bucher's talk about the specializing interpreter at PyCon US 2023. + `Slides `_ + `Video `_ + Introduction ============ From 55a1cf140b65e3650016a65181637832ecb3b080 Mon Sep 17 00:00:00 2001 From: 0x00zer0day <119995897+0x00zer0day@users.noreply.github.com> Date: Wed, 10 May 2023 12:56:13 +0530 Subject: [PATCH 077/538] Update communication-channels.rst (#1094) Co-authored-by: Oleg Iarygin Co-authored-by: Lysandros Nikolaou Co-authored-by: Hugo van Kemenade --- developer-workflow/communication-channels.rst | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 239855bb1..993547426 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -250,13 +250,27 @@ order to make open source pleasant for everyone involved. Additional Repositories ======================= -`Python Core Workflow`_ hosts the codebase for tools such as `cherry_picker`_ -and `blurb`_. +`Python Core Workflow`_ hosts the codebase for tools such as `blurb`_. + +Other core workflow tools are: + +* `cherry_picker`_ (`PyPI`_) +* `bedevere`_ +* `blurb_it`_ +* `miss-islington`_ +* `cla-bot`_ +* `cpython-emailer-webhook`_ Python `Performance Benchmark`_ project is intended to be an authoritative source of benchmarks for all Python implementations. .. _Python Core Workflow: https://github.com/python/core-workflow -.. _cherry_picker: https://pypi.org/project/cherry_picker/ .. _blurb: https://pypi.org/project/blurb +.. _cherry_picker: https://github.com/python/cherry-picker +.. _PyPI: https://pypi.org/project/cherry_picker/ +.. _bedevere: https://github.com/python/bedevere +.. _blurb_it: https://github.com/python/blurb_it +.. _miss-islington: https://github.com/python/miss-islington +.. _cla-bot: https://github.com/ambv/cla-bot +.. _cpython-emailer-webhook: https://github.com/berkerpeksag/cpython-emailer-webhook .. _Performance Benchmark: https://github.com/python/pyperformance From a0947e6c6f002357fafd91506fdeadd5b7535576 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 15 May 2023 21:52:25 +0200 Subject: [PATCH 078/538] Document custom CPython roles. (#1092) * Document custom CPython roles. * Fix role name. Co-authored-by: Hugo van Kemenade * Fix whitespace. --------- Co-authored-by: Hugo van Kemenade --- documentation/markup.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/documentation/markup.rst b/documentation/markup.rst index b142e497b..8859ab8d0 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -30,6 +30,8 @@ external links ```Link text `_`` :ref:`hyperl 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` +issues ``:gh:`ID```, ``:issue:`ID``` :ref:`roles` +CPython source ``:source:`PATH``` :ref:`roles` comments ``.. a comment`` :ref:`comments` ======================= =========================================== ==================== @@ -682,6 +684,12 @@ where simpler markup should be used: * ``*arg*`` (rendered as *arg*) for function and method arguments. * ````True````/````False````/````None```` for ``True``/``False``/``None``. +In addition, the CPython documentation defines a few custom roles: + +* ``:gh:`ID```: creates a link to a GitHub issue. +* ``:issue:`ID```: creates a link to a bugs.python.com issue. +* ``:source:`PATH```: creates a link to a source file on GitHub. + There are some additional facilities that make cross-referencing roles more versatile: From bb85592581ba1d0438577d9494a4d39611c9f43f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 17 May 2023 21:12:34 +0300 Subject: [PATCH 079/538] Replace deprecated utcnow() with now(UTC) (#1097) * Replace deprecated utcnow() with now(UTC) * Update Python requirements --- README.rst | 4 +--- _tools/generate_release_cycle.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index f083d9d0f..7f0e8b92c 100644 --- a/README.rst +++ b/README.rst @@ -24,8 +24,6 @@ The official home of this guide is https://devguide.python.org. Compilation ----------- -For the compilation of the devguide, you need to use a version of Python which -supports the ``venv`` module, because the ``make html`` command will create a -virtual environment and will install the ``Sphinx`` package:: +For the compilation of the devguide, Python 3.11+ is needed:: make html diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index 59e9fcbbe..dc3701058 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -44,7 +44,7 @@ def __init__(self) -> None: def write_csv(self) -> None: """Output CSV files.""" - now_str = str(dt.datetime.utcnow()) + now_str = str(dt.datetime.now(dt.UTC)) versions_by_category = {"branches": {}, "end-of-life": {}} headers = None From 83244f2488e09f6722f8b034bbe74006424d1c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Mon, 22 May 2023 20:21:21 +0100 Subject: [PATCH 080/538] Add Android platform to the experts list (#1053) --- core-developers/experts.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 5eed53021..b8b962f97 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -290,6 +290,7 @@ Platforms Platform Maintainers =================== =========== AIX David.Edelsohn^ +Android Cygwin jlt63^, stutzbach^ FreeBSD HP-UX From 66d310dca623434f46e5555801f4f584d4e8c578 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 23 May 2023 09:18:08 +0300 Subject: [PATCH 081/538] Python 3.13 is now main (#1099) --- _static/devguide_overrides.css | 5 +++++ include/release-cycle.json | 10 +++++++++- versions.rst | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css index a93acbbff..a8e96a43c 100644 --- a/_static/devguide_overrides.css +++ b/_static/devguide_overrides.css @@ -69,6 +69,11 @@ stroke: #008844; } +.release-cycle-chart .release-cycle-blob.release-cycle-blob-prerelease { + fill: teal; + stroke: darkgreen; +} + .release-cycle-chart .release-cycle-blob.release-cycle-blob-feature { fill: #2222EE; stroke: #008888; diff --git a/include/release-cycle.json b/include/release-cycle.json index b310429e5..f7a295ab0 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -1,8 +1,16 @@ { - "3.12": { + "3.13": { "branch": "main", "pep": 693, "status": "feature", + "first_release": "2024-10-07", + "end_of_life": "2029-10", + "release_manager": "Thomas Wouters" + }, + "3.12": { + "branch": "3.12", + "pep": 693, + "status": "prerelease", "first_release": "2023-10-02", "end_of_life": "2028-10", "release_manager": "Thomas Wouters" diff --git a/versions.rst b/versions.rst index 5225d1560..78224b09d 100644 --- a/versions.rst +++ b/versions.rst @@ -5,7 +5,7 @@ Status of Python Versions ========================= -The main branch is currently the future Python 3.12, and is the only +The ``main`` branch is currently the future Python 3.13, and is the only branch that accepts new features. The latest release for each Python version can be found on the `download page `_. From 940cc97c74d5dea2c959a7c9d7be0a960a635915 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 30 May 2023 15:44:01 +0200 Subject: [PATCH 082/538] Update location of the stable_abi.py script (#1103) --- developer-workflow/c-api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index daa694814..d9078d24f 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -375,14 +375,14 @@ Adding a new definition to the Limited API .. code-block:: shell - ./python ./Tools/scripts/stable_abi.py --generate-all ./Misc/stable_abi.toml + ./python ./Tools/build/stable_abi.py --generate-all ./Misc/stable_abi.toml - Build Python and check the using ``make check-limited-abi``. On platforms without ``make``, run this command directly: .. code-block:: shell - ./python ./Tools/scripts/stable_abi.py --all ./Misc/stable_abi.toml + ./python ./Tools/build/stable_abi.py --all ./Misc/stable_abi.toml - Add tests -- see below. From e87fa511eadc3f52a3c92f84fc8505cc9c9067f4 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 30 May 2023 20:15:03 +0100 Subject: [PATCH 083/538] Add note about the CI generated ABI file (#1104) --- getting-started/setup-building.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index d07db3bfe..993f3e40b 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -531,6 +531,10 @@ validate if the change can be made or not. with native extensions and other tools that interact with the Python interpreter. See the documentation about the :ref:`release candidate ` phase. +When the PR check fails, the associated run will have the updated ABI file +attached as an artifact. After release manager approval, you can download and +add this file into your PR to pass the check. + You can regenerate the ABI file by yourself by invoking the ``regen abidump`` Make target. Note that for doing this you need to regenerate the ABI file in the same environment that the GitHub CI uses to check for it. This is because From f9230ff0d500a4fb76e69f87eefca52b367cb0e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 08:16:09 +0300 Subject: [PATCH 084/538] Bump sphinx from 6.1.3 to 7.0.1 (#1106) Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 6.1.3 to 7.0.1. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v6.1.3...v7.0.1) --- updated-dependencies: - dependency-name: sphinx dependency-type: direct:production update-type: version-update:semver-major ... 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 d8fb7ac3d..f872cdad0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Sphinx==6.1.3 +Sphinx==7.0.1 furo>=2022.6.4 jinja2 sphinx-lint==0.6.7 From 8ffeda5c27586f0c3cfc7653be6fa41a9cc90de0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 4 Jun 2023 11:22:36 +0300 Subject: [PATCH 085/538] Maintain support for pre-Python 3.11 (#1107) Co-authored-by: C.A.M. Gerlach --- README.rst | 4 ++-- _tools/generate_release_cycle.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 7f0e8b92c..f8f7ff251 100644 --- a/README.rst +++ b/README.rst @@ -21,9 +21,9 @@ nickname of "the devguide" by the Python core developers. The official home of this guide is https://devguide.python.org. -Compilation +Render HTML ----------- -For the compilation of the devguide, Python 3.11+ is needed:: +To render the devguide to HTML under ``_build/html``, run:: make html diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index dc3701058..27b5cc3ec 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -5,6 +5,7 @@ import csv import datetime as dt import json +import sys import jinja2 @@ -44,7 +45,10 @@ def __init__(self) -> None: def write_csv(self) -> None: """Output CSV files.""" - now_str = str(dt.datetime.now(dt.UTC)) + if sys.version_info >= (3, 11): + now_str = str(dt.datetime.now(dt.UTC)) + else: + now_str = str(dt.datetime.utcnow()) versions_by_category = {"branches": {}, "end-of-life": {}} headers = None From b3e561c6f30c34138f6dfbc5c6cdc83b3de99a91 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 8 Jun 2023 23:47:36 +0200 Subject: [PATCH 086/538] Use targeted env vars for overriding compiler/linker flags on macOS (#1058) --- getting-started/setup-building.rst | 43 +++++++++++++++++------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 993f3e40b..8be292818 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -419,24 +419,21 @@ For example, with **Homebrew**, install the dependencies:: $ brew install pkg-config openssl@1.1 xz gdbm tcl-tk -Then, for Python 3.10 and newer, run ``configure``:: +Then, for Python 3.11 and newer, run ``configure``:: - $ CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ - LDFLAGS="-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" \ - PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \ + $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ + GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ ./configure --with-pydebug \ --with-openssl="$(brew --prefix openssl@1.1)" +Or, for Python 3.7 through 3.10:: -Or, for Python 3.7 through 3.9:: - - $ export PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig"; \ - CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ + $ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@1.1)" \ - --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ - --with-tcltk-includes="$(pkg-config --cflags tcl tk)" + --with-openssl="$(brew --prefix openssl@1.1)" \ + --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ + --with-tcltk-includes="$(pkg-config --cflags tcl tk)" And finally, run ``make``:: @@ -444,21 +441,31 @@ And finally, run ``make``:: Alternatively, with **MacPorts**:: - $ sudo port install pkgconfig openssl xz gdbm + $ sudo port install pkgconfig openssl11 xz gdbm tcl tk +quartz + +Then, for Python 3.11 and newer, run ``configure``:: + + $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ + GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ + ./configure --with-pydebug \ + --with-openssl="$(dirname $(dirname $(which port)))/libexec/openssl11" -and ``configure``:: +Or, for Python 3.7 through 3.10:: - $ CPPFLAGS="-I/opt/local/include" \ - LDFLAGS="-L/opt/local/lib" \ - ./configure --with-pydebug + $ CPPFLAGS="-I$(dirname $(dirname $(which port)))/include" \ + LDFLAGS="-L$(dirname $(dirname $(which port)))/lib" \ + ./configure --with-pydebug \ + --with-openssl="$(dirname $(dirname $(which port)))/libexec/openssl11" \ + --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ + --with-tcltk-includes="$(pkg-config --cflags tcl tk)" -and ``make``:: +And finally, run ``make``:: $ make -s -j2 There will sometimes be optional modules added for a new release which won't yet be identified in the OS-level build dependencies. In those cases, -just ask for assistance on the core-mentorship list. +just ask for assistance in the *Core Development* category on :ref:`help-discourse`. Explaining how to build optional dependencies on a Unix-based system without root access is beyond the scope of this guide. From 7620395ad2223a11b3b4d5ad720b5eea9dae117c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 9 Jun 2023 06:56:01 +0200 Subject: [PATCH 087/538] Bump macOS build recommendations to OpenSSL v3.0 (#1112) * Simplify recipes by: 1. removing references to 3.7 which will be end-of-life shortly and otherwise would require including OpenSSL 1.1.1 libs. 2. removing MacPorts recipe for 3.10 and earlier because there are conflicts with the use of --with-openssl and the use of CPPFLAGS/LDFLAGS. Co-authored-by: Ned Deily --- getting-started/setup-building.rst | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 8be292818..9baa545e5 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -417,21 +417,21 @@ for the header and library files to your ``configure`` command. For example, with **Homebrew**, install the dependencies:: - $ brew install pkg-config openssl@1.1 xz gdbm tcl-tk + $ brew install pkg-config openssl@3.0 xz gdbm tcl-tk Then, for Python 3.11 and newer, run ``configure``:: $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@1.1)" + --with-openssl="$(brew --prefix openssl@3.0)" -Or, for Python 3.7 through 3.10:: +Or, for Python 3.8 through 3.10:: $ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@1.1)" \ + --with-openssl="$(brew --prefix openssl@3.0)" \ --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ --with-tcltk-includes="$(pkg-config --cflags tcl tk)" @@ -441,23 +441,13 @@ And finally, run ``make``:: Alternatively, with **MacPorts**:: - $ sudo port install pkgconfig openssl11 xz gdbm tcl tk +quartz + $ sudo port install pkgconfig openssl xz gdbm tcl tk +quartz Then, for Python 3.11 and newer, run ``configure``:: $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ - ./configure --with-pydebug \ - --with-openssl="$(dirname $(dirname $(which port)))/libexec/openssl11" - -Or, for Python 3.7 through 3.10:: - - $ CPPFLAGS="-I$(dirname $(dirname $(which port)))/include" \ - LDFLAGS="-L$(dirname $(dirname $(which port)))/lib" \ - ./configure --with-pydebug \ - --with-openssl="$(dirname $(dirname $(which port)))/libexec/openssl11" \ - --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ - --with-tcltk-includes="$(pkg-config --cflags tcl tk)" + ./configure --with-pydebug And finally, run ``make``:: From 9b5ecd2a34da48d517f1a0d65ce7220672254f9d Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 9 Jun 2023 07:57:27 +0200 Subject: [PATCH 088/538] Update build status message in the Setup/Building section (#1110) --- getting-started/setup-building.rst | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 9baa545e5..90f10dae5 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -183,20 +183,17 @@ passed into the ``-j`` flag to match the number of cores you have (or if your version of Make supports it, you can use ``-j`` without a number and Make will not limit the number of steps that can run simultaneously.). -At the end of the build you should see a success message, possibly followed +At the end of the build you should see a success message, followed by a list of extension modules that haven't been built because their dependencies were missing: .. code-block:: none - Python build finished successfully! The necessary bits to build these optional modules were not found: - _bz2 _dbm _gdbm - _lzma _sqlite3 _ssl - _tkinter _uuid readline - zlib - To find the necessary bits, look in setup.py in detect_modules() - for the module's name. + _gdbm + To find the necessary bits, look in configure.ac and config.log. + + Checked 106 modules (31 built-in, 74 shared, 0 n/a on macosx-13.4-arm64, 0 disabled, 1 missing, 0 failed on import) If the build failed and you are using a C89 or C99-compliant compiler, please open a bug report on the `issue tracker`_. From 194de1f31d11768ef097724bd7998217cad3968b Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 9 Jun 2023 12:19:10 +0200 Subject: [PATCH 089/538] Rewrite 'Regenerating configure' section of building guide (#1109) --- getting-started/setup-building.rst | 54 ++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 90f10dae5..4c2f5dac3 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -477,31 +477,49 @@ Regenerate ``configure`` 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 -``configure`` script to test for availability of the functionality. +: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 `_. -Python's ``configure`` script is generated from ``configure.ac`` using Autoconf. -Instead of editing ``configure``, edit ``configure.ac`` and then run -``autoreconf`` to regenerate ``configure`` and a number of other files (such as -``pyconfig.h``). +After editing :file:`configure.ac`, run ``make regen-configure`` to generate +:file:`configure`, :cpy-file:`pyconfig.h.in`, and :cpy-file:`aclocal.m4`. +When submitting a pull request with changes made to :file:`configure.ac`, +make sure you also commit the changes in the generated files. -When submitting a patch with changes made to ``configure.ac``, you should also -include the generated files. +The recommended and by far the easiest way to regenerate :file:`configure` is:: -Note that running ``autoreconf`` is not the same as running ``autoconf``. For -example, ``autoconf`` by itself will not regenerate ``pyconfig.h.in``. -``autoreconf`` runs ``autoconf`` and a number of other tools repeatedly as is -appropriate. + $ make regen-configure -Python's ``configure.ac`` script typically requires a specific version of -Autoconf. At the moment, this reads: ``AC_PREREQ(2.69)``. It also requires -to have the ``autoconf-archive`` and ``pkg-config`` utilities installed in -the system and the ``pkg.m4`` macro file located in the appropriate ``alocal`` -location. You can easily check if this is correctly configured by running:: +If you are regenerating :file:`configure` in a clean repo, +run one of the following containers instead:: + + $ podman run --rm --pull=always -v $(pwd):/src:Z quay.io/tiran/cpython_autoconf:271 + +:: + + $ docker run --rm --pull=always -v $(pwd):/src quay.io/tiran/cpython_autoconf:271 + +Notice that the images are tagged with ``271``. +Python's :file:`configure.ac` script requires a specific version of +GNU Autoconf. +For Python 3.12 and newer, GNU Autoconf v2.71 is required. +For Python 3.11 and earlier, GNU Autoconf v2.69 is required. +For GNU Autoconf v2.69, change the ``:271`` tag to ``:269``. + +If you cannot (or don't want to) use the ``cpython_autoconf`` containers, +install the :program:`autoconf-archive` and :program:`pkg-config` utilities, +and make sure the :file:`pkg.m4` macro file located in the appropriate +:program:`aclocal` location:: $ ls $(aclocal --print-ac-dir) | grep pkg.m4 -If the system copy of Autoconf does not match this version, you will need to -install your own copy of Autoconf. +.. note:: + + Running :program:`autoreconf` is not the same as running :program:`autoconf`. + For example, running :program:`autoconf` by itself will not regenerate + :file:`pyconfig.h.in`. + :program:`autoreconf` runs :program:`autoconf` and a number of other tools + repeatedly as appropriate. .. _build_troubleshooting: From e8ba96a7961398e8bd2fc396e598f62300b2c086 Mon Sep 17 00:00:00 2001 From: Safwan Samsudeen <62411302+safwansamsudeen@users.noreply.github.com> Date: Sat, 10 Jun 2023 20:03:39 +0530 Subject: [PATCH 090/538] Correct some punctuation errors (#1113) --- getting-started/git-boot-camp.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 6332a8f59..082232cee 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -185,7 +185,7 @@ created before the rename, you should visit the GitHub page for your fork to rename the branch there. You only have to do this once. GitHub should provide you with a dialog for this. If it doesn't (or the dialog was already dismissed), you can rename the branch in your fork manually `by following -these GitHub instructions `__ +these GitHub instructions `__. After renaming the branch in your fork, you need to update any local clones as well. This only has to be done once per clone:: @@ -350,7 +350,7 @@ Solution:: git push origin main .. note:: For the above commands to work, please follow the instructions found - in the :ref:`checkout` section + in the :ref:`checkout` section. Another scenario: From 9eb2bbe56c413dc906d1b8c3c1c5e73e71002a77 Mon Sep 17 00:00:00 2001 From: Ege Akman Date: Mon, 12 Jun 2023 19:49:07 +0300 Subject: [PATCH 091/538] Replace GH-Pages with RTD for Turkish (#1114) --- documentation/translating.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 8f4ad8a73..005464d59 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -78,7 +78,7 @@ in production; others are works in progress. | (zh-tw) | Josix Wang | | +-----------------+-------------------------------+----------------------------+ | Turkish (tr) | `Ege Akman (@egeakman) | `GitHub `_ | -| | `_ | `GH-Pages `_ | +| | `_ | `RTD `_ | | | | `Doc `_ | +-----------------+-------------------------------+----------------------------+ | Ukrainian (uk) | `Dmytro Kazanzhy (@kazanzhy) | `GitHub `_ | @@ -107,7 +107,6 @@ in production; others are works in progress. .. _doc_tr: https://docs.python.org/tr/ .. _doc_zh_cn: https://docs.python.org/zh-cn/ .. _doc_zh_tw: https://docs.python.org/zh-tw/ -.. _gh_pages_tr: https://python.github.io/python-docs-tr/ .. _github_ar: https://github.com/Abdur-rahmaanJ/python-docs-ar .. _github_bn_in: https://github.com/python/python-docs-bn-in .. _github_es: https://github.com/python/python-docs-es @@ -130,6 +129,7 @@ in production; others are works in progress. .. _mail_lt: https://mail.python.org/pipermail/doc-sig/2019-July/004138.html .. _mail_pl: https://mail.python.org/pipermail/doc-sig/2019-April/004106.html .. _mail_ru: https://mail.python.org/pipermail/doc-sig/2019-May/004131.html +.. _rtd_tr: https://python-docs-tr.readthedocs.io/ .. _tx_pl: https://explore.transifex.com/python-doc/python-newest/ .. _tx_uk: https://explore.transifex.com/python-doc/python-newest/ .. _tx_zh_cn: https://explore.transifex.com/python-doc/python-newest/ From 72c37bd430509e7d46ce019000875f1ddbebf50d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 13 Jun 2023 21:15:34 +0300 Subject: [PATCH 092/538] Remove outdated reference to Python 3.5 (#1120) --- getting-started/setup-building.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 4c2f5dac3..75db82ba2 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -644,8 +644,7 @@ every rule. ``Programs`` Source code for C executables, including the main function for the - CPython interpreter (in versions prior to Python 3.5, these files are - in the Modules directory). + CPython interpreter. ``Python`` The code that makes up the core CPython runtime. This includes the From 13dc964972cdb92cde2829d0ca10fc4d3e22a559 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 15 Jun 2023 07:33:48 -0700 Subject: [PATCH 093/538] Link to Discourse first in "Help with Documentation" section (take 2) (#1118) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Docs Discourse forum is the preferred way. I reordered the sentence so that the discourse forum is mentioned first. Co-authored-by: Łukasz Langa Co-authored-by: C.A.M. Gerlach --- documentation/help-documenting.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/help-documenting.rst b/documentation/help-documenting.rst index 0da669b35..86652ffd3 100644 --- a/documentation/help-documenting.rst +++ b/documentation/help-documenting.rst @@ -36,9 +36,9 @@ and :ref:`maintenance ` branches at https://docs.python.org/dev/. 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 `docs@python.org `_ -mailing list and the `Documentation category on the Python Discourse -`_, +to the `Documentation category on the Python Discourse +`_ and the +`docs@python.org `_ mailing list where user issues are raised and documentation toolchain, projects, and standards are discussed. From 3f08d2513799028e9de99d08936b0eb7251f37e3 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 26 Jun 2023 09:11:53 +0200 Subject: [PATCH 094/538] Add guidelines for C API return values (#1123) --- developer-workflow/c-api.rst | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index d9078d24f..103abe7b0 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -93,7 +93,10 @@ CPython's public C API is available when ``Python.h`` is included normally It should be defined in ``Include/cpython/`` (unless part of the Limited API, see below). -Guidelines for expanding/changing the public API: +.. _public-api-guidelines: + +Guidelines for expanding/changing the public API +------------------------------------------------ - Make sure the new API follows reference counting conventions. (Following them makes the API easier to reason about, and easier use @@ -106,6 +109,24 @@ Guidelines for expanding/changing the public API: - Make sure the ownership rules and lifetimes of all applicable struct fields, arguments and return values are well defined. +- Functions returning ``PyObject *`` must return a valid pointer on success, + and ``NULL`` with an exception raised on error. + Most other API must return ``-1`` with an exception raised on error, + and ``0`` on success. + +- APIs with lesser and greater results must return ``0`` for the lesser result, + and ``1`` for the greater result. + Consider a lookup function with a three-way return: + + - ``return -1``: internal error or API misuse; exception raised + - ``return 0``: lookup succeeded; no item was found + - ``return 1``: lookup succeeded; item was found + +Please start a public discussion if these guidelines won't work for your API. + +.. note:: + + By *return value*, we mean the value returned by the *C return statement*. C API Tests ----------- @@ -292,10 +313,13 @@ It is possible to remove items marked as part of the Stable ABI, but only if there was no way to use them in any past version of the Limited API. +.. _limited-api-guidelines: + Guidelines for adding to the Limited API ---------------------------------------- - Guidelines for the general :ref:`public-capi` apply. + See :ref:`public-api-guidelines`. - New Limited API should only be defined if ``Py_LIMITED_API`` is set to the version the API was added in or higher. From be8ffbf76e39bb048136069c95c595cf7f639cda Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 27 Jun 2023 19:05:48 +0300 Subject: [PATCH 095/538] Python 3.7 is EOL (#1130) --- 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 f7a295ab0..621681205 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -50,7 +50,7 @@ "3.7": { "branch": "3.7", "pep": 537, - "status": "security", + "status": "end-of-life", "first_release": "2018-06-27", "end_of_life": "2023-06-27", "release_manager": "Ned Deily" From 0f2347b177ccb3d766a1f34bf8b8b7354645865b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 27 Jun 2023 20:59:59 +0300 Subject: [PATCH 096/538] Add PEP 719 for Python 3.13 (#1131) --- 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 621681205..849efe614 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -1,7 +1,7 @@ { "3.13": { "branch": "main", - "pep": 693, + "pep": 719, "status": "feature", "first_release": "2024-10-07", "end_of_life": "2029-10", From 93c3ee7cf53bf4b95a5e194441f82eeb2d23c3ed Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 10 Jul 2023 22:54:06 +0300 Subject: [PATCH 097/538] Update planned 3.13.0 release date: 2024-10-01 (#1132) --- 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 849efe614..38c0fd2ba 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -3,7 +3,7 @@ "branch": "main", "pep": 719, "status": "feature", - "first_release": "2024-10-07", + "first_release": "2024-10-01", "end_of_life": "2029-10", "release_manager": "Thomas Wouters" }, From a5defb456384b6ecd9524b370618a4ee6f2f0535 Mon Sep 17 00:00:00 2001 From: Emmanuel Arias Date: Mon, 17 Jul 2023 16:50:20 -0300 Subject: [PATCH 098/538] Update link to blurb documentation (#1137) --- index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.rst b/index.rst index 063dced4a..b84a76667 100644 --- a/index.rst +++ b/index.rst @@ -69,7 +69,8 @@ instructions please see the :ref:`setup guide `. 8. Add a News entry into the ``Misc/NEWS.d`` directory as individual file. The news entry can be created by using `blurb-it `_, or the `blurb `_ tool and its ``blurb add`` - command. Please read more about ``blurb`` in :ref:`documentation `. + command. Please read more about ``blurb`` in its + `repository `_. .. note:: From d6edccf9573f9909f9e188f0d9d73fefe054cf8c Mon Sep 17 00:00:00 2001 From: chengfangho <87441472+chengfangho@users.noreply.github.com> Date: Fri, 21 Jul 2023 22:12:09 -0700 Subject: [PATCH 099/538] Strip space from pasted text (#1142) --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 2c1add6c3..15823481b 100644 --- a/conf.py +++ b/conf.py @@ -166,6 +166,6 @@ def _asset_hash(path: os.PathLike[str]) -> str: # Strip the dollar prompt when copying code # https://sphinx-copybutton.readthedocs.io/en/latest/use.html#strip-and-configure-input-prompts-for-code-cells -copybutton_prompt_text = "$" +copybutton_prompt_text = "$ " # https://sphinx-copybutton.readthedocs.io/en/latest/use.html#honor-line-continuation-characters-when-copying-multline-snippets copybutton_line_continuation_character = "\\" From 65ae4a82765594ce8e4ad9a54f5bb750f2dc98fa Mon Sep 17 00:00:00 2001 From: Moritz Neeb Date: Sun, 23 Jul 2023 21:44:18 +0200 Subject: [PATCH 100/538] Reviewing PRs: On GitHub the nosy list is called subscribers (#1143) --- getting-started/pull-request-lifecycle.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 5b4469e2b..5c81d0a99 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -416,7 +416,7 @@ request (we cannot force anyone to review pull requests and no one is employed to look at pull requests). If your pull request has not received any notice from reviewers (i.e., no comment made) after one month, first "ping" the issue on the `issue tracker`_ to remind the -nosy list that the pull request needs a review. +subscribers that the pull request needs a review. If you don't get a response within a week after pinging the issue, you can post on the `Core Development Discourse category`_ to ask for someone to review your pull request. From 1cb3c183f807c56166d404dfc179140108e4dfc0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 31 Jul 2023 11:06:12 +0300 Subject: [PATCH 101/538] Add linting to CI via pre-commit (#987) --- .flake8 | 2 ++ .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/workflows/ci.yml | 2 -- .github/workflows/lint.yml | 14 +++++++++ .pre-commit-config.yaml | 47 +++++++++++++++++++++++++++++ LICENSE | 2 +- Makefile | 6 ++++ _extensions/custom_roles.py | 5 +-- conf.py | 11 ++++--- developer-workflow/lang-changes.rst | 1 - 10 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 .flake8 create mode 100644 .github/workflows/lint.yml create mode 100644 .pre-commit-config.yaml diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..f4546adb4 --- /dev/null +++ b/.flake8 @@ -0,0 +1,2 @@ +[flake8] +max_line_length = 88 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 839471ed0..b1d63fbf3 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,4 +8,4 @@ It should describe the change to be made. Most PRs will require an issue number. Trivial changes, like fixing a typo, do not need an issue. ---> \ No newline at end of file +--> diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3267db717..f2b16054d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,6 @@ jobs: cache: pip - name: Build docs run: make html - - name: Check markup - run: make check - name: Link check run: make linkcheck continue-on-error: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..c78a4053a --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,14 @@ +name: Lint + +on: [push, pull_request, workflow_dispatch] + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + - uses: pre-commit/action@v3.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..e6b335c32 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,47 @@ +repos: + - repo: https://github.com/asottile/pyupgrade + rev: v3.10.1 + hooks: + - id: pyupgrade + args: [--py38-plus] + + - repo: https://github.com/psf/black + rev: 23.7.0 + hooks: + - id: black + args: [--skip-string-normalization] + + - repo: https://github.com/PyCQA/isort + rev: 5.12.0 + hooks: + - id: isort + args: [--profile=black] + + - repo: https://github.com/PyCQA/flake8 + rev: 6.1.0 + hooks: + - id: flake8 + additional_dependencies: [flake8-2020] + + - repo: https://github.com/sphinx-contrib/sphinx-lint + rev: v0.6.7 + hooks: + - id: sphinx-lint + args: ["--enable=default-role"] + + - repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.10.0 + hooks: + - id: python-check-blanket-noqa + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-json + - id: check-merge-conflict + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + +ci: + autoupdate_schedule: quarterly diff --git a/LICENSE b/LICENSE index 28289e879..4594fb738 100644 --- a/LICENSE +++ b/LICENSE @@ -113,4 +113,4 @@ Affirmer's express Statement of Purpose. CC0 or use of the Work. For more information, please see - \ No newline at end of file + diff --git a/Makefile b/Makefile index d86ebf533..17141ac2d 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ help: @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " check to run a check for frequent markup errors" + @echo " lint to lint all the files" @echo " versions to update release cycle after changing release-cycle.json" .PHONY: clean @@ -183,6 +184,11 @@ check: ensure-venv # Ignore the tools and venv dirs and check that the default role is not used. $(SPHINXLINT) -i tools -i $(VENVDIR) --enable default-role +.PHONY: lint +lint: venv + $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit + $(VENVDIR)/bin/python3 -m pre_commit run --all-files + .PHONY: serve serve: @echo "The 'serve' target was removed, use 'htmlview' instead" \ diff --git a/_extensions/custom_roles.py b/_extensions/custom_roles.py index 2c4e9d9d0..f8c9bb895 100644 --- a/_extensions/custom_roles.py +++ b/_extensions/custom_roles.py @@ -35,8 +35,9 @@ def role(name, rawtext, text, lineno, inliner, _options=None, _content=None): if text.startswith('!'): node = nodes.literal(rawtext, text[1:]) else: - node = nodes.reference(rawtext, '', nodes.literal(rawtext, text), - refuri=url, internal=False) + node = nodes.reference( + rawtext, '', nodes.literal(rawtext, text), refuri=url, internal=False + ) return [node], [] return role diff --git a/conf.py b/conf.py index 15823481b..36be6625c 100644 --- a/conf.py +++ b/conf.py @@ -34,6 +34,7 @@ '.github', ] + def _asset_hash(path: os.PathLike[str]) -> str: """Append a `?digest=` to an url based on the file content.""" full_path = (Path(html_static_path[0]) / path).resolve() @@ -59,19 +60,19 @@ def _asset_hash(path: os.PathLike[str]) -> str: linkcheck_allowed_redirects = { # Edit page - r"https://docs.google.com/document/d/.*/": r"https://docs.google.com/document/d/.*/edit", + r"https://docs.google.com/document/d/.*/": r"https://docs.google.com/document/d/.*/edit", # noqa: E501 # Canonical r"https://docs.python.org/": r"https://docs.python.org/3/", # Translations with country codes r"https://docs.python.org/[a-z-]+/": r"https://docs.python.org/[a-z-]+/3/", # Personal /my/ links redirect to login page - r"https://discuss.python.org/my/.*": r"https://discuss.python.org/login-preferences", + r"https://discuss.python.org/my/.*": r"https://discuss.python.org/login-preferences", # noqa: E501 # Login page - r"https://github.com/python/core-workflow/issues/new.*": r"https://github.com/login.*", + r"https://github.com/python/core-workflow/issues/new.*": r"https://github.com/login.*", # noqa: E501 # Archive redirect - r"https://github.com/python/cpython/archive/main.zip": r"https://codeload.github.com/python/cpython/zip/refs/heads/main", + r"https://github.com/python/cpython/archive/main.zip": r"https://codeload.github.com/python/cpython/zip/refs/heads/main", # noqa: E501 # Blob to tree - r"https://github.com/python/cpython/blob/.*": r"https://github.com/python/cpython/tree/.*", + r"https://github.com/python/cpython/blob/.*": r"https://github.com/python/cpython/tree/.*", # noqa: E501 # HackMD shortcuts r"https://hackmd.io/s/.*": r"https://hackmd.io/@.*", # Read the Docs diff --git a/developer-workflow/lang-changes.rst b/developer-workflow/lang-changes.rst index 7d663530c..19cc42dd1 100644 --- a/developer-workflow/lang-changes.rst +++ b/developer-workflow/lang-changes.rst @@ -86,4 +86,3 @@ to inform others who may propose a similar language change in the future. .. _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 - From ee22ad7a703539650e56c163fd05cc7640b1dcbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 06:26:24 +0300 Subject: [PATCH 102/538] Bump sphinx from 7.0.1 to 7.1.1 (#1147) Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 7.0.1 to 7.1.1. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v7.0.1...v7.1.1) --- updated-dependencies: - dependency-name: sphinx dependency-type: direct:production update-type: version-update:semver-minor ... 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 f872cdad0..1a35f0e11 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Sphinx==7.0.1 +Sphinx==7.1.1 furo>=2022.6.4 jinja2 sphinx-lint==0.6.7 From d61215d8afff82a804015806950ade9de9c4b818 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 06:35:06 +0300 Subject: [PATCH 103/538] Bump sphinx-lint from 0.6.7 to 0.6.8 (#1146) Bumps [sphinx-lint](https://github.com/sphinx-contrib/sphinx-lint) from 0.6.7 to 0.6.8. - [Release notes](https://github.com/sphinx-contrib/sphinx-lint/releases) - [Commits](https://github.com/sphinx-contrib/sphinx-lint/compare/v0.6.7...v0.6.8) --- updated-dependencies: - dependency-name: sphinx-lint 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 1a35f0e11..b5476b7e0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ Sphinx==7.1.1 furo>=2022.6.4 jinja2 -sphinx-lint==0.6.7 +sphinx-lint==0.6.8 sphinx-notfound-page sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 From dc0be4dbd29b6f1c7ef8281ef29cfbbbddb41177 Mon Sep 17 00:00:00 2001 From: Marlene <57748216+marlenezw@users.noreply.github.com> Date: Wed, 2 Aug 2023 18:11:57 +0200 Subject: [PATCH 104/538] Adding Codespaces Documentation (#1144) Co-authored-by: Hugo van Kemenade Co-authored-by: Pradyun Gedam Co-authored-by: Brett Cannon --- getting-started/setup-building.rst | 69 ++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 75db82ba2..60db82d47 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -655,3 +655,72 @@ every rule. .. _issue tracker: https://github.com/python/cpython/issues + + +.. _using-codespaces: + +Contribute using GitHub Codespaces +================================== + +.. _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 +`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 `_ +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 +you'd prefer to use that directly. + +.. _codespaces-create-a-codespace: + +Create a CPython codespace +-------------------------- + +Here are the basic steps needed to contribute a patch using Codespaces. +You first need to navigate to the +`CPython repo `_ hosted on GitHub. + +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). +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 + 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 + and push your changes once you're ready! + +If you close your repository and come back later you can always resume your +codespace by navigating to the CPython repo, selecting the codespaces tab and +selecting your most recent codespaces session. You should then be able to pick +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 +options. If you prefer working in a locally installed copy of VS Code you can +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. + + +.. TODO: add docker instructions From 0eba99f69242991c88ebadc9c3d1aaef4a40cfa5 Mon Sep 17 00:00:00 2001 From: A <5249513+Dumeng@users.noreply.github.com> Date: Fri, 4 Aug 2023 21:35:34 +0800 Subject: [PATCH 105/538] Add a new coordinator for zh_CN (#1150) --- documentation/translating.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 005464d59..eb19bf468 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -67,8 +67,8 @@ in production; others are works in progress. +-----------------+-------------------------------+----------------------------+ | Russian (ru) | | `mail `_ | +-----------------+-------------------------------+----------------------------+ -| Simplified | `Shengjing Zhu `_ | `Transifex `_ | -| Chinese | | `GitHub `_ | +| Simplified | `Shengjing Zhu `_, | `Transifex `_ | +| Chinese | `Du, Meng `_ | `GitHub `_ | | (zh-cn) | | `Doc `_ | +-----------------+-------------------------------+----------------------------+ | Spanish (es) | Raúl Cumplido | `GitHub `_ | @@ -96,6 +96,7 @@ in production; others are works in progress. .. _gh_oonid: https://github.com/oonid .. _gh_osdotsystem: https://github.com/Abdur-rahmaanJ .. _gh_zhsj: https://github.com/zhsj +.. _gh_dumeng: https://github.com/dumeng .. _gh_mattwang44: https://github.com/mattwang44 .. _gh_egeakman: https://github.com/egeakman .. _email_garade: mailto:garade@pm.me From 689528c6f5f9597077cd93354585b954b8c1baf5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 8 Aug 2023 22:05:34 +0200 Subject: [PATCH 106/538] Rename Advanced Tools to Development Tools (#1149) Co-authored-by: Hugo van Kemenade --- conf.py | 18 +++++++++++++++--- .../clang.rst | 0 .../coverity.rst | 0 {advanced-tools => development-tools}/gdb.rst | 0 .../index.rst | 6 +++--- index.rst | 2 +- 6 files changed, 19 insertions(+), 7 deletions(-) rename {advanced-tools => development-tools}/clang.rst (100%) rename {advanced-tools => development-tools}/coverity.rst (100%) rename {advanced-tools => development-tools}/gdb.rst (100%) rename {advanced-tools => development-tools}/index.rst (52%) diff --git a/conf.py b/conf.py index 36be6625c..a9b0ec1a7 100644 --- a/conf.py +++ b/conf.py @@ -108,14 +108,21 @@ def _asset_hash(path: os.PathLike[str]) -> str: ] rediraffe_redirects = { - "clang.rst": "advanced-tools/clang.rst", - "coverity.rst": "advanced-tools/coverity.rst", - "gdb.rst": "advanced-tools/gdb.rst", + # Development Tools + "clang.rst": "development-tools/clang.rst", + "coverity.rst": "development-tools/coverity.rst", + "gdb.rst": "development-tools/gdb.rst", + # Advanced Tools was renamed Development Tools in gh-1149 + "advanced-tools/clang.rst": "development-tools/clang.rst", + "advanced-tools/coverity.rst": "development-tools/coverity.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", + # Developer Workflow "c-api.rst": "developer-workflow/c-api.rst", "communication.rst": "developer-workflow/communication-channels.rst", "devcycle.rst": "developer-workflow/development-cycle.rst", @@ -124,22 +131,27 @@ def _asset_hash(path: os.PathLike[str]) -> str: "langchanges.rst": "developer-workflow/lang-changes.rst", "porting.rst": "developer-workflow/porting.rst", "stdlibchanges.rst": "developer-workflow/stdlib.rst", + # Documentation "docquality.rst": "documentation/help-documenting.rst", "documenting.rst": "documentation/start-documenting.rst", + # Getting Started "fixingissues.rst": "getting-started/fixing-issues.rst", "help.rst": "getting-started/getting-help.rst", "gitbootcamp.rst": "getting-started/git-boot-camp.rst", "pullrequest.rst": "getting-started/pull-request-lifecycle.rst", "setup.rst": "getting-started/setup-building.rst", + # CPython Internals "compiler.rst": "internals/compiler.rst", "exploring.rst": "internals/exploring.rst", "garbage_collector.rst": "internals/garbage-collector.rst", "parser.rst": "internals/parser.rst", + # Testing and Buildbots "buildbots.rst": "testing/buildbots.rst", "coverage.rst": "testing/coverage.rst", "buildworker.rst": "testing/new-buildbot-worker.rst", "runtests.rst": "testing/run-write-tests.rst", "silencewarnings.rst": "testing/silence-warnings.rst", + # Issues and Triaging "gh-faq.rst": "triage/github-bpo-faq.rst", "tracker.rst": "triage/issue-tracker.rst", "gh-labels.rst": "triage/labels.rst", diff --git a/advanced-tools/clang.rst b/development-tools/clang.rst similarity index 100% rename from advanced-tools/clang.rst rename to development-tools/clang.rst diff --git a/advanced-tools/coverity.rst b/development-tools/coverity.rst similarity index 100% rename from advanced-tools/coverity.rst rename to development-tools/coverity.rst diff --git a/advanced-tools/gdb.rst b/development-tools/gdb.rst similarity index 100% rename from advanced-tools/gdb.rst rename to development-tools/gdb.rst diff --git a/advanced-tools/index.rst b/development-tools/index.rst similarity index 52% rename from advanced-tools/index.rst rename to development-tools/index.rst index afa96741f..6a3e7466e 100644 --- a/advanced-tools/index.rst +++ b/development-tools/index.rst @@ -1,6 +1,6 @@ -============== -Advanced Tools -============== +================= +Development Tools +================= .. toctree:: :maxdepth: 5 diff --git a/index.rst b/index.rst index b84a76667..82327d46a 100644 --- a/index.rst +++ b/index.rst @@ -247,9 +247,9 @@ Full Table of Contents triage/index documentation/index testing/index + development-tools/index core-developers/index internals/index - advanced-tools/index versions .. _Buildbot status: https://www.python.org/dev/buildbot/ From d994dffce14996de95e051ced242b6babc88b50d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B8=B8=EC=9E=AC=EC=9D=80?= Date: Sun, 13 Aug 2023 21:53:45 +0900 Subject: [PATCH 107/538] Document PGO builds (#1153) Co-authored-by: Alex Waygood Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- getting-started/setup-building.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 60db82d47..e91ee07b8 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -237,6 +237,27 @@ build the :py:mod:`ctypes` module (without the flag the rest of CPython will still build properly). +Optimization +'''''''''''' + +If you are trying to improve CPython's performance, you will probably want +to use an optimized build of CPython. It can take a lot longer to build CPython +with optimizations enabled, and it's usually not necessary to do so. However, +it's essential if you want accurate benchmark results for a proposed performance +optimization. + +For an optimized build of Python, use +``configure --enable-optimizations --with-lto``. +This sets the default make targets up to enable Profile Guided Optimization (PGO) +and may be used to auto-enable Link Time Optimization (LTO) on some platforms. +See :option:`python:--enable-optimizations` and :option:`python:--with-lto` +to learn more about these options. + +.. code:: console + + $ ./configure --enable-optimizations --with-lto + + .. _windows-compiling: Windows From b66af5a0043001b05d196623a5268e1ae30a6a31 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Thu, 17 Aug 2023 17:07:16 +0100 Subject: [PATCH 108/538] Update dev guide with recent compiler and bytecode simplifications (#1154) --- internals/compiler.rst | 55 +++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/internals/compiler.rst b/internals/compiler.rst index a820ef260..7312fdcbd 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -14,8 +14,9 @@ In CPython, the compilation from source code to bytecode involves several steps: 1. Tokenize the source code (:cpy-file:`Parser/tokenizer.c`) 2. Parse the stream of tokens into an Abstract Syntax Tree (:cpy-file:`Parser/parser.c`) -3. Transform AST into a Control Flow Graph (:cpy-file:`Python/compile.c`) -4. Emit bytecode based on the Control Flow Graph (:cpy-file:`Python/compile.c`) +3. Transform AST into an instruction sequence (:cpy-file:`Python/compile.c`) +4. Construct a Control Flow Graph and apply optimizations to it (:cpy-file:`Python/flowgraph.c`) +5. Emit bytecode based on the Control Flow Graph (:cpy-file:`Python/assemble.c`) The purpose of this document is to outline how these steps of the process work. @@ -433,18 +434,6 @@ the variable. As for handling the line number on which a statement is defined, this is handled by ``compiler_visit_stmt()`` and thus is not a worry. -In addition to emitting bytecode based on the AST node, handling the -creation of basic blocks must be done. Below are the macros and -functions used for managing basic blocks: - -``NEXT_BLOCK(struct compiler *)`` - create an implicit jump from the current block - to the new block -``compiler_new_block(struct compiler *)`` - create a block but don't use it (used for generating jumps) -``compiler_use_next_block(struct compiler *, basicblock *block)`` - set a previously created block as a current block - Once the CFG is created, it must be flattened and then final emission of bytecode occurs. Flattening is handled using a post-order depth-first search. Once flattened, jump offsets are backpatched based on the @@ -460,15 +449,13 @@ not as simple as just suddenly introducing new bytecode in the AST -> bytecode step of the compiler. Several pieces of code throughout Python depend on having correct information about what bytecode exists. -First, you must choose a name and a unique identifier number. The official -list of bytecode can be found in :cpy-file:`Lib/opcode.py`. If the opcode is to -take an argument, it must be given a unique number greater than that assigned to -``HAVE_ARGUMENT`` (as found in :cpy-file:`Lib/opcode.py`). - -Once the name/number pair has been chosen and entered in :cpy-file:`Lib/opcode.py`, -you must also enter it into :cpy-file:`Doc/library/dis.rst`, and regenerate -:cpy-file:`Include/opcode.h` and :cpy-file:`Python/opcode_targets.h` by running -``make regen-opcode regen-opcode-targets``. +First, you must choose a name, implement the bytecode in +:cpy-file:`Python/bytecodes.c`, and add a documentation entry in +:cpy-file:`Doc/library/dis.rst`. Then run ``make regen-cases`` to +assign a number for it (see :cpy-file:`Include/opcode_ids.h`) and +regenerate a number of files with the actual implementation of the +bytecodes (:cpy-file:`Python/generated_cases.c.h`) and additional +files with metadata about them. With a new bytecode you must also change what is called the magic number for .pyc files. The variable ``MAGIC_NUMBER`` in @@ -478,23 +465,21 @@ to be recompiled by the interpreter on import. Whenever ``MAGIC_NUMBER`` is changed, the ranges in the ``magic_values`` array in :cpy-file:`PC/launcher.c` must also be updated. Changes to :cpy-file:`Lib/importlib/_bootstrap_external.py` will take effect only after running ``make regen-importlib``. Running this -command before adding the new bytecode target to :cpy-file:`Python/ceval.c` will -result in an error. You should only run ``make regen-importlib`` after the new -bytecode target has been added. +command before adding the new bytecode target to :cpy-file:`Python/bytecodes.c` +(followed by ``make regen-cases``) will result in an error. You should only run +``make regen-importlib`` after the new bytecode target has been added. .. note:: On Windows, running the ``./build.bat`` script will automatically regenerate the required files without requiring additional arguments. Finally, you need to introduce the use of the new bytecode. Altering -:cpy-file:`Python/compile.c` and :cpy-file:`Python/ceval.c` will be the primary -places to change. You must add the case for a new opcode into the 'switch' -statement in the ``stack_effect()`` function in :cpy-file:`Python/compile.c`. -If the new opcode has a jump target, you will need to update macros and -'switch' statements in :cpy-file:`Python/compile.c`. If it affects a control -flow or the block stack, you may have to update the ``frame_setlineno()`` -function in :cpy-file:`Objects/frameobject.c`. :cpy-file:`Lib/dis.py` may need -an update if the new opcode interprets its argument in a special way (like -``FORMAT_VALUE`` or ``MAKE_FUNCTION``). +:cpy-file:`Python/compile.c`, :cpy-file:`Python/bytecodes.c` will be the +primary places to change. Optimizations in :cpy-file:`Python/flowgraph.c` +may also need to be updated. +If the new opcode affects a control flow or the block stack, you may have +to update the ``frame_setlineno()`` function in :cpy-file:`Objects/frameobject.c`. +:cpy-file:`Lib/dis.py` may need an update if the new opcode interprets its +argument in a special way (like ``FORMAT_VALUE`` or ``MAKE_FUNCTION``). If you make a change here that can affect the output of bytecode that is already in existence and you do not change the magic number constantly, make From 99fe52a0e98fda8b0f34abda81a4ddc1e93d0cb1 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Thu, 24 Aug 2023 12:10:58 -0500 Subject: [PATCH 109/538] Point to buildbot config repo rather than mailing list for adding a worker (#1156) --- testing/new-buildbot-worker.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index 53c186ea7..0e79fceba 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -46,8 +46,9 @@ everything required to do normal python development: a compiler, a linker, and 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. Email -python-buildbots@python.org to discuss adding your worker and to obtain the +and password for your worker so it can join the fleet. Open an issue in the +`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 the "buildbot worker" step below. From f88487f639549d39bc2207689892f1caf05c236c Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Thu, 24 Aug 2023 12:17:30 -0500 Subject: [PATCH 110/538] Fix buildbot config issue URL --- testing/new-buildbot-worker.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index 0e79fceba..1beaa3afa 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -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 From b70b7634bc5ac75f0822962ed7a2e99542828ec2 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 31 Aug 2023 06:37:36 +0100 Subject: [PATCH 111/538] Bump Sphinx to 7.2.5 (#1155) Co-authored-by: Hugo van Kemenade --- conf.py | 12 +----------- requirements.txt | 4 ++-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/conf.py b/conf.py index a9b0ec1a7..32d46e581 100644 --- a/conf.py +++ b/conf.py @@ -1,8 +1,6 @@ -import hashlib import os import sys import time -from pathlib import Path # Location of custom extensions. sys.path.insert(0, os.path.abspath(".") + "/_extensions") @@ -35,14 +33,6 @@ ] -def _asset_hash(path: os.PathLike[str]) -> str: - """Append a `?digest=` to an url based on the file content.""" - full_path = (Path(html_static_path[0]) / path).resolve() - digest = hashlib.sha1(full_path.read_bytes()).hexdigest() - - return f"{path}?digest={digest}" - - html_theme = 'furo' html_theme_options = { "source_repository": "https://github.com/python/devguide", @@ -50,7 +40,7 @@ def _asset_hash(path: os.PathLike[str]) -> str: } html_static_path = ['_static'] html_css_files = [ - _asset_hash('devguide_overrides.css'), + 'devguide_overrides.css', ] html_logo = "_static/python-logo.svg" html_favicon = "_static/favicon.png" diff --git a/requirements.txt b/requirements.txt index b5476b7e0..260c90752 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -Sphinx==7.1.1 +Sphinx~=7.2.5 furo>=2022.6.4 jinja2 sphinx-lint==0.6.8 -sphinx-notfound-page +sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 sphinxext-rediraffe From dbccd8395186c47370b7b81d123b438264263e99 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 13 Sep 2023 10:51:13 -0600 Subject: [PATCH 112/538] =?UTF-8?q?Add=20"Helping=20with=20the=20Developer?= =?UTF-8?q?=E2=80=99s=20Guide"=20to=20documentarians=20column=20(#1164)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.rst b/index.rst index 82327d46a..2272cc74b 100644 --- a/index.rst +++ b/index.rst @@ -118,7 +118,7 @@ Contributors Documentarians Triagers Core Develo :ref:`pullrequest` :ref:`style-guide` :ref:`helptriage` :ref:`committing` :ref:`runtests` :ref:`rst-primer` :ref:`experts` :ref:`devcycle` :ref:`fixingissues` :ref:`translating` :ref:`labels` :ref:`motivations` -:ref:`communication` :ref:`gh-faq` :ref:`office hour` +:ref:`communication` :ref:`devguide` :ref:`gh-faq` :ref:`office hour` :ref:`gitbootcamp` :ref:`triage-team` :ref:`experts` :ref:`devcycle` ======================== =================== ======================= ======================= From 5d27e9146059687c0702f3759794af8fe996bf19 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 13 Sep 2023 10:51:25 -0600 Subject: [PATCH 113/538] Fix typos to follow style guide (#1163) --- core-developers/motivations.rst | 4 ++-- documentation/style-guide.rst | 4 ++-- documentation/translating.rst | 8 ++++---- getting-started/git-boot-camp.rst | 12 ++++++------ getting-started/pull-request-lifecycle.rst | 10 +++++----- getting-started/setup-building.rst | 16 ++++++++-------- index.rst | 4 ++-- internals/parser.rst | 2 +- testing/new-buildbot-worker.rst | 2 +- 9 files changed, 31 insertions(+), 31 deletions(-) diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index 625c763d9..abc23aad7 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -166,7 +166,7 @@ participating in the CPython core development process: business started declining) to being a full time independent consultant, David started contributing directly to CPython development. He became a committer in 2009. He subsequently took over primary maintenance of the - email package from Barry Warsaw, and contributed the unicode oriented API. + email package from Barry Warsaw, and contributed the Unicode oriented API. David is also active in mentoring new contributors and, when time is available, working on the infrastructure that supports CPython development, specifically the Roundup-based bug tracker and the buildbot system. @@ -175,7 +175,7 @@ participating in the CPython core development process: primarily in Python, through the company in which he is a partner, `Murray & Walker, Inc `_. He has done contract work focused specifically on CPython development both through the PSF (the - kickstart of the email unicode API development) and directly funded by + kickstart of the email Unicode API development) and directly funded by interested corporations (additional development work on email funded by QNX, and work on CPython ICC support funded by Intel). He would like to spend more of his (and his company's) time on open source work, and so is diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index f5dfe4570..ae4b8ed6e 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -56,7 +56,7 @@ sections are in title case, you can either convert all titles to sentence case or use the dominant style in the new section title. Sentences that start with a word for which specific rules require -starting it with a lower case letter should be avoided. +starting it with a lowercase letter should be avoided. .. note:: @@ -92,7 +92,7 @@ Python reST For "reStructuredText," an easy to read, plaintext markup syntax used to produce Python documentation. When spelled out, it is - always one word and both forms start with a lower case 'r'. + always one word and both forms start with a lowercase 'r'. Unicode The name of a character coding system. This is always written diff --git a/documentation/translating.rst b/documentation/translating.rst index eb19bf468..d71d4b65f 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -151,7 +151,7 @@ The important steps look like this: - Create the GitHub repo (anywhere) with the right hierarchy (using the cookiecutter). - 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. +- 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 @@ -211,7 +211,7 @@ Here's what we're using: from one file to others. - `pospell `__ to check for typos in ``.po`` files. - `powrap `__ to rewrap the ``.po`` files - before committing. This helps keep git diffs short. + before committing. This helps keep Git diffs short. - `potodo `__ to list what needs to be translated. @@ -240,7 +240,7 @@ Ask on the `translation mailing list `_, or better, make a PR o `__. -I have a translation, but it's not in git. What should I do? +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 @@ -248,7 +248,7 @@ the team will help you create an appropriate repository. You can still use tools if you like. -My git hierarchy does not match yours. Can I keep it? +My Git hierarchy does not match yours. Can I keep it? ----------------------------------------------------- No, inside the ``github.com/python`` organization we’ll all have the diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 082232cee..c9c6c9da9 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -10,11 +10,11 @@ Git Bootcamp and Cheat Sheet This section provides instructions on common tasks in CPython's workflow. It's designed to assist new contributors who have - some familiarity with git and GitHub. + some familiarity with Git and GitHub. - If you are new to git and GitHub, please become comfortable with + If you are new to Git and GitHub, please become comfortable with these instructions before submitting a pull request. As there are several - ways to accomplish these tasks using git and GitHub, this section reflects + ways to accomplish these tasks using Git and GitHub, this section reflects one method suitable for new contributors. Experienced contributors may desire a different approach. @@ -23,9 +23,9 @@ In this section, we will go over some commonly used Git commands that are relevant to CPython's workflow. .. note:: - Setting up git aliases for common tasks can be useful to you. You can + 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: @@ -544,7 +544,7 @@ page. Find the event that says something like:: By following the link to ````, you will get the full commit hash. -Alternatively, the commit hash can also be obtained by the following git +Alternatively, the commit hash can also be obtained by the following Git commands: .. code-block:: bash diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 5c81d0a99..54242ac1f 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -132,7 +132,7 @@ You should have already :ref:`set up your system `, git pull origin # pull = fetch + merge If you have made local changes that have not been pushed to your fork and - there are merge conflicts, git will warn you about this and enter conflict + there are merge conflicts, Git will warn you about this and enter conflict resolution mode. See :ref:`resolving-merge-conflicts` below. * If time passes and there are merge conflicts with the main branch, GitHub @@ -165,14 +165,14 @@ resolved as follows: git status #. Edit the affected files and bring them to their intended final state. - Make sure to remove the special "conflict markers" inserted by git. + Make sure to remove the special "conflict markers" inserted by Git. #. Commit the affected files:: git add git merge --continue -When running the final command, git may open an editor for writing a commit +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 `_ @@ -241,7 +241,7 @@ should do to help ensure that your pull request is accepted. ``patchcheck`` is a simple automated patch checklist that guides a developer through the common patch generation checks. To run ``patchcheck``: - On *UNIX* (including macOS):: + On *Unix* (including macOS):: make patchcheck @@ -303,7 +303,7 @@ to explain in proper depth what has happened (detail should be good enough that a core developer reading the commit message understands the justification for the change). -Check :ref:`the git bootcamp ` for further +Check :ref:`the Git bootcamp ` for further instructions on how the commit message should look like when merging a pull request. diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index e91ee07b8..b507d58aa 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -15,28 +15,28 @@ directory structure of the CPython source code. Alternatively, if you have `Docker `_ installed you might want to use `our official images `_. These -contain the latest releases of several Python versions, along with git head, +contain the latest releases of several Python versions, along with Git head, and are provided for development and testing purposes only. .. seealso:: The :ref:`quick-reference` gives brief summary of the process from - installing git to submitting a pull request. + installing Git to submitting a pull request. .. _vcsetup: -Install ``git`` -=============== +Install 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. +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 + 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 `_. diff --git a/index.rst b/index.rst index 2272cc74b..3ff4fb47f 100644 --- a/index.rst +++ b/index.rst @@ -27,7 +27,7 @@ instructions please see the :ref:`setup guide `. git clone https://github.com//cpython cd cpython -3. Build Python, on UNIX and macOS use:: +3. Build Python, on Unix and macOS use:: ./configure --with-pydebug && make -j @@ -39,7 +39,7 @@ instructions please see the :ref:`setup guide `. See also :ref:`more detailed instructions `, :ref:`how to install and build dependencies `, - and the platform-specific pages for :ref:`UNIX `, + and the platform-specific pages for :ref:`Unix `, :ref:`macOS`, and :ref:`Windows `. 4. :ref:`Run the tests `:: diff --git a/internals/parser.rst b/internals/parser.rst index aa035c1a7..323cc0fea 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -570,7 +570,7 @@ Pegen has some special grammatical elements and rules: * Strings with single quotes (') (e.g. ``'class'``) denote KEYWORDS. * Strings with double quotes (") (e.g. ``"match"``) denote SOFT KEYWORDS. -* Upper case names (e.g. ``NAME``) denote tokens in the :cpy-file:`Grammar/Tokens` file. +* Uppercase names (e.g. ``NAME``) denote tokens in the :cpy-file:`Grammar/Tokens` file. * Rule names starting with ``invalid_`` are used for specialized syntax errors. - These rules are NOT used in the first pass of the parser. diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index 1beaa3afa..6bbeb1ee4 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -26,7 +26,7 @@ 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 -on that list would be interesting: different Linux/UNIX distributions, +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 want to run an OS that's already on our list there may be utility in setting it From cb39ecacef99dc05820a2b83ebdaeadff78f4924 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 13 Sep 2023 23:38:46 -0600 Subject: [PATCH 114/538] Use sentence case for titles (#1162) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Ezio Melotti --- core-developers/become-core-developer.rst | 6 +-- core-developers/committing.rst | 2 +- core-developers/developer-log.rst | 4 +- core-developers/experts.rst | 4 +- core-developers/index.rst | 2 +- core-developers/motivations.rst | 2 +- core-developers/responsibilities.rst | 6 +-- developer-workflow/c-api.rst | 8 ++-- developer-workflow/communication-channels.rst | 14 +++--- developer-workflow/development-cycle.rst | 16 +++---- developer-workflow/extension-modules.rst | 2 +- developer-workflow/grammar.rst | 2 +- developer-workflow/index.rst | 2 +- developer-workflow/lang-changes.rst | 6 +-- developer-workflow/porting.rst | 2 +- developer-workflow/stdlib.rst | 6 +-- development-tools/clang.rst | 12 ++--- development-tools/index.rst | 2 +- documentation/help-documenting.rst | 4 +- documentation/markup.rst | 14 +++--- documentation/start-documenting.rst | 8 ++-- documentation/style-guide.rst | 12 ++--- getting-started/fixing-issues.rst | 2 +- getting-started/getting-help.rst | 10 ++-- getting-started/git-boot-camp.rst | 46 +++++++++---------- getting-started/index.rst | 2 +- getting-started/pull-request-lifecycle.rst | 22 ++++----- getting-started/setup-building.rst | 6 +-- index.rst | 14 +++--- internals/compiler.rst | 20 ++++---- internals/exploring.rst | 6 +-- internals/garbage-collector.rst | 2 +- internals/index.rst | 2 +- internals/interpreter.rst | 2 +- internals/parser.rst | 12 ++--- testing/buildbots.rst | 4 +- testing/coverage.rst | 16 +++---- testing/index.rst | 2 +- testing/new-buildbot-worker.rst | 8 ++-- testing/run-write-tests.rst | 4 +- testing/silence-warnings.rst | 2 +- triage/github-bpo-faq.rst | 8 ++-- triage/index.rst | 2 +- triage/issue-tracker.rst | 6 +-- triage/labels.rst | 2 +- triage/triaging.rst | 12 ++--- versions.rst | 10 ++-- 47 files changed, 179 insertions(+), 179 deletions(-) diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index 9887ffcf9..296e64b0b 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -2,10 +2,10 @@ .. _coredev: ============================== -How to Become a Core Developer +How to become a core developer ============================== -What it Takes +What it takes ============= When you have consistently contributed patches which meet quality standards @@ -22,7 +22,7 @@ an official offer. How core developers come to that agreement are outlined in :pep:`13`. -Gaining Commit Privileges +Gaining commit privileges ========================= After a candidate has demonstrated consistent contributions, commit privileges diff --git a/core-developers/committing.rst b/core-developers/committing.rst index 256fda9d1..8b3ee2b3c 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -1,6 +1,6 @@ .. _committing: -Accepting Pull Requests +Accepting pull requests ======================= .. highlight:: none diff --git a/core-developers/developer-log.rst b/core-developers/developer-log.rst index 5a7ff01dd..665ef0700 100644 --- a/core-developers/developer-log.rst +++ b/core-developers/developer-log.rst @@ -1,7 +1,7 @@ .. _developer-log: .. _developers: -Developer Log +Developer log ============= This page lists the historical members of the Python development team. (The @@ -13,7 +13,7 @@ information.) :file: developers.csv :encoding: "utf-8" -Procedure for Granting or Dropping Access +Procedure for granting or dropping access ----------------------------------------- To be granted the ability to manage who is a committer, you must be a diff --git a/core-developers/experts.rst b/core-developers/experts.rst index b8b962f97..419efb42c 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -1,7 +1,7 @@ .. _experts: ============= -Experts Index +Experts index ============= This document has tables that list Python Modules, Tools, Platforms and @@ -362,7 +362,7 @@ version control merwok, ezio-melotti ================== ========================================================== -Documentation Translations +Documentation translations ========================== For a list of translators, see :ref:`this table about translations `. diff --git a/core-developers/index.rst b/core-developers/index.rst index cf743c405..2b3ac7b79 100644 --- a/core-developers/index.rst +++ b/core-developers/index.rst @@ -1,5 +1,5 @@ =============== -Core Developers +Core developers =============== .. toctree:: diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index abc23aad7..4d91e5a32 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -1,7 +1,7 @@ .. _motivations: ============================ -Motivations and Affiliations +Motivations and affiliations ============================ CPython core developers participate in the core development process for a diff --git a/core-developers/responsibilities.rst b/core-developers/responsibilities.rst index aec4b98cc..0638a967e 100644 --- a/core-developers/responsibilities.rst +++ b/core-developers/responsibilities.rst @@ -44,7 +44,7 @@ making design and development decisions in different areas (as documented in the :ref:`experts` and :ref:`developers`). -Communication Channels and Bug Notifications +Communication channels and bug notifications ============================================ Mailing lists have generally been replaced by the @@ -59,7 +59,7 @@ follow the link and click on the :guilabel:`Watch` button to set your notificati .. _contributor_agreement: -Sign a Contributor Agreement +Sign a contributor agreement ============================ Submitting a `contributor form for Python`_ licenses any code you contribute to @@ -77,7 +77,7 @@ username into your details on the issue tracker. .. _contributor form for Python: https://www.python.org/psf/contrib/ -Pull Request merging +Pull request merging ==================== Once you have your commit privileges on GitHub you will be able to accept diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index 103abe7b0..3525cb81f 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -58,7 +58,7 @@ When in doubt, new internal C functions should be defined in ``Include/internal`` using the ``extern`` keyword. Private names --------------- +------------- Any API named with a leading underscore is also considered internal. There is currently only one main use case for using such names rather than @@ -74,7 +74,7 @@ the :ref:`unstable-capi`: * APIs for very specialized uses like JIT compilers. -Internal API Tests +Internal API tests ------------------ C tests for the internal C API live in ``Modules/_testinternalcapi.c``. @@ -128,7 +128,7 @@ Please start a public discussion if these guidelines won't work for your API. By *return value*, we mean the value returned by the *C return statement*. -C API Tests +C API tests ----------- Tests for the public C API live in the ``_testcapi`` module. @@ -411,7 +411,7 @@ Adding a new definition to the Limited API - Add tests -- see below. -Limited API Tests +Limited API tests ----------------- Since Limited API is a subset of the C API, there's no need to test the diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 993547426..1ff3b85ca 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -2,7 +2,7 @@ .. _communication: ============================== -Following Python's Development +Following Python's development ============================== Python's development is communicated through a myriad of ways, @@ -24,7 +24,7 @@ in return. .. _mailinglists: -Mailing Lists +Mailing lists ============= .. note:: Some mailing lists have been supplanted by categories in the @@ -95,7 +95,7 @@ It is also the designated venue for the core developer promotion votes (as the Discourse equivalent of the `python-committers`_ mailing list). Tutorials for new users -------------------------- +----------------------- To start a topic or participate in any discussions in the forum, sign up and create an account using an email address or GitHub account. You can do so by @@ -138,7 +138,7 @@ bottom progress bar to expand it. Notifications ------------- -Following categories (Category notifications) +Following categories (category notifications) ''''''''''''''''''''''''''''''''''''''''''''' Notifications can be set for individual categories and topics. To change any of these @@ -151,7 +151,7 @@ different options: Watching, Tracking, Watching First Post, Normal, and Muted. All categories are set by default in Normal mode where you will only be notified if someone mentions your @name or replies to you. -Following individual threads (Topic notifications) +Following individual threads (topic notifications) '''''''''''''''''''''''''''''''''''''''''''''''''' To follow any individual topics or threads, you can adjust your notifications @@ -239,7 +239,7 @@ that way. You can find their blogs (and various other developers who use Python) at https://planetpython.org/. -Setting Expectations for Open Source Participation +Setting expectations for open source participation ================================================== Burn-out is common in open source due to a misunderstanding of what users, contributors, @@ -247,7 +247,7 @@ and maintainers should expect from each other. Brett Cannon gave a `talk ` starts again for the next minor version. -Repository Administration +Repository administration ''''''''''''''''''''''''' The source code is currently hosted on `GitHub `_ in the `Python organization `_. -Organization Repository Policy +Organization repository policy ------------------------------ Within the `GitHub Python organization `_, @@ -254,7 +254,7 @@ specifically want to “bless” one implementation (as with e.g. `pythoncapi-compat `_). -Organization Owner Policy +Organization owner policy ------------------------- The GitHub Organization Owner role allows for full management of all aspects of @@ -281,7 +281,7 @@ Owner of the Python Organization. .. _current owners: -Current Owners +Current owners -------------- +----------------------+--------------------------------+-----------------+ @@ -307,7 +307,7 @@ mentioned to request assistance from an organization owner. .. _be performed: https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles -Repository Administrator Role Policy +Repository administrator role policy ------------------------------------ The Administrator role on the repository allows for managing all aspects @@ -328,7 +328,7 @@ who no longer necessitate this level of access will be removed with notice. Multi-Factor Authentication must be enabled by the user in order to remain an Administrator of the repository. -Current Administrators +Current administrators ---------------------- +-------------------+----------------------------------------------------------+-----------------+ @@ -353,7 +353,7 @@ Current Administrators | Mariatta Wijaya | Maintainer of bedevere, blurb_it and miss-islington | Mariatta | +-------------------+----------------------------------------------------------+-----------------+ -Repository Release Manager Role Policy +Repository release manager role policy -------------------------------------- Release Managers for :ref:`in-development `, :ref:`maintenance diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index 3a5a759a5..0384c2b38 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -2,7 +2,7 @@ .. _extensions: ================================== -Standard Library Extension Modules +Standard library extension modules ================================== In this section, we could explain how to write a CPython extension with the C language, but the topic can take a complete book. diff --git a/developer-workflow/grammar.rst b/developer-workflow/grammar.rst index 2ba18ec22..dfb6a2f9d 100644 --- a/developer-workflow/grammar.rst +++ b/developer-workflow/grammar.rst @@ -1,7 +1,7 @@ .. _grammar: ========================== -Changing CPython's Grammar +Changing CPython's grammar ========================== Abstract diff --git a/developer-workflow/index.rst b/developer-workflow/index.rst index bc90a832a..23f1909c9 100644 --- a/developer-workflow/index.rst +++ b/developer-workflow/index.rst @@ -1,5 +1,5 @@ ==================== -Development Workflow +Development workflow ==================== .. toctree:: diff --git a/developer-workflow/lang-changes.rst b/developer-workflow/lang-changes.rst index 19cc42dd1..70ecd679d 100644 --- a/developer-workflow/lang-changes.rst +++ b/developer-workflow/lang-changes.rst @@ -1,7 +1,7 @@ .. _lang-changes: .. _langchanges: -Changing the Python Language +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 @@ -9,7 +9,7 @@ have a reasonable chance of being considered and what the process is to propose changes to the language. -What Qualifies +What qualifies -------------- First and foremost, it must be understood that changes to the Python programming language are difficult to make. When the language changes, @@ -66,7 +66,7 @@ see `Justifying Python Language Changes`_. .. _lang-changes-pep-process: -PEP Process +PEP process ----------- Once you are certain you have a language change proposal diff --git a/developer-workflow/porting.rst b/developer-workflow/porting.rst index fc0c91517..26756bc8f 100644 --- a/developer-workflow/porting.rst +++ b/developer-workflow/porting.rst @@ -1,7 +1,7 @@ .. _porting: ========================= -Porting to a New Platform +Porting to a new platform ========================= The first step is to familiarize yourself with the development toolchain on diff --git a/developer-workflow/stdlib.rst b/developer-workflow/stdlib.rst index 176c72679..9ead7d706 100644 --- a/developer-workflow/stdlib.rst +++ b/developer-workflow/stdlib.rst @@ -1,7 +1,7 @@ .. _stdlib: .. _stdlibchanges: -Adding to the Stdlib +Adding to the stdlib ==================== While the stdlib contains a great amount of useful code, sometimes you want @@ -61,7 +61,7 @@ over other available solutions. All of this means that additions to the stdlib are not taken lightly. -Acceptable Types of Modules +Acceptable types of modules ''''''''''''''''''''''''''' Typically two types of modules get added to the stdlib. One type is a module which implements something that is difficult to get right. A good example of @@ -120,7 +120,7 @@ also helps to make sure that the overall design of the module continues to be uniform. -Proposal Process +Proposal process '''''''''''''''' If the module you want to propose adding to the stdlib meets the requirements, diff --git a/development-tools/clang.rst b/development-tools/clang.rst index 1f693fcae..14040dd8b 100644 --- a/development-tools/clang.rst +++ b/development-tools/clang.rst @@ -1,7 +1,7 @@ .. _clang: =========================== -Dynamic Analysis with Clang +Dynamic analysis with Clang =========================== .. highlight:: bash @@ -25,7 +25,7 @@ front-end provides access to LLVM's optimizer and code generator. The sanitizers - or checkers - are hooks into the code generation phase to instrument compiled code so suspicious behavior is flagged. -What are Sanitizers? +What are sanitizers? ==================== Clang sanitizers are runtime checkers used to identify suspicious and undefined @@ -52,7 +52,7 @@ the war chest to uncovering bugs and improving code quality. Clang should be used to compliment other methods, including Code Reviews, Valgrind, Coverity, etc. -Clang/LLVM Setup +Clang/LLVM setup ================ This portion of the document covers downloading, building and installing Clang @@ -62,7 +62,7 @@ compiler, the compiler front end and the compiler runtime library. In preparation you should create a scratch directory. Also ensure you are using Python 2 and not Python 3. Python 3 will cause the build to fail. -Download, Build and Install +Download, build and install --------------------------- Perform the following to download, build and install the Clang/LLVM 3.4. :: @@ -148,7 +148,7 @@ example, you might want to run a ``scan-build`` or examine the results with things work as expected. If a library is missing, then you should search for it in the Clang/LLVM build directory. -Python Build Setup +Python build setup ================== This portion of the document covers invoking Clang and LLVM with the options @@ -306,7 +306,7 @@ compile (formatting added for clarity): If its not installed, then look in the Clang/LLVM build directory for it and copy it to ``/usr/local/bin``. -Blacklisting (Ignoring) Findings +Blacklisting (ignoring) findings -------------------------------- .. highlight:: none diff --git a/development-tools/index.rst b/development-tools/index.rst index 6a3e7466e..d8e8453cf 100644 --- a/development-tools/index.rst +++ b/development-tools/index.rst @@ -1,5 +1,5 @@ ================= -Development Tools +Development tools ================= .. toctree:: diff --git a/documentation/help-documenting.rst b/documentation/help-documenting.rst index 86652ffd3..137827b3e 100644 --- a/documentation/help-documenting.rst +++ b/documentation/help-documenting.rst @@ -2,7 +2,7 @@ .. _docquality: ========================== -Helping with Documentation +Helping with documentation ========================== Python is known for having well-written documentation. Maintaining the @@ -20,7 +20,7 @@ You will find extensive and detailed information on how to write documentation and submit changes on the :ref:`Documenting Python ` page. -Python Documentation +Python documentation ==================== The :ref:`Documenting Python ` section covers the details of how diff --git a/documentation/markup.rst b/documentation/markup.rst index 8859ab8d0..0a0d51a63 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -1,7 +1,7 @@ .. _markup: ======================= -reStructuredText Markup +reStructuredText markup ======================= .. highlight:: rest @@ -10,7 +10,7 @@ This document describes the custom reStructuredText markup introduced by Sphinx to support Python documentation and how it should be used. -Quick Reference +Quick reference =============== This table summarizes which markup should be used for some commonly used @@ -38,7 +38,7 @@ comments ``.. a comment`` :ref:`commen .. _rst-primer: -reStructuredText Primer +reStructuredText primer ======================= This section is a brief introduction to reStructuredText (reST) concepts and @@ -89,7 +89,7 @@ provide semantic markup and cross-referencing of identifiers, as described in the appropriate section. The general syntax is ``:rolename:`content```. -Lists and Quotes +Lists and quotes ---------------- List markup is natural: just place an asterisk at the start of a paragraph and @@ -133,7 +133,7 @@ Paragraphs are quoted by just indenting them more than the surrounding paragraphs. -Source Code +Source code ----------- Literal code blocks are introduced by ending a paragraph with the special marker @@ -200,7 +200,7 @@ Python documentation, here is a suggested convention: * ``"``, for paragraphs -Explicit Markup +Explicit markup --------------- "Explicit markup" is used in reST for most constructs that need special @@ -291,7 +291,7 @@ There are some problems one commonly runs into while authoring reST documents: .. _additional-markup-constructs: -Additional Markup Constructs +Additional markup constructs ============================ Sphinx adds a lot of new directives and interpreted text roles to standard reST diff --git a/documentation/start-documenting.rst b/documentation/start-documenting.rst index 592059bf7..ea72704f1 100644 --- a/documentation/start-documenting.rst +++ b/documentation/start-documenting.rst @@ -2,7 +2,7 @@ .. _documenting: =============== -Getting Started +Getting started =============== .. highlight:: rest @@ -169,13 +169,13 @@ replace ``html`` above with the desired builder ``name``. .. _venv-create: https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment -Style Guide +Style guide =========== -Moved to :doc:`style-guide` +Moved to :doc:`style-guide`. Translating =========== -Moved to :doc:`translating` +Moved to :doc:`translating`. diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index ae4b8ed6e..d9f04526e 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -1,7 +1,7 @@ .. _style-guide: =========== -Style Guide +Style guide =========== .. highlight:: rest @@ -102,7 +102,7 @@ Unix The name of the operating system developed at AT&T Bell Labs in the early 1970s. -Affirmative Tone +Affirmative tone ================ The documentation focuses on affirmatively stating what the language does and @@ -127,7 +127,7 @@ language): achieve the same effect. This assures that files are flushed and file descriptor resources are released in a timely manner. -Economy of Expression +Economy of expression ===================== More documentation is not necessarily better documentation. Err on the side @@ -138,7 +138,7 @@ to understanding and can result in even more ways to misread or misinterpret the text. Long descriptions full of corner cases and caveats can create the impression that a function is more complex or harder to use than it actually is. -Security Considerations (and Other Concerns) +Security considerations (and other concerns) ============================================ Some modules provided with Python are inherently exposed to security issues @@ -159,7 +159,7 @@ module (e.g. OS level pipe buffers filling up and stalling child processes), these can be documented in a "Common Errors" section and cross-referenced rather than repeated for every affected interface. -Code Examples +Code examples ============= Short code examples can be a useful adjunct to understanding. Readers can often @@ -177,7 +177,7 @@ lines and output lines. Besides contributing visual clutter, it makes it difficult for readers to cut-and-paste examples so they can experiment with variations. -Code Equivalents +Code equivalents ================ Giving pure Python code equivalents (or approximate equivalents) can be a useful diff --git a/getting-started/fixing-issues.rst b/getting-started/fixing-issues.rst index 70d33dd77..6161f4aa6 100644 --- a/getting-started/fixing-issues.rst +++ b/getting-started/fixing-issues.rst @@ -2,7 +2,7 @@ .. _fixingissues: ================================= -Fixing "easy" Issues (and Beyond) +Fixing "easy" issues (and beyond) ================================= When you feel comfortable enough to want to help tackle issues by trying to diff --git a/getting-started/getting-help.rst b/getting-started/getting-help.rst index dce04a570..d1b48f23f 100644 --- a/getting-started/getting-help.rst +++ b/getting-started/getting-help.rst @@ -1,7 +1,7 @@ .. _getting-help: .. _help: -Where to Get Help +Where to get help ================= If you are working on Python it is very possible you will come across an issue @@ -39,7 +39,7 @@ Those particularly relevant for help contributing to Python itself include: .. _help-mailing-lists: -Mailing Lists +Mailing lists ------------- Further options for seeking assistance include the @@ -73,7 +73,7 @@ whereas ``#python`` is for questions concerning development *with* Python. .. _Libera.Chat: https://libera.chat/ -Core Mentorship +Core mentorship --------------- If you are interested in improving Python and contributing to its development, @@ -88,7 +88,7 @@ welcomed and encouraged to contribute. .. _office hour: -Core Developers Office Hours +Core developers office hours ---------------------------- Several core developers have set aside time to host mentorship office hours. @@ -105,7 +105,7 @@ during office hours. | Zachary Ware | See details link | Schedule at https://calendly.com/zware | +------------------+-------------------------------+------------------------------------------------+ -File a Bug +File a bug ---------- If you strongly suspect you have stumbled on a bug (be it in the build diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index c9c6c9da9..4746de33b 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -1,7 +1,7 @@ .. _git-boot-camp: .. _gitbootcamp: -Git Bootcamp and Cheat Sheet +Git bootcamp and cheat sheet ============================ .. highlight:: console @@ -29,7 +29,7 @@ relevant to CPython's workflow. .. _fork-cpython: -Forking CPython GitHub Repository +Forking CPython GitHub repository --------------------------------- You will only need to do this once. @@ -44,7 +44,7 @@ You will only need to do this once. .. _clone-your-fork: -Cloning a Forked CPython Repository +Cloning a forked CPython repository ----------------------------------- You will only need to do this once per machine. From your command line:: @@ -58,7 +58,7 @@ It is also recommended to configure an ``upstream`` remote repository:: You can also use SSH-based or HTTPS-based URLs. -Configure the Remotes +Configure the remotes --------------------- .. These steps are duplicated in setup-building in step 6 and 7. @@ -73,7 +73,7 @@ Since one should never attempt to push to ``upstream``, configure git remote set-url --push upstream git@github.com:/cpython.git -Listing the Remote Repositories +Listing the remote repositories ------------------------------- To list the remote repositories that are configured, along with their URLs:: @@ -98,7 +98,7 @@ It should emit ``upstream``, indicating to track/pull changes for ``main`` from .. _set-up-name-email: -Setting Up Your Name and Email Address +Setting up your name and email address -------------------------------------- .. code-block:: bash @@ -120,7 +120,7 @@ will reject all changesets having the wrong line endings:: git config --global core.autocrlf input -Creating and Switching Branches +Creating and switching branches ------------------------------- .. important:: @@ -159,7 +159,7 @@ on the 2.7 release from the ``upstream`` remote:: .. _deleting_branches: -Deleting Branches +Deleting branches ----------------- To delete a **local** branch that you no longer need:: @@ -174,7 +174,7 @@ To delete a **remote** branch:: You may specify more than one branch for deletion. -Renaming Branch +Renaming branch --------------- The CPython repository's default branch was renamed from ``master`` to @@ -209,7 +209,7 @@ rename your local branch as follows:: .. _commit-changes: -Staging and Committing Files +Staging and committing files ---------------------------- 1. To show the current changes:: @@ -227,7 +227,7 @@ Staging and Committing Files git commit -m "This is the commit message." -Reverting Changes +Reverting changes ----------------- To revert changes to a file that has not been committed yet:: @@ -239,7 +239,7 @@ the origin is at:: git reset --hard HEAD -Stashing Changes +Stashing changes ---------------- To stash away changes that are not ready to be committed yet:: @@ -252,7 +252,7 @@ To re-apply the last stashed change:: .. _diff-changes: -Comparing Changes +Comparing changes ----------------- View all non-commited changes:: @@ -278,7 +278,7 @@ defined in :cpy-file:`.gitattributes`, found in the repository root. .. _push-changes: -Pushing Changes +Pushing changes --------------- Once your changes are ready for a review or a pull request, you will need to push @@ -289,7 +289,7 @@ them to the remote repository. git switch git push origin -Creating a Pull Request +Creating a pull request ----------------------- 1. Go to https://github.com/python/cpython. @@ -308,7 +308,7 @@ Creating a Pull Request You should include the issue number in the title of the PR, in the format ``gh-NNNNN: ``. -Linking to Issues and Pull Requests +Linking to issues and pull requests ----------------------------------- You can link to issues and pull requests using ``gh-NNNNN`` (this form is @@ -327,7 +327,7 @@ you know for sure that a single PR is enough to address and close the issue. .. _bedevere: https://github.com/python/bedevere .. _special keywords: https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword -Updating your CPython Fork +Updating your CPython fork -------------------------- Scenario: @@ -378,7 +378,7 @@ When it happens, you need to resolve conflict. See these articles about resolvi .. _git_from_patch: -Applying a Patch to Git +Applying a patch to Git ----------------------- Scenario: @@ -421,7 +421,7 @@ Solution: .. _git_pr: -Downloading Other's Patches +Downloading other's patches --------------------------- Scenario: @@ -457,7 +457,7 @@ local copy of a pull request as follows:: .. _accepting-and-merging-a-pr: -Accepting and Merging a Pull Request +Accepting and merging a pull request ------------------------------------ Pull requests can be accepted and merged by a Python Core Developer. @@ -503,7 +503,7 @@ PR life cycle, while being irrelevant to the final change. Finally, press the ``Confirm squash and merge`` button. -Cancelling an Automatic Merge +Cancelling an automatic merge ----------------------------- If you notice a problem with a pull request that was accepted and where @@ -524,7 +524,7 @@ dismissing your previous review that requested changes. Note that pushing new changes after the auto-merge flow was enabled does **NOT** stop it. -Backporting Merged Changes +Backporting merged changes -------------------------- A pull request may need to be backported into one of the maintenance branches @@ -574,7 +574,7 @@ Example of bad backport commit message:: * Add method A to the spam module * Update the documentation of the spam module -Editing a Pull Request Prior to Merging +Editing a pull request prior to merging --------------------------------------- When a pull request submitter has enabled the `Allow edits from maintainers`_ diff --git a/getting-started/index.rst b/getting-started/index.rst index 420f1231c..18f7d5cd5 100644 --- a/getting-started/index.rst +++ b/getting-started/index.rst @@ -1,5 +1,5 @@ =============== -Getting Started +Getting started =============== .. toctree:: diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 54242ac1f..3466a4878 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -3,7 +3,7 @@ .. _pullrequest: =========================== -Lifecycle of a Pull Request +Lifecycle of a pull request =========================== .. highlight:: bash @@ -19,7 +19,7 @@ the official CPython repository (``upstream``). .. _pullrequest-quickguide: -Quick Guide +Quick guide =========== `Clear communication`_ is key to contributing to any project, especially an @@ -70,7 +70,7 @@ Here is a quick overview of how you can contribute to CPython: .. _pullrequest-steps: -Step-by-step Guide +Step-by-step guide ================== You should have already :ref:`set up your system `, @@ -152,7 +152,7 @@ You should have already :ref:`set up your system `, .. _resolving-merge-conflicts: -Resolving Merge Conflicts +Resolving merge conflicts ------------------------- When merging changes from different branches (or variants of a branch on @@ -181,7 +181,7 @@ for a detailed technical explanation. .. _good-prs: -Making Good PRs +Making good PRs =============== When creating a pull request for submission, there are several things that you @@ -274,7 +274,7 @@ making a complete patch. .. _good-commits: -Making Good Commits +Making good commits =================== Each feature or bugfix should be addressed by a single pull request, @@ -386,7 +386,7 @@ another so they can easily verify whether their comments have been addressed. The commits will be squashed when the pull request is merged. -Converting an Existing Patch from b.p.o to GitHub +Converting an existing patch from b.p.o to GitHub ================================================= When a patch exists in the `issue tracker`_ that should be converted into a @@ -430,7 +430,7 @@ thus iterate until a satisfactory solution has emerged. .. _how-to-review-a-pull-request: -How to Review a Pull Request +How to review a pull request ---------------------------- One of the bottlenecks in the Python development @@ -471,7 +471,7 @@ code and leave comments in the pull request or issue tracker. However, please be aware that if you are recommending a pull request as 'merge-ready', you should always make sure the entire test suite passes. -Leaving a Pull Request Review on GitHub +Leaving a pull request review on GitHub ======================================= When you review a pull request, you should provide additional details and context @@ -487,7 +487,7 @@ Instead of simply "approving" the pull request, leave comments. For example: #. Comment on what is "good" about the pull request, not just the "bad". Doing so will make it easier for the PR author to find the good in your comments. -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 @@ -496,7 +496,7 @@ the PR to themselves, then it is a sign that they are actively looking after the PR, and their review should not be dismissed. -Committing/Rejecting +Committing/rejecting ==================== Once your pull request has reached an acceptable state (and thus considered diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index b507d58aa..e1a53a498 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -2,7 +2,7 @@ .. _setup: ================== -Setup and Building +Setup and building ================== .. highlight:: console @@ -604,7 +604,7 @@ To overcome this problem, auto-generated files are also checked into the Git repository. So if you don't touch the auto-generation scripts, there's no real need to auto-generate anything. -Editors and Tools +Editors and tools ================= Python is used widely enough that practically all code editors have some form @@ -733,7 +733,7 @@ up from where you left off! .. _codespaces-use-locally: -Use Codespaces Locally +Use Codespaces locally ---------------------- On the bottom left side of the codespace screen you will see a green or grey diff --git a/index.rst b/index.rst index 3ff4fb47f..20bc228b0 100644 --- a/index.rst +++ b/index.rst @@ -11,7 +11,7 @@ community that maintains Python. We welcome your contributions to Python! .. _quick-reference: -Quick Reference +Quick reference --------------- Here are the basic steps needed to get set up and contribute a patch. @@ -78,7 +78,7 @@ instructions please see the :ref:`setup guide `. Agreement (CLA) as described in the :ref:`Licensing ` section of this guide. -Quick Links +Quick links ----------- Here are some links that you probably will reference frequently while @@ -148,7 +148,7 @@ happen and that process is also described as part of this guide: * :ref:`langchanges` -Other Interpreter Implementations +Other interpreter implementations --------------------------------- This guide is specifically for contributing to the Python reference interpreter, @@ -176,7 +176,7 @@ developers to work on them. Some major examples that may be of interest are: and learning to code on low-cost microcontroller boards. -Key Resources +Key resources ------------- * Coding style guides @@ -195,7 +195,7 @@ Key Resources .. _resources: -Additional Resources +Additional resources -------------------- * Anyone can clone the sources for this guide. See @@ -217,7 +217,7 @@ Additional Resources * :ref:`Search this guide ` -Code of Conduct +Code of conduct --------------- Please note that all interactions on `Python Software Foundation `__-supported @@ -236,7 +236,7 @@ Moved to :ref:`versions` .. _contents: -Full Table of Contents +Full table of contents ---------------------- .. toctree:: diff --git a/internals/compiler.rst b/internals/compiler.rst index 7312fdcbd..d7853456d 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -1,7 +1,7 @@ .. _compiler: =============== -Compiler Design +Compiler design =============== .. highlight:: none @@ -40,7 +40,7 @@ Various C files, including :cpy-file:`Parser/parser.c` are generated from these (see :ref:`grammar`). -Abstract Syntax Trees (AST) +Abstract syntax trees (AST) =========================== .. _compiler-ast-trees: @@ -129,7 +129,7 @@ this case) a ``stmt_ty`` struct with the appropriate initialization. The initializes the *name*, *args*, *body*, and *attributes* fields. -Memory Management +Memory management ================= Before discussing the actual implementation of the compiler, a discussion of @@ -163,7 +163,7 @@ are very rare. However, if you've allocated a PyObject, you must tell the arena about it by calling ``PyArena_AddPyObject()``. -Source Code to AST +Source code to AST ================== The AST is generated from source code using the function @@ -290,7 +290,7 @@ number is passed as the last parameter to each ``stmt_ty`` function. .. seealso:: :pep:`617` (PEP 617 -- New PEG parser for CPython) -Control Flow Graphs +Control flow graphs =================== A *control flow graph* (often referenced by its acronym, CFG) is a @@ -336,7 +336,7 @@ output order) by doing a post-order depth-first search on the CFG following the edges. -AST to CFG to Bytecode +AST to CFG to bytecode ====================== With the AST created, the next step is to create the CFG. The first step @@ -441,7 +441,7 @@ flattening and then a ``PyCodeObject`` is created. All of this is handled by calling ``assemble()``. -Introducing New Bytecode +Introducing new bytecode ======================== Sometimes a new feature requires a new opcode. But adding new bytecode is @@ -495,7 +495,7 @@ bytecode of frozen importlib files. You have to run ``make`` again after this for recompiling generated C files. -Code Objects +Code objects ============ The result of ``PyAST_CompileObject()`` is a ``PyCodeObject`` which is defined in @@ -507,7 +507,7 @@ will also need a new case statement for the new opcode in the big switch statement in ``_PyEval_EvalFrameDefault()``. -Important Files +Important files =============== * :cpy-file:`Parser/` @@ -614,7 +614,7 @@ Important Files (named ``MAGIC_NUMBER``) for bytecode versioning. -Known Compiler-related Experiments +Known compiler-related experiments ================================== This section lists known experiments involving the compiler (including diff --git a/internals/exploring.rst b/internals/exploring.rst index b049159af..3a812d1a9 100644 --- a/internals/exploring.rst +++ b/internals/exploring.rst @@ -1,7 +1,7 @@ .. _exploring: ======================== -Exploring the Internals +Exploring the internals ======================== This is a quick guide for people who are interested in learning more about @@ -9,7 +9,7 @@ CPython's internals. It provides a summary of the source code structure and contains references to resources providing a more in-depth view. -CPython Source Code Layout +CPython source code layout ========================== This guide gives an overview of CPython's code structure. @@ -49,7 +49,7 @@ Some exceptions: * Windows-only module ``winreg`` is at :cpy-file:`PC/winreg.c` -Additional References +Additional references ===================== For over 20 years the CPython code base has been changing and evolving. diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index ab6b35c7a..c2cbf6d72 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -3,7 +3,7 @@ .. _garbage_collector: ======================== -Garbage Collector Design +Garbage collector design ======================== :Author: Pablo Galindo Salgado diff --git a/internals/index.rst b/internals/index.rst index 161113560..4e9d28c83 100644 --- a/internals/index.rst +++ b/internals/index.rst @@ -1,5 +1,5 @@ =================== -CPython's Internals +CPython's internals =================== .. toctree:: diff --git a/internals/interpreter.rst b/internals/interpreter.rst index 68d5017d2..003d5de13 100644 --- a/internals/interpreter.rst +++ b/internals/interpreter.rst @@ -1,7 +1,7 @@ .. _interpreter: =============================== -The Bytecode Interpreter (3.11) +The bytecode interpreter (3.11) =============================== .. highlight:: c diff --git a/internals/parser.rst b/internals/parser.rst index 323cc0fea..f05d59b4a 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -1,7 +1,7 @@ .. _parser: =================== -Guide to the Parser +Guide to the parser =================== :Author: Pablo Galindo Salgado @@ -24,7 +24,7 @@ outputs the parser. The way the Python language is changed is therefore by modifying the grammar file and developers rarely need to interact with the parser generator itself other than use it to generate the parser. -How PEG Parsers Work +How PEG parsers work ==================== .. _how-peg-parsers-work: @@ -159,7 +159,7 @@ the rule: :: If the return type is omitted, then a ``void *`` is returned in C and an ``Any`` in Python. -Grammar Expressions +Grammar expressions ------------------- ``# comment`` @@ -306,7 +306,7 @@ and "hidden left-recursion" like:: rule: 'optional'? rule '@' some_other_rule -Variables in the Grammar +Variables in the grammar ------------------------ A sub-expression can be named by preceding it with an identifier and an @@ -641,7 +641,7 @@ when writing actions. In the C parser, some of these automatic variable names ar which is normally used to create AST nodes as almost all constructors need these attributes to be provided. All of the location variables are taken from the location information of the current token. -Hard and Soft keywords +Hard and soft keywords ---------------------- .. note:: @@ -722,7 +722,7 @@ error messages. tokenizer errors such as unclosed parenthesis will be reported only after the parser finishes without returning anything. -How Syntax errors are reported +How syntax errors are reported ------------------------------ As described previously in the :ref:`how PEG parsers work section diff --git a/testing/buildbots.rst b/testing/buildbots.rst index e9ccbcab0..38e606364 100644 --- a/testing/buildbots.rst +++ b/testing/buildbots.rst @@ -1,7 +1,7 @@ .. _buildbots: ====================== -Working with Buildbots +Working with buildbots ====================== .. highlight:: bash @@ -36,7 +36,7 @@ need assistance with the buildbots, a good way to get help is to either: worker owners are subscribed; or * contact the release manager of the branch you have issues with. -Buildbot failures on Pull Requests +Buildbot failures on pull requests ================================== The ``bedevere-bot`` on GitHub will put a message on your merged Pull Request diff --git a/testing/coverage.rst b/testing/coverage.rst index 49a2ff129..a28fb06db 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -1,7 +1,7 @@ .. _coverage: ====================== -Increase Test Coverage +Increase test coverage ====================== Python development follows a practice that all semantic changes and additions @@ -36,7 +36,7 @@ explicit coverage of the module is from its own set of tests instead of from implicit testing by other code that happens to use the module. -Common Gotchas +Common gotchas ============== Please realize that coverage reports on modules already imported before coverage @@ -54,7 +54,7 @@ prefer that other types of tests not be used (e.g., blackbox). When in doubt, stick with whitebox testing in order to properly exercise the code. -Measuring Coverage +Measuring coverage ================== It should be noted that a quirk of running coverage over Python's own stdlib is @@ -79,7 +79,7 @@ provided by the stdlib then you can :ref:`use test.regrtest .. _install_coverage: -Install Coverage +Install coverage '''''''''''''''' By default, pip will not install into the in-development version of Python you @@ -122,7 +122,7 @@ it. For this, you will again need to use the full path to that installation. .. _coverage_usage: -Basic Usage +Basic usage ''''''''''' The following command will tell you if your copy of coverage works (substitute @@ -176,7 +176,7 @@ with pages that visibly show what lines of code were or were not executed. .. _branch_coverage: -Branch Coverage +Branch coverage ''''''''''''''' For the truly daring, you can use another powerful feature of coverage.py: @@ -193,7 +193,7 @@ This will lead to the report stating not only what lines were not covered, but also what branch paths were not executed. -Coverage Results For Modules Imported Early On +Coverage results for modules imported early on '''''''''''''''''''''''''''''''''''''''''''''' For the *truly truly* daring, you can use a hack to get coverage.py to include @@ -256,7 +256,7 @@ files for each executed module along with which lines were executed how many times. -Filing the Issue +Filing the issue ================ Once you have increased coverage, you need to create an issue on the `issue tracker`_ and diff --git a/testing/index.rst b/testing/index.rst index 4a7247c98..770c25800 100644 --- a/testing/index.rst +++ b/testing/index.rst @@ -1,5 +1,5 @@ ===================== -Testing and Buildbots +Testing and buildbots ===================== .. toctree:: diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index 6bbeb1ee4..01692fa31 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -2,7 +2,7 @@ .. _buildworker: ==================== -New Buildbot Workers +New buildbot workers ==================== .. highlight:: bash @@ -274,7 +274,7 @@ or, if possible, providing ssh access to a committer to run experiments to try to resolve the issue. -Required Ports +Required ports ============== The worker operates as a *client* to the *buildmaster*. This means that @@ -304,7 +304,7 @@ Many tests will also create local TCP sockets and connect to them, usually using either ``localhost`` or ``127.0.0.1``. -Required Resources +Required resources ================== Based on the last time we did a `survey @@ -322,7 +322,7 @@ that Python compiles correctly on the platform and can run the rest of the test suite. -Security Considerations +Security considerations ======================= We only allow builds to be triggered against commits to the diff --git a/testing/run-write-tests.rst b/testing/run-write-tests.rst index f9323463a..14ef0c686 100644 --- a/testing/run-write-tests.rst +++ b/testing/run-write-tests.rst @@ -2,7 +2,7 @@ .. _runtests: ========================= -Running and Writing Tests +Running and writing tests ========================= .. note:: @@ -97,7 +97,7 @@ you want the most thorough tests you should use the strenuous approach shown above. -Unexpected Skips +Unexpected skips ---------------- Sometimes when running the test suite, you will see "unexpected skips" diff --git a/testing/silence-warnings.rst b/testing/silence-warnings.rst index e32da9a9c..e46a11a02 100644 --- a/testing/silence-warnings.rst +++ b/testing/silence-warnings.rst @@ -2,7 +2,7 @@ .. _silencewarnings: ==================================== -Silence Warnings From the Test Suite +Silence warnings from the test suite ==================================== When running Python's test suite, no warnings should result when you run it diff --git a/triage/github-bpo-faq.rst b/triage/github-bpo-faq.rst index 1027056ff..1385be052 100644 --- a/triage/github-bpo-faq.rst +++ b/triage/github-bpo-faq.rst @@ -2,7 +2,7 @@ .. _gh-faq: =========================== -GitHub Issues for BPO Users +GitHub issues for BPO users =========================== Here are some frequently asked questions about how to do things in @@ -82,7 +82,7 @@ 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"? +What on earth is a "mannequin"? =============================== For issues migrated to GitHub from `bpo`_ where the authors or commenters @@ -97,12 +97,12 @@ that happened in the issue. In case the user did share their GitHub account name in their `bpo`_ profile, we use that. Otherwise, their classic `bpo`_ username is used instead. -Where did the "Resolution" field go? +Where did the "resolution" field go? ==================================== Based on historical data we found it not being used very often. -Where did the "Low", "High", and "Critical" priorities go? +Where did the "low", "high", and "critical" priorities go? ========================================================== Based on historical data we found those not being used very often. diff --git a/triage/index.rst b/triage/index.rst index b2ae1c573..a054ad62f 100644 --- a/triage/index.rst +++ b/triage/index.rst @@ -1,5 +1,5 @@ =================== -Issues and Triaging +Issues and triaging =================== .. toctree:: diff --git a/triage/issue-tracker.rst b/triage/issue-tracker.rst index 889d71e9a..0f93df9ca 100644 --- a/triage/issue-tracker.rst +++ b/triage/issue-tracker.rst @@ -2,11 +2,11 @@ .. _tracker: ============= -Issue Tracker +Issue tracker ============= -Using the Issue Tracker +Using the issue tracker ======================= If you think you have found a bug in Python, you can report it to the @@ -124,7 +124,7 @@ By writing :samp:`Duplicate of #{NNN}` in a comment, you can `mark issues and PRs as duplicates `_. -Disagreement With a Resolution on the Issue Tracker +Disagreement with a resolution on the issue tracker =================================================== As humans, we will have differences of opinions from time to time. First and diff --git a/triage/labels.rst b/triage/labels.rst index 95e84558b..7cee20af8 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -2,7 +2,7 @@ .. _gh-labels: ============= -GitHub Labels +GitHub labels ============= Triagers, core developers and bots can add labels on GitHub diff --git a/triage/triaging.rst b/triage/triaging.rst index 9e0a62155..6ad96eeff 100644 --- a/triage/triaging.rst +++ b/triage/triaging.rst @@ -1,14 +1,14 @@ .. _triaging: ================= -Triaging an Issue +Triaging an issue ================= This section of the devguide documents the :ref:`issue tracker ` for users and developers. -Checklist for Triaging +Checklist for triaging ====================== * Read the initial message and the comments. @@ -44,7 +44,7 @@ a team member, likely a triager or a core developer. .. _helptriage: -Helping Triage Issues +Helping triage issues ===================== Once you know your way around how Python's source files are @@ -56,7 +56,7 @@ Around the clock, new issues are being opened on the :ref:`issue tracker ` and existing issues are being updated. Every issue needs to be triaged to make sure everything runs smoothly. -Classifying Reports +Classifying reports ------------------- For bugs, an issue needs to: @@ -81,7 +81,7 @@ This is all helpful as it allows members of the :ref:`triage team ` to properly classify an issue so it can be handled by the right core developers in a timely fashion. -Reviewing Pull Requests +Reviewing pull requests ----------------------- If an issue has a linked pull request that has not been reviewed, @@ -101,7 +101,7 @@ experience working on Python's code base will notice. See also :ref:`committing`. -Finding an Issue You Can Help With +Finding an issue you can help with ---------------------------------- If you want to help with triaging, you might also want to search for issues diff --git a/versions.rst b/versions.rst index 78224b09d..b712dfc6e 100644 --- a/versions.rst +++ b/versions.rst @@ -2,7 +2,7 @@ .. _branchstatus: ========================= -Status of Python Versions +Status of Python versions ========================= The ``main`` branch is currently the future Python 3.13, and is the only @@ -10,13 +10,13 @@ branch that accepts new features. The latest release for each Python version can be found on the `download page `_. -Python Release Cycle +Python release cycle ==================== .. raw:: html :file: include/release-cycle.svg -Supported Versions +Supported versions ================== Dates shown in *italic* are scheduled and can be adjusted. @@ -29,7 +29,7 @@ Dates shown in *italic* are scheduled and can be adjusted. .. Remember to update main branch in the paragraph above too -Unsupported Versions +Unsupported versions ==================== .. csv-table:: @@ -38,7 +38,7 @@ Unsupported Versions :file: include/end-of-life.csv -Status Key +Status key ========== :feature: new features, bugfixes, and security fixes are accepted. From 738cb26e9802bad8977badeb82fbdf6f0328ff51 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 15 Sep 2023 01:03:44 -0600 Subject: [PATCH 115/538] Update legal name from Dong-hee Na to Donghee Na (#1165) --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 2939f8e5d..a0635a8b3 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -17,7 +17,7 @@ Batuhan Taskaya,isidentical,2020-11-08,, Brandt Bucher,brandtbucher,2020-09-14,, Lysandros Nikolaou,lysnikolaou,2020-06-29,, Kyle Stanley,aeros,2020-04-14,, -Dong-hee Na,corona10,2020-04-08,, +Donghee Na,corona10,2020-04-08,, Karthikeyan Singaravelan,tirkarthi,2019-12-31,, Joannah Nanjekye,nanjekyejoannah,2019-09-23,, Abhilash Raj,maxking,2019-08-06,, From 03a3c234a32c93543318b9669f2aa92f74e2bcd0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 24 Sep 2023 13:01:23 -0600 Subject: [PATCH 116/538] Remove redundant references to python-committers (#1166) --- core-developers/become-core-developer.rst | 6 +----- core-developers/motivations.rst | 4 ++-- developer-workflow/communication-channels.rst | 3 +-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index 296e64b0b..057ef509b 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -29,8 +29,7 @@ After a candidate has demonstrated consistent contributions, commit privileges are granted through these steps: #. A core developer (submitter, usually the mentor) starts a poll in the - `Committers category`_ on the `Python Discourse`_ and cross-posts it to - the `python-committers mailing list`_. + `Committers category`_ on the `Python Discourse`_. - Open for 7 days - Results shown upon close @@ -45,8 +44,6 @@ are granted through these steps: - A request for account details as required by `🔒 python/voters `_ - - A request for the committer's preferred address for subscription to - the `python-committers mailing list`_ - A reminder about the `Code of Conduct`_ and guidance on reporting issues to the PSF Conduct WG @@ -62,4 +59,3 @@ are granted through these steps: .. _Code of Conduct: https://www.python.org/psf/conduct/ .. _Committers category: https://discuss.python.org/c/committers/5 .. _Python Discourse: https://discuss.python.org -.. _python-committers mailing list: https://mail.python.org/mailman3/lists/python-committers.python.org/ diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index 4d91e5a32..a15490891 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -89,9 +89,9 @@ participating in the CPython core development process: If there's a kind of link you'd like to include in your entry that isn't already covered by the categories mentioned above, please start a discussion about that on the Committers category on the Python Discourse - (discuss.python.org) or the python-committers mailing list. + (discuss.python.org). - The Committers Discourse category or the python-committers mailing list + The Committers Discourse category is also the appropriate point of contact for any other questions or suggestions relating to this page. diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 1ff3b85ca..66b88e784 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -91,8 +91,7 @@ the `Committers`_ category, where posting is restricted to the `CPython `_ core developers. The Committers category is often used for announcements and notifications. -It is also the designated venue for the core developer promotion votes -(as the Discourse equivalent of the `python-committers`_ mailing list). +It is also the designated venue for the core developer promotion votes. Tutorials for new users ----------------------- From 5c9482020991c5e350891b147573b34b407df94d Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sat, 4 Jan 2014 12:44:57 -0800 Subject: [PATCH 117/538] Issue #19659: Added documentation for Argument Clinic. GitHub-Issue-Link: https://github.com/python/cpython/issues/63858 --- Doc/howto/clinic.rst | 900 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 900 insertions(+) create mode 100644 Doc/howto/clinic.rst diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst new file mode 100644 index 000000000..afbeb417a --- /dev/null +++ b/Doc/howto/clinic.rst @@ -0,0 +1,900 @@ +====================== +Argument Clinic How-To +====================== + +:author: Larry Hastings + + +.. topic:: Abstract + + Argument Clinic is a preprocessor for CPython C files. + Its purpose is to automate all the boilerplate involved + with writing argument parsing code for "builtins". + This document shows you how to convert your first C + function to work with Argument Clinic, and then introduces + some advanced topics on Argument Clinic usage. + + Argument Clinic is currently considered an internal + tool for the CPython code tree. Its use is not supported + for files outside the CPython code tree, and no guarantees + are made regarding backwards compatibility for future + versions. In other words: if you maintain an external C + extension for CPython, you're welcome to experiment with + Argument Clinic in your own code. But the version of Argument + Clinic that ships with CPython 3.5 *could* be totally + incompatible and break all your code. + +======================== +Basic Concepts And Usage +======================== + +Argument Clinic ships with CPython. You can find it in ``Tools/clinic/clinic.py``. +If you run that script, specifying a C file as an argument:: + + % python3 Tools/clinic/clinic.py foo.c + +Argument Clinic will scan over the file looking for lines that +look exactly like this:: + + /*[clinic] + +When it finds one, it reads everything up to a line that looks +like this:: + + [clinic]*/ + +Everything in between these two lines is input for Argument Clinic. +All of these lines, including the beginning and ending comment +lines, are collectively called an Argument Clinic "input block", +or "block" for short. + +When Argument Clinic parses one of these blocks, it +generates output. This output is rewritten into the C file +immediately after the block, followed by a comment containing a checksum. +The resulting Argument Clinic block looks like this:: + + /*[clinic] + ... clinic input goes here ... + [clinic]*/ + ... clinic output goes here ... + /*[clinic checksum:...]*/ + +If you run Argument Clinic on the same file a second time, Argument Clinic +will discard the old output and write out the new output with a fresh checksum +line. However, if the input hasn't changed, the output won't change either. + +You should never modify the output portion of an Argument Clinic block. Instead, +change the input until it produces the output you want. (That's the purpose of the +checksum--to detect and warn you in case someone accidentally modifies the output.) + +For the sake of clarity, here's the terminology we'll use with Argument Clinic: + +* The first line of the comment (``/*[clinic]``) is the *start line*. +* The last line of the initial comment (``[clinic]*/``) is the *end line*. +* The last line (``/*[clinic checksum:...]*/``) is the *checksum line*. +* In between the start line and the end line is the *input*. +* In between the end line and the checksum line is the *output*. +* All the text collectively, from the start line to the checksum line inclusively, + is the *block*. (A block that hasn't been successfully processed by Argument + Clinic yet doesn't have output or a checksum line, but it's still considered + a block.) + + +============================== +Converting Your First Function +============================== + +The best way to get a sense of how Argument Clinic works is to +convert a function to work with it. Let's dive in! + +0. Make sure you're working with a freshly updated trunk. + +1. Find a Python builtin that calls either ``PyArg_ParseTuple()`` + or ``PyArg_ParseTupleAndKeywords()``, and hasn't been converted yet. + For my example I'm using ``pickle.Pickler.dump()``. + +2. If the call to the ``PyArg_Parse`` function uses any of the + following format units:: + + O& + O! + es + es# + et + et# + + or if it has multiple calls to ``PyArg_ParseTuple()``, + you should choose a different function. Argument Clinic *does* + support all of these scenarios. But these are advanced + topics--let's do something simpler for your first function. + +3. Add the following boilerplate above the function, creating our block:: + + /*[clinic] + [clinic]*/ + +4. 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.) + + Sample:: + + /*[clinic] + Write a pickled representation of obj to the open file. + [clinic]*/ + +5. 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. + + (Our docstring consists solely of the summary line, so the sample + code doesn't have to change for this step.) + +6. 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. + + Sample:: + + /*[clinic] + pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic]*/ + +7. 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.) + + Sample:: + + /*[clinic] + module pickle + class pickle.Pickler + [clinic]*/ + + /*[clinic] + pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic]*/ + + +8. 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:: + + name_of_parameter: converter + + If the parameter has a default value, add that after the + converter:: + + name_of_parameter: converter = default_value + + 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 ``PyArg_Parse()`` format argument and + specify *that* as its converter, as a quoted + string. ("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 multicharacter format units like ``z#``, use the + entire two-or-three character string. + + Sample:: + + /*[clinic] + module pickle + class pickle.Pickler + [clinic]*/ + + /*[clinic] + pickle.Pickler.dump + + obj: 'O' + + Write a pickled representation of obj to the open file. + [clinic]*/ + +9. 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. + + (``pickle.Pickler.dump`` has neither, so our sample is unchanged.) + + +10. If the existing C function uses ``PyArg_ParseTuple()`` + (instead of ``PyArg_ParseTupleAndKeywords()``), then all its + arguments are positional-only. + + To mark all parameters as positional-only in Argument Clinic, + add a ``/`` on a line by itself after the last parameter, + indented the same as the parameter lines. + + Sample:: + + /*[clinic] + module pickle + class pickle.Pickler + [clinic]*/ + + /*[clinic] + pickle.Pickler.dump + + obj: 'O' + / + + Write a pickled representation of obj to the open file. + [clinic]*/ + +11. It's helpful to write a per-parameter docstring, indented + another level past the parameter declaration. But per-parameter + docstrings are optional; you can skip this step if you prefer. + + Here's how per-parameter docstrings work. The first line + of the per-parameter docstring must be indented further than the + parameter definition. This left margin 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 as you like, + across multiple lines if you wish. + + Sample:: + + /*[clinic] + module pickle + class pickle.Pickler + [clinic]*/ + + /*[clinic] + pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic]*/ + +12. Save and close the file, then run ``Tools/clinic/clinic.py`` on it. + With luck everything worked and your block now has output! Reopen + the file in your text editor to see:: + + /*[clinic] + module pickle + class pickle.Pickler + [clinic]*/ + /*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + + /*[clinic] + pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic]*/ + + PyDoc_STRVAR(pickle_Pickler_dump__doc__, + "Write a pickled representation of obj to the open file.\n" + "\n" + ... + static PyObject * + pickle_Pickler_dump_impl(PyObject *self, PyObject *obj) + /*[clinic checksum: 3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ + +13. 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 + ``PyArg_ParseTuple()`` or ``PyArg_ParseTupleAndKeywords()``; + ensure that the code generated by Argument Clinic calls the + same function. + + Second, the format string passed in to ``PyArg_ParseTuple()`` or + ``PyArg_ParseTupleAndKeywords()`` should be *exactly* the same + as the hand-written one in the existing function. + + Well, there's one way that Argument Clinic's output is permitted + to be different. Argument Clinic always generates a format string + ending with ``:`` followed by the name of the function. If the + format string originally ended with ``;`` (to specify usage help), + this is harmless--don't worry about this difference. + + Apart from that, if either of these things differ in *any way*, + fix your input to Argument Clinic and rerun ``Tools/clinic/clinic.py`` + until they are the same. + + +14. 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. + The result should be a function that handles just the implementation + of the Python function without any argument-parsing code. + + Sample:: + + /*[clinic] + module pickle + class pickle.Pickler + [clinic]*/ + /*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + + /*[clinic] + pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic]*/ + + PyDoc_STRVAR(pickle_Pickler_dump__doc__, + "Write a pickled representation of obj to the open file.\n" + "\n" + ... + static PyObject * + pickle_Pickler_dump_impl(PyObject *self, PyObject *obj) + /*[clinic 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; + + ... + +15. Compile and 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. + + Well, except for one difference: ``inspect.signature()`` run on your function + should now provide a valid signature! + + Congratulations, you've ported your first function to work with Argument Clinic! + +=============== +Advanced Topics +=============== + + +Renaming the C functions 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: you can explicitly +specify the base name to use 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 the function name you use for the base (generated) function, +and then add ``"_impl"`` to the end for the name of the impl function. + +For example, if we wanted to rename the C function names generated for +``pickle.Pickler.dump``, it'd look like this:: + + /*[clinic] + pickle.Pickler.dump as pickler_dumper + + ... + +The base function would now be named ``pickler_dumper()``, +and the impl function would be named ``pickler_dumper_impl()``. + + +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 ``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 ``PyArg_ParseTupleAndKeywords()`` was created. + +Functions using this approach can often be converted to +use ``PyArg_ParseTupleAndKeywords()``, optional arguments, and default values. +But it's not always possible, because some of these legacy functions have +behaviors ``PyArg_ParseTupleAndKeywords()`` can't directly support. +The most obvious example is the builtin function ``range()``, which has +an optional argument on the *left* side of its required argument! +Another example is ``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.) + +For the sake of backwards compatibility, Argument Clinic supports this +alternate approach to parsing, using what are called *optional groups*. +Optional groups are groups of arguments that can only be specified together. +They can be to the left or the right of the required arguments. They +can *only* be used with positional-only parameters. + +To specify an optional group, add a ``[`` on a line by itself before +the parameters you wish to be +in a group together, and a ``]`` on a line by itself after the +parameters. As an example, here's how ``curses.window.addch`` +uses optional groups to make the first two parameters and the last +parameter optional:: + + /*[clinic] + + 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, and it will + be 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 are 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 are *only* intended for legacy code. Please do not + use optional groups for new code. + + +Using 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 the "legacy converters". "Legacy converters" are a convenience, +designed explicitly to make porting existing code to Argument Clinic +easier. And to be clear, their use is entirely acceptable when porting +code for Python 3.4. + +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 ``PyArg_ParseTuple()`` supports. + +So if you want +to go that extra effort, you should consider using normal +converters instead of the 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. All parameters to Argument Clinic converters are keyword-only. + +All Argument Clinic converters accept the following arguments: + +``doc_default`` + If the parameter takes a default value, normally this value is also + provided in the ``inspect.Signature`` metadata, and displayed in the + docstring. ``doc_default`` lets you override the value used in these + two places: pass in a string representing the Python value you wish + to use in these two contexts. + +``required`` + If a parameter takes a default value, Argument Clinic infers that the + parameter is optional. However, you may want a parameter to take a + default value in C, but not behave in Python as if the parameter is + optional. Passing in ``required=True`` to a converter tells Argument + Clinic that this parameter is not optional, even if it has a default + value. + +``annotation`` + The annotation value for this parameter. Not currently supported, + because PEP 8 mandates that the Python library may not use + annotations. + +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'`` ``byte(bitwise=True)`` +``'b'`` ``byte`` +``'c'`` ``char`` +``'C'`` ``int(types='str')`` +``'d'`` ``double`` +``'D'`` ``Py_complex`` +``'es#'`` ``str(encoding='name_of_encoding', length=True, zeroes=True)`` +``'es'`` ``str(encoding='name_of_encoding')`` +``'et#'`` ``str(encoding='name_of_encoding', types='bytes bytearray str', length=True)`` +``'et'`` ``str(encoding='name_of_encoding', types='bytes bytearray str')`` +``'f'`` ``float`` +``'h'`` ``short`` +``'H'`` ``unsigned_short`` +``'i'`` ``int`` +``'I'`` ``unsigned_int`` +``'K'`` ``unsigned_PY_LONG_LONG`` +``'L'`` ``PY_LONG_LONG`` +``'n'`` ``Py_ssize_t`` +``'O!'`` ``object(type='name_of_Python_type')`` +``'O&'`` ``object(converter='name_of_c_function')`` +``'O'`` ``object`` +``'p'`` ``bool`` +``'s#'`` ``str(length=True)`` +``'S'`` ``PyBytesObject`` +``'s'`` ``str`` +``'s*'`` ``Py_buffer(types='str bytes bytearray buffer')`` +``'u#'`` ``Py_UNICODE(length=True)`` +``'u'`` ``Py_UNICODE`` +``'U'`` ``unicode`` +``'w*'`` ``Py_buffer(types='bytearray rwbuffer')`` +``'y#'`` ``str(type='bytes', length=True)`` +``'Y'`` ``PyByteArrayObject`` +``'y'`` ``str(type='bytes')`` +``'y*'`` ``Py_buffer`` +``'Z#'`` ``Py_UNICODE(nullable=True, length=True)`` +``'z#'`` ``str(nullable=True, length=True)`` +``'Z'`` ``Py_UNICODE(nullable=True)`` +``'z'`` ``str(nullable=True)`` +``'z*'`` ``Py_buffer(types='str bytes bytearray buffer', nullable=True)`` +========= ================================================================================= + +As an example, here's our sample ``pickle.Pickler.dump`` using the proper +converter:: + + /*[clinic] + pickle.Pickler.dump + + obj: object + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic]*/ + +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. + + +Advanced converters +------------------- + +Remeber 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&``), ``type`` (for ``O!``), +or ``encoding`` (for all the format units that start with ``e``). + +Note that ``object()`` must explicitly support each Python type you specify +for the ``type`` argument. Currently it only supports ``str``. It should be +easy to add more, just edit ``Tools/clinic/clinic.py``, search for ``O!`` in +the text, and add more entries to the dict mapping types to strings just above it. + +Note also that this approach takes away some possible flexibility for the format +units starting with ``e``. It used to be possible to decide at runtime what +encoding string to pass in to ``PyArg_ParseTuple()``. But now this string must +be hard-coded at compile-time. This limitation is deliberate; it made supporting +this format unit much easier, and may allow for future compile-time optimizations. +This restriction does not seem unreasonable; CPython itself always passes in static +hard-coded strings when using format units starting with ``e``. + + +Using a return converter +------------------------ + +By default the impl function Argument Clinic generates for you returns ``PyObject *``. +But your C function often computes some C type, then converts it into the ``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 ``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. 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 occured? 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 (``PyErr_Occurred()`` returns a true +value), then the generated code will propogate the error. Otherwise it will +encode the value you return like normal. + +Currently Argument Clinic supports only a few return converters:: + + int + long + Py_ssize_t + DecodeFSDefault + +None of these take parameters. For the first three, return -1 to indicate +error. For ``DecodeFSDefault``, the return type is ``char *``; return a NULL +pointer to indicate an error. + +Calling Python code +------------------- + +The rest of the advanced topics require you to write Python code +which lives inside your C file and modifies Argument Clinic at +runtime. 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] + # python code goes here + [python]*/ + +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] + print('static int __ignored_unused_variable__ = 0;') + [python]*/ + static int __ignored_unused_variable__ = 0; + /*[python checksum:...]*/ + + +Using a "self converter" +------------------------ + +Argument Clinic automatically adds a "self" parameter for you +using a default converter. 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 +``self_converter`` or a subclass thereof. + +What's the point? This lets you automatically cast ``self`` +from ``PyObject *`` to a custom type. + +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] + + _pickle.Pickler.dump + + self: self(type="PicklerObject *") + obj: object + / + + Write a pickled representation of the given object to the open file. + [clinic]*/ + +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 +``self_converter`` but overwriting the ``type`` member:: + + /*[clinic] + class PicklerObject_converter(self_converter): + type = "PicklerObject *" + [clinic]*/ + + /*[clinic] + + _pickle.Pickler.dump + + self: PicklerObject + obj: object + / + + Write a pickled representation of the given object to the open file. + [clinic]*/ + + + +Writing a custom converter +-------------------------- + +As we hinted at in the previous section... you can write your own converters! +A converter is simply a Python class that inherits from ``CConverter``. +The main purpose of a custom converter is if you have a parameter using +the ``O&`` format unit--parsing this parameter means calling +a ``PyArg_ParseTuple()`` "converter function". + +Your converter class should be named ``*something*_converter``. +If the name follows this convention, then your converter class +will be automatically registered with Argument Clinic; its name +will be the name of your class with the ``_converter`` suffix +stripped off. (This is done automatically for you with a metaclass.) + +You shouldn't subclass ``CConverter.__init__``. Instead, you should +write a ``converter_init()`` function. ``converter_init()`` +always accepts a ``self`` parameter; after that, all additional +parameters *must* be keyword-only. Any arguments passed in to +the converter in Argument Clinic will be passed along to your +``converter_init()``. + +There are some additional members of ``CConverter`` you may wish +to specify in your subclass. Here's the current list: + +``type`` + The C type to use for this variable. + ``type`` should be a Python string specifying the type, e.g. ``int``. + If this is a pointer type, the type string should end with ``' *'``. + +``default`` + The Python default value for this parameter, as a Python value. + Or the magic value ``unspecified`` if there is no default. + +``doc_default`` + ``default`` as it should appear in the documentation, + as a string. + Or ``None`` if there is no default. + This string, when run through ``eval()``, should produce + a Python value. + +``py_default`` + ``default`` as it should appear in Python code, + as a string. + Or ``None`` if there is no default. + +``c_default`` + ``default`` as it should appear in C code, + as a string. + Or ``None`` if there is no default. + +``c_ignored_default`` + The default value used to initialize the C variable when + there is no default, but not specifying a default may + result in an "uninitialized variable" warning. This is + easily happen when using option groups--although + properly-written code won't actually use the variable, + the variable does get passed in to the _impl, and the + C compiler will complain about the "use" of the uninitialized + value. This value should be a string. + +``converter`` + The name of the C converter function, as a string. + +``impl_by_reference`` + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into the impl function. + +``parse_by_reference`` + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into ``PyArg_ParseTuple()``. + + +Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``:: + + /*[python] + + class uint_converter(CConverter): + type = 'unsigned int' + converter = 'uint_converter' + + [python]*/ + /*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + +This block adds a ``uint`` converter to Argument Clinic. Parameters +declared as ``uint`` will be declared as type ``unsigned int``, and will +be parsed by calling the ``uint_converter`` converter function in C. +``uint`` 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``. + +Writing a custom return converter +--------------------------------- + +Writing a custom return converter is much like writing +a custom converter. Except it's much simpler, because return +converters are themselves much simpler. + +Return converters must subclass ``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 ``Tools/clinic/clinic.py``, +specifically the implementation of ``CReturnConverter`` and +all its subclasses. + + +Using 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:: + + #/*[python] + #print("def foo(): pass") + #[python]*/ + def foo(): pass + #/*[python checksum:...]*/ From 2c5488037abe072838c336428981763be6cbf7b7 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sun, 5 Jan 2014 02:50:45 -0800 Subject: [PATCH 118/538] Argument Clinic: fixed test suite, improved howto. --- Doc/howto/clinic.rst | 241 +++++++++++++++++++++++++++---------------- 1 file changed, 154 insertions(+), 87 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index afbeb417a..2d8a0533e 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -14,21 +14,20 @@ Argument Clinic How-To function to work with Argument Clinic, and then introduces some advanced topics on Argument Clinic usage. - Argument Clinic is currently considered an internal - tool for the CPython code tree. Its use is not supported - for files outside the CPython code tree, and no guarantees - are made regarding backwards compatibility for future - versions. In other words: if you maintain an external C - extension for CPython, you're welcome to experiment with - Argument Clinic in your own code. But the version of Argument - Clinic that ships with CPython 3.5 *could* be totally - incompatible and break all your code. + Currently Argument Clinic is considered internal-only + for CPython. Its use is not supported for files outside + CPython, and no guarantees are made regarding backwards + compatibility for future versions. In other words: if you + maintain an external C extension for CPython, you're welcome + to experiment with Argument Clinic in your own code. But the + version of Argument Clinic that ships with CPython 3.5 *could* + be totally incompatible and break all your code. ======================== Basic Concepts And Usage ======================== -Argument Clinic ships with CPython. You can find it in ``Tools/clinic/clinic.py``. +Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. If you run that script, specifying a C file as an argument:: % python3 Tools/clinic/clinic.py foo.c @@ -45,13 +44,12 @@ like this:: Everything in between these two lines is input for Argument Clinic. All of these lines, including the beginning and ending comment -lines, are collectively called an Argument Clinic "input block", -or "block" for short. +lines, are collectively called an Argument Clinic "block". When Argument Clinic parses one of these blocks, it generates output. This output is rewritten into the C file immediately after the block, followed by a comment containing a checksum. -The resulting Argument Clinic block looks like this:: +The Argument Clinic block now looks like this:: /*[clinic] ... clinic input goes here ... @@ -65,7 +63,8 @@ line. However, if the input hasn't changed, the output won't change either. You should never modify the output portion of an Argument Clinic block. Instead, change the input until it produces the output you want. (That's the purpose of the -checksum--to detect and warn you in case someone accidentally modifies the output.) +checksum--to detect if someone changed the output, as these edits would be lost +the next time Argument Clinic writes out fresh output.) For the sake of clarity, here's the terminology we'll use with Argument Clinic: @@ -87,10 +86,12 @@ Converting Your First Function The best way to get a sense of how Argument Clinic works is to convert a function to work with it. Let's dive in! -0. Make sure you're working with a freshly updated trunk. +0. Make sure you're working with a freshly updated checkout + of the CPython trunk. -1. Find a Python builtin that calls either ``PyArg_ParseTuple()`` - or ``PyArg_ParseTupleAndKeywords()``, and hasn't been converted yet. +1. 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 my example I'm using ``pickle.Pickler.dump()``. 2. If the call to the ``PyArg_Parse`` function uses any of the @@ -103,7 +104,7 @@ convert a function to work with it. Let's dive in! et et# - or if it has multiple calls to ``PyArg_ParseTuple()``, + or if it has multiple calls to :c:func:`PyArg_ParseTuple`, you should choose a different function. Argument Clinic *does* support all of these scenarios. But these are advanced topics--let's do something simpler for your first function. @@ -130,7 +131,7 @@ convert a function to work with it. Let's dive in! be a paragraph consisting of a single 80-column line at the beginning of the docstring. - (Our docstring consists solely of the summary line, so the sample + (Our example docstring consists solely of a summary line, so the sample code doesn't have to change for this step.) 6. Above the docstring, enter the name of the function, followed @@ -198,7 +199,8 @@ convert a function to work with it. Let's dive in! string. ("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.) + 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. @@ -231,14 +233,18 @@ convert a function to work with it. Let's dive in! (``pickle.Pickler.dump`` has neither, so our sample is unchanged.) -10. If the existing C function uses ``PyArg_ParseTuple()`` - (instead of ``PyArg_ParseTupleAndKeywords()``), then all its +10. 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 all parameters as positional-only in Argument Clinic, add a ``/`` on a line by itself after the last parameter, indented the same as the parameter lines. + Currently this is all-or-nothing; either all parameters are + positional-only, or none of them are. (In the future Argument + Clinic may relax this restriction.) + Sample:: /*[clinic] @@ -255,16 +261,16 @@ convert a function to work with it. Let's dive in! Write a pickled representation of obj to the open file. [clinic]*/ -11. It's helpful to write a per-parameter docstring, indented - another level past the parameter declaration. But per-parameter - docstrings are optional; you can skip this step if you prefer. +11. It's helpful to write a per-parameter docstring for each parameter. + But per-parameter docstrings are optional; you can skip this step + if you prefer. - Here's how per-parameter docstrings work. The first line + 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. This left margin 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 as you like, - across multiple lines if you wish. + 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:: @@ -311,28 +317,47 @@ convert a function to work with it. Let's dive in! pickle_Pickler_dump_impl(PyObject *self, PyObject *obj) /*[clinic checksum: 3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ + 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. + 13. 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 - ``PyArg_ParseTuple()`` or ``PyArg_ParseTupleAndKeywords()``; + :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`; ensure that the code generated by Argument Clinic calls the - same function. + *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, or an encoding string, or a pointer + to a conversion function), ensure that the second argument is + *exactly* the same between the two invocations. - Second, the format string passed in to ``PyArg_ParseTuple()`` or - ``PyArg_ParseTupleAndKeywords()`` should be *exactly* the same - as the hand-written one in the existing function. + 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:: - Well, there's one way that Argument Clinic's output is permitted - to be different. Argument Clinic always generates a format string - ending with ``:`` followed by the name of the function. If the - format string originally ended with ``;`` (to specify usage help), - this is harmless--don't worry about this difference. + #define _PICKLE_PICKLER_DUMP_METHODDEF \ + {"dump", (PyCFunction)_pickle_Pickler_dump, METH_O, _pickle_Pickler_dump__doc__}, - Apart from that, if either of these things differ in *any way*, - fix your input to Argument Clinic and rerun ``Tools/clinic/clinic.py`` - until they are the same. + 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. 14. Notice that the last line of its output is the declaration @@ -342,8 +367,19 @@ convert a function to work with it. Let's dive in! 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. - The result should be a function that handles just the implementation - of the Python function without any argument-parsing code. + + Let's reiterate, just because it's kind of weird. Your code should now + look like this:: + + static return_type + your_function_impl(...) + /*[clinic checksum: ...]*/ + { + ... + + 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:: @@ -386,7 +422,27 @@ convert a function to work with it. Let's dive in! ... -15. Compile and run the relevant portions of the regression-test suite. +15. 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. So 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 */ + }; + + +16. 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. @@ -405,11 +461,11 @@ Renaming the C functions 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: you can explicitly -specify the base name to use for the C functions. Just add the keyword ``"as"`` +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 the function name you use for the base (generated) function, -and then add ``"_impl"`` to the end for the name of the impl function. +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 ``pickle.Pickler.dump``, it'd look like this:: @@ -420,7 +476,7 @@ For example, if we wanted to rename the C function names generated for ... The base function would now be named ``pickler_dumper()``, -and the impl function would be named ``pickler_dumper_impl()``. +and the impl function would now be named ``pickler_dumper_impl()``. Optional Groups @@ -428,15 +484,15 @@ 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 ``PyArg_ParseTuple()`` calls depending on +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 ``PyArg_ParseTupleAndKeywords()`` was created. +arguments back before :c:func:`PyArg_ParseTupleAndKeywords` was created. -Functions using this approach can often be converted to -use ``PyArg_ParseTupleAndKeywords()``, optional arguments, and default values. -But it's not always possible, because some of these legacy functions have -behaviors ``PyArg_ParseTupleAndKeywords()`` can't directly support. +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 ``range()``, which has an optional argument on the *left* side of its required argument! Another example is ``curses.window.addch()``, which has a group of two @@ -445,16 +501,17 @@ 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.) -For the sake of backwards compatibility, Argument Clinic supports this -alternate approach to parsing, using what are called *optional groups*. -Optional groups are groups of arguments that can only be specified together. +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. To specify an optional group, add a ``[`` on a line by itself before -the parameters you wish to be -in a group together, and a ``]`` on a line by itself after the -parameters. As an example, here's how ``curses.window.addch`` +the parameters you wish to group together, and a ``]`` on a line by itself +after these parameters. As an example, here's how ``curses.window.addch`` uses optional groups to make the first two parameters and the last parameter optional:: @@ -484,8 +541,8 @@ parameter optional:: Notes: * For every optional group, one additional parameter will be passed into the - impl function representing the group. The parameter will be an int, and it will - be named ``group_{direction}_{number}``, + 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 @@ -495,11 +552,13 @@ Notes: in this invocation.) * If there are no required arguments, the optional groups will behave - as if they are to the right of the required arguments. + 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. @@ -509,7 +568,7 @@ Using 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 the "legacy converters". "Legacy converters" are a convenience, +you to use "legacy converters". "Legacy converters" are a convenience, designed explicitly to make porting existing code to Argument Clinic easier. And to be clear, their use is entirely acceptable when porting code for Python 3.4. @@ -523,18 +582,19 @@ reasons: 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 ``PyArg_ParseTuple()`` supports. + restricted to what :c:func:`PyArg_ParseTuple` supports; this flexibility + won't be available to parameters using legacy converters. -So if you want -to go that extra effort, you should consider using normal -converters instead of the legacy converters. +Therefore, if you don't mind a little extra effort, you should consider +using 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. All parameters to Argument Clinic converters are keyword-only. +the same converters. +All arguments to Argument Clinic converters are keyword-only. All Argument Clinic converters accept the following arguments: ``doc_default`` @@ -643,11 +703,11 @@ the text, and add more entries to the dict mapping types to strings just above i Note also that this approach takes away some possible flexibility for the format units starting with ``e``. It used to be possible to decide at runtime what -encoding string to pass in to ``PyArg_ParseTuple()``. But now this string must +encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must be hard-coded at compile-time. This limitation is deliberate; it made supporting this format unit much easier, and may allow for future compile-time optimizations. This restriction does not seem unreasonable; CPython itself always passes in static -hard-coded strings when using format units starting with ``e``. +hard-coded encoding strings for parameters whose format units start with ``e``. Using a return converter @@ -692,12 +752,17 @@ None of these take parameters. For the first three, return -1 to indicate error. For ``DecodeFSDefault``, the return type is ``char *``; return a NULL pointer to indicate an 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. + + Calling Python code ------------------- The rest of the advanced topics require you to write Python code -which lives inside your C file and modifies Argument Clinic at -runtime. This is simple; you simply define a Python block. +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:: @@ -778,13 +843,13 @@ As we hinted at in the previous section... you can write your own converters! A converter is simply a Python class that inherits from ``CConverter``. The main purpose of a custom converter is if you have a parameter using the ``O&`` format unit--parsing this parameter means calling -a ``PyArg_ParseTuple()`` "converter function". +a :c:func:`PyArg_ParseTuple` "converter function". Your converter class should be named ``*something*_converter``. If the name follows this convention, then your converter class will be automatically registered with Argument Clinic; its name will be the name of your class with the ``_converter`` suffix -stripped off. (This is done automatically for you with a metaclass.) +stripped off. (This is accomplished with a metaclass.) You shouldn't subclass ``CConverter.__init__``. Instead, you should write a ``converter_init()`` function. ``converter_init()`` @@ -825,12 +890,13 @@ to specify in your subclass. Here's the current list: ``c_ignored_default`` The default value used to initialize the C variable when there is no default, but not specifying a default may - result in an "uninitialized variable" warning. This is + result in an "uninitialized variable" warning. This can easily happen when using option groups--although - properly-written code won't actually use the variable, - the variable does get passed in to the _impl, and the - C compiler will complain about the "use" of the uninitialized - value. This value should be a string. + properly-written code will never actually use this value, + the variable does get passed in to the impl, and the + C compiler will complain about the "use" of the + uninitialized value. This value should always be a + non-empty string. ``converter`` The name of the C converter function, as a string. @@ -843,7 +909,7 @@ to specify in your subclass. Here's the current list: ``parse_by_reference`` A boolean value. If true, Argument Clinic will add a ``&`` in front of the name of - the variable when passing it into ``PyArg_ParseTuple()``. + the variable when passing it into :c:func:`PyArg_ParseTuple`. Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``:: @@ -857,9 +923,10 @@ Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c`` [python]*/ /*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ -This block adds a ``uint`` converter to Argument Clinic. Parameters +This block adds a converter to Argument Clinic named ``uint``. Parameters declared as ``uint`` will be declared as type ``unsigned int``, and will -be parsed by calling the ``uint_converter`` converter function in C. +be parsed by the ``'O&'`` format unit, which will call the ``uint_converter`` +converter function. ``uint`` variables automatically support default values. More sophisticated custom converters can insert custom C code to @@ -871,7 +938,7 @@ Writing a custom return converter --------------------------------- Writing a custom return converter is much like writing -a custom converter. Except it's much simpler, because return +a custom converter. Except it's somewhat simpler, because return converters are themselves much simpler. Return converters must subclass ``CReturnConverter``. From 3cd45433622442de24e903ab392d5e0ff9e866bd Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Tue, 7 Jan 2014 12:13:13 -0800 Subject: [PATCH 119/538] Issue #20141: Improved Argument Clinic's support for the PyArg_Parse "O!" format unit. GitHub-Issue-Link: https://github.com/python/cpython/issues/64340 --- Doc/howto/clinic.rst | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 2d8a0533e..a22a11f22 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -640,7 +640,7 @@ on the right is the text you'd replace it with. ``'K'`` ``unsigned_PY_LONG_LONG`` ``'L'`` ``PY_LONG_LONG`` ``'n'`` ``Py_ssize_t`` -``'O!'`` ``object(type='name_of_Python_type')`` +``'O!'`` ``object(subclass_of='&PySomething_Type')`` ``'O&'`` ``object(converter='name_of_c_function')`` ``'O'`` ``object`` ``'p'`` ``bool`` @@ -693,20 +693,22 @@ 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&``), ``type`` (for ``O!``), +argument is either ``converter`` (for ``O&``), ``subclass_of`` (for ``O!``), or ``encoding`` (for all the format units that start with ``e``). -Note that ``object()`` must explicitly support each Python type you specify -for the ``type`` argument. Currently it only supports ``str``. It should be -easy to add more, just edit ``Tools/clinic/clinic.py``, search for ``O!`` in -the text, and add more entries to the dict mapping types to strings just above it. +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 ``PyUnicode_Type``, you probably want +to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type')``. -Note also that this approach takes away some possible flexibility for the format -units starting with ``e``. It used to be possible to decide at runtime what +One possible problem with using Argument Clinic: it takes away some possible +flexibility for the format units starting with ``e``. When writing a +``PyArg_Parse`` call by hand, you could theoretically decide at runtime what encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must -be hard-coded at compile-time. This limitation is deliberate; it made supporting -this format unit much easier, and may allow for future compile-time optimizations. -This restriction does not seem unreasonable; CPython itself always passes in static +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``. @@ -796,7 +798,8 @@ block, and ensure that its converter is an instance of ``self_converter`` or a subclass thereof. What's the point? This lets you automatically cast ``self`` -from ``PyObject *`` to a custom type. +from ``PyObject *`` to a custom type, just like ``object()`` +does with its ``type`` parameter. 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``, From 29ac2564500f703f6981466ba5aae513f7e435fa Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Tue, 7 Jan 2014 12:41:53 -0800 Subject: [PATCH 120/538] Issue #19273: The marker comments Argument Clinic uses have been changed to improve readability. GitHub-Issue-Link: https://github.com/python/cpython/issues/63472 --- Doc/howto/clinic.rst | 126 +++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index a22a11f22..555fa68d4 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -35,12 +35,12 @@ If you run that script, specifying a C file as an argument:: Argument Clinic will scan over the file looking for lines that look exactly like this:: - /*[clinic] + /*[clinic input] When it finds one, it reads everything up to a line that looks -like this:: +exactly like this:: - [clinic]*/ + [clinic start generated code]*/ Everything in between these two lines is input for Argument Clinic. All of these lines, including the beginning and ending comment @@ -51,11 +51,11 @@ generates output. This output is rewritten into the C file immediately after the block, followed by a comment containing a checksum. The Argument Clinic block now looks like this:: - /*[clinic] + /*[clinic input] ... clinic input goes here ... - [clinic]*/ + [clinic start generated code]*/ ... clinic output goes here ... - /*[clinic checksum:...]*/ + /*[clinic end generated code: checksum=...]*/ If you run Argument Clinic on the same file a second time, Argument Clinic will discard the old output and write out the new output with a fresh checksum @@ -68,9 +68,9 @@ the next time Argument Clinic writes out fresh output.) For the sake of clarity, here's the terminology we'll use with Argument Clinic: -* The first line of the comment (``/*[clinic]``) is the *start line*. -* The last line of the initial comment (``[clinic]*/``) is the *end line*. -* The last line (``/*[clinic checksum:...]*/``) is the *checksum line*. +* The first line of the comment (``/*[clinic input]``) is the *start line*. +* The last line of the initial comment (``[clinic start generated code]*/``) is the *end line*. +* The last line (``/*[clinic end generated code: checksum=...]*/``) is the *checksum line*. * In between the start line and the end line is the *input*. * In between the end line and the checksum line is the *output*. * All the text collectively, from the start line to the checksum line inclusively, @@ -111,8 +111,8 @@ convert a function to work with it. Let's dive in! 3. Add the following boilerplate above the function, creating our block:: - /*[clinic] - [clinic]*/ + /*[clinic input] + [clinic start generated code]*/ 4. Cut the docstring and paste it in between the ``[clinic]`` lines, removing all the junk that makes it a properly quoted C string. @@ -122,9 +122,9 @@ convert a function to work with it. Let's dive in! Sample:: - /*[clinic] + /*[clinic input] Write a pickled representation of obj to the open file. - [clinic]*/ + [clinic start generated code]*/ 5. 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 @@ -143,11 +143,11 @@ convert a function to work with it. Let's dive in! Sample:: - /*[clinic] + /*[clinic input] pickle.Pickler.dump Write a pickled representation of obj to the open file. - [clinic]*/ + [clinic start generated code]*/ 7. If this is the first time that module or class has been used with Argument Clinic in this C file, @@ -159,16 +159,16 @@ convert a function to work with it. Let's dive in! Sample:: - /*[clinic] + /*[clinic input] module pickle class pickle.Pickler - [clinic]*/ + [clinic start generated code]*/ - /*[clinic] + /*[clinic input] pickle.Pickler.dump Write a pickled representation of obj to the open file. - [clinic]*/ + [clinic start generated code]*/ 8. Declare each of the parameters to the function. Each parameter @@ -207,18 +207,18 @@ convert a function to work with it. Let's dive in! Sample:: - /*[clinic] + /*[clinic input] module pickle class pickle.Pickler - [clinic]*/ + [clinic start generated code]*/ - /*[clinic] + /*[clinic input] pickle.Pickler.dump obj: 'O' Write a pickled representation of obj to the open file. - [clinic]*/ + [clinic start generated code]*/ 9. If your function has ``|`` in the format string, meaning some parameters have default values, you can ignore it. Argument @@ -247,19 +247,19 @@ convert a function to work with it. Let's dive in! Sample:: - /*[clinic] + /*[clinic input] module pickle class pickle.Pickler - [clinic]*/ + [clinic start generated code]*/ - /*[clinic] + /*[clinic input] pickle.Pickler.dump obj: 'O' / Write a pickled representation of obj to the open file. - [clinic]*/ + [clinic start generated code]*/ 11. It's helpful to write a per-parameter docstring for each parameter. But per-parameter docstrings are optional; you can skip this step @@ -274,12 +274,12 @@ convert a function to work with it. Let's dive in! Sample:: - /*[clinic] + /*[clinic input] module pickle class pickle.Pickler - [clinic]*/ + [clinic start generated code]*/ - /*[clinic] + /*[clinic input] pickle.Pickler.dump obj: 'O' @@ -287,19 +287,19 @@ convert a function to work with it. Let's dive in! / Write a pickled representation of obj to the open file. - [clinic]*/ + [clinic start generated code]*/ 12. Save and close the file, then run ``Tools/clinic/clinic.py`` on it. With luck everything worked and your block now has output! Reopen the file in your text editor to see:: - /*[clinic] + /*[clinic input] module pickle class pickle.Pickler - [clinic]*/ - /*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + [clinic start generated code]*/ + /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - /*[clinic] + /*[clinic input] pickle.Pickler.dump obj: 'O' @@ -307,7 +307,7 @@ convert a function to work with it. Let's dive in! / Write a pickled representation of obj to the open file. - [clinic]*/ + [clinic start generated code]*/ PyDoc_STRVAR(pickle_Pickler_dump__doc__, "Write a pickled representation of obj to the open file.\n" @@ -315,7 +315,7 @@ convert a function to work with it. Let's dive in! ... static PyObject * pickle_Pickler_dump_impl(PyObject *self, PyObject *obj) - /*[clinic checksum: 3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ + /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ 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 @@ -373,7 +373,7 @@ convert a function to work with it. Let's dive in! static return_type your_function_impl(...) - /*[clinic checksum: ...]*/ + /*[clinic end generated code: checksum=...]*/ { ... @@ -383,13 +383,13 @@ convert a function to work with it. Let's dive in! Sample:: - /*[clinic] + /*[clinic input] module pickle class pickle.Pickler - [clinic]*/ - /*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + [clinic start generated code]*/ + /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - /*[clinic] + /*[clinic input] pickle.Pickler.dump obj: 'O' @@ -397,7 +397,7 @@ convert a function to work with it. Let's dive in! / Write a pickled representation of obj to the open file. - [clinic]*/ + [clinic start generated code]*/ PyDoc_STRVAR(pickle_Pickler_dump__doc__, "Write a pickled representation of obj to the open file.\n" @@ -405,7 +405,7 @@ convert a function to work with it. Let's dive in! ... static PyObject * pickle_Pickler_dump_impl(PyObject *self, PyObject *obj) - /*[clinic checksum: 3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ + /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ { /* Check whether the Pickler was initialized correctly (issue3664). Developers often forget to call __init__() in their subclasses, which @@ -470,7 +470,7 @@ 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 ``pickle.Pickler.dump``, it'd look like this:: - /*[clinic] + /*[clinic input] pickle.Pickler.dump as pickler_dumper ... @@ -515,7 +515,7 @@ after these parameters. As an example, here's how ``curses.window.addch`` uses optional groups to make the first two parameters and the last parameter optional:: - /*[clinic] + /*[clinic input] curses.window.addch @@ -666,7 +666,7 @@ on the right is the text you'd replace it with. As an example, here's our sample ``pickle.Pickler.dump`` using the proper converter:: - /*[clinic] + /*[clinic input] pickle.Pickler.dump obj: object @@ -674,7 +674,7 @@ converter:: / Write a pickled representation of obj to the open file. - [clinic]*/ + [clinic start generated code]*/ Argument Clinic will show you all the converters it has available. For each converter it'll show you all the parameters @@ -769,9 +769,9 @@ 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] + /*[python input] # python code goes here - [python]*/ + [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 @@ -780,9 +780,9 @@ 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] + /*[python input] print('static int __ignored_unused_variable__ = 0;') - [python]*/ + [python start generated code]*/ static int __ignored_unused_variable__ = 0; /*[python checksum:...]*/ @@ -806,7 +806,7 @@ 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] + /*[clinic input] _pickle.Pickler.dump @@ -815,18 +815,18 @@ passing in the type you want to use as the ``type`` parameter:: / Write a pickled representation of the given object to the open file. - [clinic]*/ + [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 ``self_converter`` but overwriting the ``type`` member:: - /*[clinic] + /*[clinic input] class PicklerObject_converter(self_converter): type = "PicklerObject *" - [clinic]*/ + [clinic start generated code]*/ - /*[clinic] + /*[clinic input] _pickle.Pickler.dump @@ -835,7 +835,7 @@ type for ``self``, it's best to create your own converter, subclassing / Write a pickled representation of the given object to the open file. - [clinic]*/ + [clinic start generated code]*/ @@ -917,14 +917,14 @@ to specify in your subclass. Here's the current list: Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``:: - /*[python] + /*[python input] class uint_converter(CConverter): type = 'unsigned int' converter = 'uint_converter' - [python]*/ - /*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + [python start generated code]*/ + /*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ This block adds a converter to Argument Clinic named ``uint``. Parameters declared as ``uint`` will be declared as type ``unsigned int``, and will @@ -963,8 +963,8 @@ 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:: - #/*[python] + #/*[python input] #print("def foo(): pass") - #[python]*/ + #[python start generated code]*/ def foo(): pass #/*[python checksum:...]*/ From f2a1796f19835fda7a9d1dd4fbb93974b4f3043e Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Thu, 9 Jan 2014 21:41:23 -0600 Subject: [PATCH 121/538] Closes #20200: Argument Clinic custom converter example should be in a 'python' clinic block, not a 'clinic' clinic block. Patch written by Ryan Smith-Roberts. GitHub-Issue-Link: https://github.com/python/cpython/issues/64399 --- Doc/howto/clinic.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 555fa68d4..2324142c6 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -821,10 +821,10 @@ 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 ``self_converter`` but overwriting the ``type`` member:: - /*[clinic input] + /*[python input] class PicklerObject_converter(self_converter): type = "PicklerObject *" - [clinic start generated code]*/ + [python start generated code]*/ /*[clinic input] From 6f86b5a218b6df1325290b034dcaf5a9063926b8 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sun, 12 Jan 2014 11:09:57 -0800 Subject: [PATCH 122/538] Issue #20214: Fixed a number of small issues and documentation errors in Argument Clinic (see issue for details). GitHub-Issue-Link: https://github.com/python/cpython/issues/64413 --- Doc/howto/clinic.rst | 140 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 120 insertions(+), 20 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 2324142c6..e9e1377cb 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -109,6 +109,13 @@ convert a function to work with it. Let's dive in! support all of these scenarios. But these are advanced topics--let's do something simpler for your first function. + 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 + 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. + 3. Add the following boilerplate above the function, creating our block:: /*[clinic input] @@ -170,6 +177,11 @@ convert a function to work with it. Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ + 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. + + 8. Declare each of the parameters to the function. Each parameter should get its own line. All the parameter lines should be @@ -455,6 +467,28 @@ convert a function to work with it. Let's dive in! Advanced Topics =============== +Now that you've had some experience working with Argument Clinic, it's time +for some advanced topics. + + +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 ``sys.maxsize``, which must + start with the name of the module + +In case you're curious, this is implemented in ``from_builtin()`` +in ``Lib/inspect.py``. + +(In the future, this may need to get even more elaborate, +to allow full expressions like ``CONSTANT - 1``.) + Renaming the C functions generated by Argument Clinic ----------------------------------------------------- @@ -479,6 +513,29 @@ The base function would now be named ``pickler_dumper()``, and the impl function would now be named ``pickler_dumper_impl()``. +The NULL default value +---------------------- + +For string and object parameters, you can set them to ``None`` to indicate +that there is 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 case: from Python's perspective it +behaves like a default value of ``None``, but the C variable is initialized +with ``NULL``. + + +Converting 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. + Optional Groups --------------- @@ -570,8 +627,8 @@ 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. And to be clear, their use is entirely acceptable when porting -code for Python 3.4. +easier. And to be clear, their use is acceptable when porting code for +Python 3.4. However, in the long term we probably want all our blocks to use Argument Clinic's real syntax for converters. Why? A couple @@ -585,8 +642,8 @@ reasons: 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, you should consider -using normal converters instead of 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 @@ -597,12 +654,19 @@ the same converters. All arguments to Argument Clinic converters are keyword-only. All Argument Clinic converters accept the following arguments: -``doc_default`` - If the parameter takes a default value, normally this value is also - provided in the ``inspect.Signature`` metadata, and displayed in the - docstring. ``doc_default`` lets you override the value used in these - two places: pass in a string representing the Python value you wish - to use in these two contexts. +``py_default`` + The default value for this parameter when defined in Python. + Specifically, the value that will be used in the ``inspect.Signature`` + string. + If a default value is specified for the parameter, defaults to + ``repr(default)``, else defaults to ``None``. + Specified as a string. + +``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". + Specified as a string. ``required`` If a parameter takes a default value, Argument Clinic infers that the @@ -612,6 +676,9 @@ All Argument Clinic converters accept the following arguments: Clinic that this parameter is not optional, even if it has a default value. + (The need for ``required`` may be obviated by ``c_default``, which is + newer but arguably a better solution.) + ``annotation`` The annotation value for this parameter. Not currently supported, because PEP 8 mandates that the Python library may not use @@ -634,10 +701,11 @@ on the right is the text you'd replace it with. ``'et'`` ``str(encoding='name_of_encoding', types='bytes bytearray str')`` ``'f'`` ``float`` ``'h'`` ``short`` -``'H'`` ``unsigned_short`` +``'H'`` ``unsigned_short(bitwise=True)`` ``'i'`` ``int`` -``'I'`` ``unsigned_int`` -``'K'`` ``unsigned_PY_LONG_LONG`` +``'I'`` ``unsigned_int(bitwise=True)`` +``'k'`` ``unsigned_long(bitwise=True)`` +``'K'`` ``unsigned_PY_LONG_LONG(bitwise=True)`` ``'L'`` ``PY_LONG_LONG`` ``'n'`` ``Py_ssize_t`` ``'O!'`` ``object(subclass_of='&PySomething_Type')`` @@ -681,6 +749,14 @@ 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. +Py_buffer +--------- + +When using the ``Py_buffer`` converter +(or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters) +note that the code Argument Clinic generates for you will automatically +call :c:func:`PyBuffer_Release` on the buffer for you. + Advanced converters ------------------- @@ -745,15 +821,26 @@ encode the value you return like normal. Currently Argument Clinic supports only a few return converters:: + bool int + unsigned int long + unsigned int + size_t Py_ssize_t + float + double DecodeFSDefault None of these take parameters. For the first three, return -1 to indicate error. For ``DecodeFSDefault``, the return type is ``char *``; return a NULL pointer to indicate an error. +(There's also an experimental ``NoneType`` converter, which lets you +return ``Py_None`` on success or ``NULL`` on failure, without having +to increment the reference count on ``Py_None``. I'm not sure it adds +enough clarity to be worth using.) + 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. @@ -873,13 +960,6 @@ to specify in your subclass. Here's the current list: The Python default value for this parameter, as a Python value. Or the magic value ``unspecified`` if there is no default. -``doc_default`` - ``default`` as it should appear in the documentation, - as a string. - Or ``None`` if there is no default. - This string, when run through ``eval()``, should produce - a Python value. - ``py_default`` ``default`` as it should appear in Python code, as a string. @@ -951,6 +1031,26 @@ write your own return converter, please read ``Tools/clinic/clinic.py``, specifically the implementation of ``CReturnConverter`` and all its subclasses. +METH_O and METH_NOARGS +---------------------------------------------- + +To convert a function using ``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 ``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 ``METH_O``. Using Argument Clinic in Python files ------------------------------------- From 0083c627af5785dcfb1cc9d497388118190e839c Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sun, 12 Jan 2014 13:57:36 -0800 Subject: [PATCH 123/538] Minor doc fix in Clinic howto. --- Doc/howto/clinic.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index e9e1377cb..9c558bc50 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -753,9 +753,10 @@ Py_buffer --------- When using the ``Py_buffer`` converter -(or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters) -note that the code Argument Clinic generates for you will automatically -call :c:func:`PyBuffer_Release` on the buffer for you. +(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). + Advanced converters From f76bc2656e8262da0ffd1b893726cd644ab16f4f Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Tue, 14 Jan 2014 22:22:41 -0800 Subject: [PATCH 124/538] Issue #20268: Argument Clinic now supports cloning the parameters and return converter from existing functions. GitHub-Issue-Link: https://github.com/python/cpython/issues/64467 --- Doc/howto/clinic.rst | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 9c558bc50..0df8d445c 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -847,6 +847,49 @@ their parameters (if any), just run ``Tools/clinic/clinic.py --converters`` for the full list. +Cloning 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. + Calling Python code ------------------- From 1357eddff649c076f6320a18ce7563a6b6c22406 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Thu, 16 Jan 2014 11:32:01 -0800 Subject: [PATCH 125/538] Issue #20226: Major improvements to Argument Clinic. * You may now specify an expression as the default value for a parameter! Example: "sys.maxsize - 1". This support is intentionally quite limited; you may only use values that can be represented as static C values. * Removed "doc_default", simplified support for "c_default" and "py_default". (I'm not sure we still even need "py_default", but I'm leaving it in for now in case a use presents itself.) * Parameter lines support a trailing '\\' as a line continuation character, allowing you to break up long lines. * The argument parsing code generated when supporting optional groups now uses PyTuple_GET_SIZE instead of PyTuple_GetSize, leading to a 850% speedup in parsing. (Just kidding, this is an unmeasurable difference.) * A bugfix for the recent regression where the generated prototype from pydoc for builtins would be littered with unreadable "="" default values for parameters that had no default value. * Converted some asserts into proper failure messages. * Many doc improvements and fixes. GitHub-Issue-Link: https://github.com/python/cpython/issues/64425 --- Doc/howto/clinic.rst | 269 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 227 insertions(+), 42 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 0df8d445c..96f84b01e 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -127,6 +127,12 @@ convert a function to work with it. Let's dive in! 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 ``help()`` on your builtin in the future, + the first line will be built automatically based on the function's + signature.) + Sample:: /*[clinic input] @@ -196,6 +202,10 @@ convert a function to work with it. Let's dive in! name_of_parameter: converter = default_value + Argument Clinic's support for "default values" is quite sophisticated; + please see :ref:`the section below on default values ` + for more information. + Add a blank line below the parameters. What's a "converter"? It establishes both the type @@ -513,16 +523,6 @@ The base function would now be named ``pickler_dumper()``, and the impl function would now be named ``pickler_dumper_impl()``. -The NULL default value ----------------------- - -For string and object parameters, you can set them to ``None`` to indicate -that there is 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 case: from Python's perspective it -behaves like a default value of ``None``, but the C variable is initialized -with ``NULL``. - Converting functions using PyArg_UnpackTuple -------------------------------------------- @@ -654,35 +654,70 @@ the same converters. All arguments to Argument Clinic converters are keyword-only. All Argument Clinic converters accept the following arguments: -``py_default`` - The default value for this parameter when defined in Python. - Specifically, the value that will be used in the ``inspect.Signature`` - string. - If a default value is specified for the parameter, defaults to - ``repr(default)``, else defaults to ``None``. - Specified as a string. - -``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". - Specified as a string. - -``required`` - If a parameter takes a default value, Argument Clinic infers that the - parameter is optional. However, you may want a parameter to take a - default value in C, but not behave in Python as if the parameter is - optional. Passing in ``required=True`` to a converter tells Argument - Clinic that this parameter is not optional, even if it has a default - value. - - (The need for ``required`` may be obviated by ``c_default``, which is - newer but arguably a better solution.) - -``annotation`` - The annotation value for this parameter. Not currently supported, - because PEP 8 mandates that the Python library may not use - annotations. + ``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. + +In addition, some converters accept additional arguments. Here is a list +of these arguments, along with their meanings: + + ``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. + + ``length`` + Only supported for strings. If true, requests that the length of the + string be passed in to the impl function, just after the string parameter, + in a parameter named ``_length``. + + ``nullable`` + Only supported for strings. If true, this parameter may also be set to + ``None``, in which case the C parameter will be set to ``NULL``. + + ``subclass_of`` + Only supported for the ``object`` converter. Requires that the Python + value be a subclass of a Python type, as expressed in C. + + ``types`` + Only supported for the ``object`` (and ``self``) converter. Specifies + the C type that will be used to declare the variable. Default value is + ``"PyObject *"``. + + ``types`` + A string containing a list 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.) + + ``zeroes`` + Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are + permitted inside the value. + +Please note, not every possible combination of arguments will work. +Often these arguments are implemented internally by specific ``PyArg_ParseTuple`` +*format units*, with specific behavior. For example, currently you cannot +call ``str`` and pass in ``zeroes=True`` without also specifying an ``encoding``; +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, @@ -720,9 +755,9 @@ on the right is the text you'd replace it with. ``'u'`` ``Py_UNICODE`` ``'U'`` ``unicode`` ``'w*'`` ``Py_buffer(types='bytearray rwbuffer')`` -``'y#'`` ``str(type='bytes', length=True)`` +``'y#'`` ``str(types='bytes', length=True)`` ``'Y'`` ``PyByteArrayObject`` -``'y'`` ``str(type='bytes')`` +``'y'`` ``str(types='bytes')`` ``'y*'`` ``Py_buffer`` ``'Z#'`` ``Py_UNICODE(nullable=True, length=True)`` ``'z#'`` ``str(nullable=True, length=True)`` @@ -789,6 +824,90 @@ This restriction doesn't seem unreasonable; CPython itself always passes in stat hard-coded encoding strings for parameters whose format units start with ``e``. +.. _default_values: + +Parameter default values +------------------------ + +Default values for parameters can be any of a number of values. +At their simplest, they can be string, int, or float literals:: + + foo: str = "abc" + bar: int = 123 + bat: float = 45.6 + +They can also use any of Python's built-in constants:: + + 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``. + +Expressions specified 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:: + + foo: Py_ssize_t = sys.maxsize - 1 + +``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 "``max_widgets``", you may simply use it:: + + foo: Py_ssize_t = max_widgets + +If the symbol isn't found in the current module, it fails over to looking in +``sys.modules``. That's how it can find ``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:: + + 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. + + + Using a return converter ------------------------ @@ -1096,7 +1215,73 @@ any arguments. You can still use a self converter, a return converter, and specify a ``type`` argument to the object converter for ``METH_O``. -Using Argument Clinic in Python files +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 you'll have:: + + #ifdef HAVE_FUNCTIONNAME + {'functionname', ... }, + #endif /* HAVE_FUNCTIONNAME */ + +In this scenario, you should change the code to look like the following:: + + #ifdef HAVE_FUNCTIONNAME + /*[clinic input] + module.functionname + ... + [clinic start generated code]*/ + static module_functionname(...) + { + ... + } + #endif /* HAVE_FUNCTIONNAME */ + +Run Argument Clinic on the code in this state, then refresh the file in +your editor. Now you'll have the generated code, including the #define +for the ``PyMethodDef``, like so:: + + #ifdef HAVE_FUNCTIONNAME + /*[clinic input] + ... + [clinic start generated code]*/ + ... + #define MODULE_FUNCTIONNAME \ + {'functionname', ... }, + ... + /*[clinic end generated code: checksum=...]*/ + static module_functionname(...) + { + ... + } + #endif /* HAVE_FUNCTIONNAME */ + +Change the #endif at the bottom as follows:: + + #else + #define MODULE_FUNCTIONNAME + #endif /* HAVE_FUNCTIONNAME */ + +Now you can remove the #ifdefs around the ``PyMethodDef`` structure +at the end, and replace those three lines with ``MODULE_FUNCTIONNAME``. +If the function is available, the macro turns into the ``PyMethodDef`` +static value, including the trailing comma; if the function isn't +available, the macro turns into nothing. Perfect! + +(This is the preferred approach for optional functions; in the future, +Argument Clinic may generate the entire ``PyMethodDef`` structure.) + ------------------------------------- It's actually possible to use Argument Clinic to preprocess Python files. From d23512e37e453297fbef924966b46638a28b34d1 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Fri, 17 Jan 2014 17:47:17 -0800 Subject: [PATCH 126/538] Issue #20287: Argument Clinic's output is now configurable, allowing delaying its output or even redirecting it to a separate file. GitHub-Issue-Link: https://github.com/python/cpython/issues/64486 --- Doc/howto/clinic.rst | 320 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 319 insertions(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 96f84b01e..a61508e3f 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -23,6 +23,58 @@ Argument Clinic How-To version of Argument Clinic that ships with CPython 3.5 *could* be totally incompatible and break all your code. +============================ +The Goals Of Argument Clinic +============================ + +Argument Clinic's primary goal +is to take over responsibility for all argument parsing code +inside CPython. This means that, when you convert a function +to work with Argument Clinic, that function should no longer +do any of its own argument parsing--the code generated by +Argument Clinic should be a "black box" to you, where CPython +calls in at the top, and your code gets called at the bottom, +with ``PyObject *args`` (and maybe ``PyObject *kwargs``) +magically converted into the C variables and types you need. + +In order for Argument Clinic to accomplish its primary goal, +it must be easy to use. Currently, working with CPython's +argument parsing library is a chore, requiring maintaining +redundant information in a surprising number of places. +When you use Argument Clinic, you don't have to repeat yourself. + +Obviously, no one would want to use Argument Clinic unless +it's solving a their problem without creating problems of +its own. +So Argument Clinic should generate correct code, and its +code should preferably be slower, and definitely should +not introduce a major speed regression. (Eventually Argument +Clinic should enable a major speedup--we should be able +to rewrite its code generator so it produces tailor-made +parsing code, rather than using the general-purpose functions +from the CPython code base, which would make for the fastest +argument parsing possible.) + +Additionally, Argument Clinic must be flexible enough to +work with any approach to argument parsing. Python has +some functions with some very strange parsing behaviors; +Argument Clinic's goal is to support all of them. + +Finally, the original motivation for Argument Clinic was +to provide introspection "signatures" for CPython builtins. +It used to be, the introspection query functions would throw +an exception if you passed in a builtin. With Argument +Clinic, that's a thing of the past! + +One idea you should keep in mind, as you work with +Argument Clinic: the more information you give it, the +better job it'll be able to do. +Argument Clinic is admittedly relatively simple right +now. But as it evolves it will get more sophisticated, +and it should be able to do many interesting and smart +things with all the information you give it. + + ======================== Basic Concepts And Usage ======================== @@ -84,7 +136,15 @@ Converting Your First Function ============================== The best way to get a sense of how Argument Clinic works is to -convert a function to work with it. Let's dive in! +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 advanced concepts you'll see later on in +the document (like "return converters" and "self converters"). +But we'll keep it simple for this walkthrough so you can learn. + +Let's dive in! 0. Make sure you're working with a freshly updated checkout of the CPython trunk. @@ -1282,6 +1342,264 @@ available, the macro turns into nothing. Perfect! (This is the preferred approach for optional functions; in the future, Argument Clinic may generate the entire ``PyMethodDef`` structure.) + +Changing and redirecting 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 befire 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 ``PyMethodDef`` structure + is a field, called ``methoddef_define``. Clinic has seven + different fields it can output per function definition:: + + 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 exsiting 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 ``_pickle.c`` would be written to + ``_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 written once, and it prints out all text sent to it during + all of processing, even from Clinic blocks *after* the + + ``suppress`` + The text is suppressed--thrown away. + + +Clinic defines five new directives that let you reconfigure its output. + +The first new directive is ``dump``:: + + 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:: + + 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:: + + 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: + + ``original`` + Clinic's starting configuration. + + 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``. + + ``buffer`` + Save up all 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_defintion`` to ``buffer``, write everything else to ``block``. + +The third new directive is ``destination``:: + + destination [...] + +This performs an operation on the destination named ``name``. + +There are two defined subcommands: ``new`` and ``clear``. + +The ``new`` subcommand works like this:: + + 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: + + {filename} + The full filename. + {basename} + Everything up to but not including the last '.'. + {extension} + The last '.' and everything after it. + + 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:: + + 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``:: + + 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 suport 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``:: + + preserve + +This tells Clinic that the current contents of the output should be kept, unmodifed. +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. + + +Using Argument Clinic in Python files ------------------------------------- It's actually possible to use Argument Clinic to preprocess Python files. From 9b2c94482f694c375abb04fad6954a4c49c7c5ad Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sat, 18 Jan 2014 01:08:50 -0800 Subject: [PATCH 127/538] Doc improvements for Clinic howto "Goals" section. --- Doc/howto/clinic.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index a61508e3f..1f96e8245 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -44,16 +44,16 @@ redundant information in a surprising number of places. When you use Argument Clinic, you don't have to repeat yourself. Obviously, no one would want to use Argument Clinic unless -it's solving a their problem without creating problems of +it's solving their problem--and without creating new problems of its own. -So Argument Clinic should generate correct code, and its -code should preferably be slower, and definitely should -not introduce a major speed regression. (Eventually Argument -Clinic should enable a major speedup--we should be able -to rewrite its code generator so it produces tailor-made -parsing code, rather than using the general-purpose functions -from the CPython code base, which would make for the fastest -argument parsing possible.) +So it's paramount that Argument Clinic generate correct code. +It'd be nice if the code was faster, too, but at the very least +it should not introduce a major speed regression. (Eventually Argument +Clinic *should* make a major speedup possible--we could +rewrite its code generator to produce tailor-made argument +parsing code, rather than calling the general-purpose CPython +argument parsing library. That would make for the fastest +argument parsing possible!) Additionally, Argument Clinic must be flexible enough to work with any approach to argument parsing. Python has From e1a950b6d9ef3f7fbf6c77ef0fb566c53cffe516 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sat, 18 Jan 2014 23:50:21 -0800 Subject: [PATCH 128/538] Issue #20294: Argument Clinic now supports argument parsing for __new__ and __init__ functions. GitHub-Issue-Link: https://github.com/python/cpython/issues/64493 --- Doc/howto/clinic.rst | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 1f96e8245..5ee6c3da1 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -784,8 +784,8 @@ Argument Clinic converters. On the left is the legacy converter, on the right is the text you'd replace it with. ========= ================================================================================= -``'B'`` ``byte(bitwise=True)`` -``'b'`` ``byte`` +``'B'`` ``unsigned_char(bitwise=True)`` +``'b'`` ``unsigned_char`` ``'c'`` ``char`` ``'C'`` ``int(types='str')`` ``'d'`` ``double`` @@ -1275,6 +1275,25 @@ any arguments. You can still use a self converter, a return converter, and specify a ``type`` argument to the object converter for ``METH_O``. +tp_new and tp_init functions +---------------------------------------------- + +You can convert ``tp_new`` and ``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 ``PyMethodDef`` ``#define`` is generated for these functions. + +* ``__init__`` functions return ``int``, not ``PyObject *``. + +* Argument Clinic supports any signature for these functions, even though + the parsing function is required to always take ``args`` and ``kwargs`` + objects. + The #ifdef trick ---------------------------------------------- From b09433d13aca9a553a2f88acb8cc657194bd2a31 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Wed, 22 Jan 2014 05:49:11 -0800 Subject: [PATCH 129/538] Doc fixes for Argument Clinic. --- Doc/howto/clinic.rst | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 5ee6c3da1..20477db99 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -626,6 +626,15 @@ 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 sigantures 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 ``curses.window.addch`` @@ -1278,9 +1287,8 @@ a ``type`` argument to the object converter for ``METH_O``. tp_new and tp_init functions ---------------------------------------------- -You can convert ``tp_new`` and ``tp_init`` -functions. Just name them ``__new__`` or -``__init__`` as appropriate. Notes: +You can convert ``tp_new`` and ``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 @@ -1290,9 +1298,13 @@ functions. Just name them ``__new__`` or * ``__init__`` functions return ``int``, not ``PyObject *``. -* Argument Clinic supports any signature for these functions, even though - the parsing function is required to always take ``args`` and ``kwargs`` - objects. +* 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.) The #ifdef trick ---------------------------------------------- From adecaef652b9b14c98f027f8efefd3ccc0603bf3 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Sat, 25 Jan 2014 17:27:46 +0200 Subject: [PATCH 130/538] GitHub-Issue-Link: https://github.com/python/cpython/issues/64547 --- Doc/howto/clinic.rst | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 20477db99..bfae20e7c 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1,6 +1,6 @@ -====================== +********************** Argument Clinic How-To -====================== +********************** :author: Larry Hastings @@ -23,7 +23,6 @@ Argument Clinic How-To version of Argument Clinic that ships with CPython 3.5 *could* be totally incompatible and break all your code. -============================ The Goals Of Argument Clinic ============================ @@ -75,7 +74,6 @@ and it should be able to do many interesting and smart things with all the information you give it. -======================== Basic Concepts And Usage ======================== @@ -131,7 +129,6 @@ For the sake of clarity, here's the terminology we'll use with Argument Clinic: a block.) -============================== Converting Your First Function ============================== @@ -533,7 +530,6 @@ Let's dive in! Congratulations, you've ported your first function to work with Argument Clinic! -=============== Advanced Topics =============== From 96aca64d7d0f67ed27a55e4bb2e562b75ef607b0 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sun, 26 Jan 2014 00:42:02 -0800 Subject: [PATCH 131/538] Documentation fixes, including fixing "suspicious" problems. --- Doc/howto/clinic.rst | 114 ++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 50 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index bfae20e7c..8fcc2e82f 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -149,7 +149,7 @@ Let's dive in! 1. 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 my example I'm using ``pickle.Pickler.dump()``. + For my example I'm using ``_pickle.Pickler.dump()``. 2. If the call to the ``PyArg_Parse`` function uses any of the following format units:: @@ -214,7 +214,7 @@ Let's dive in! Sample:: /*[clinic input] - pickle.Pickler.dump + _pickle.Pickler.dump Write a pickled representation of obj to the open file. [clinic start generated code]*/ @@ -227,22 +227,27 @@ Let's dive in! 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. + Sample:: - /*[clinic input] - module pickle - class pickle.Pickler - [clinic start generated code]*/ + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ - /*[clinic input] - pickle.Pickler.dump + /*[clinic input] + _pickle.Pickler.dump - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - 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. @@ -286,13 +291,13 @@ Let's dive in! Sample:: - /*[clinic input] - module pickle - class pickle.Pickler - [clinic start generated code]*/ + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ - /*[clinic input] - pickle.Pickler.dump + /*[clinic input] + _pickle.Pickler.dump obj: 'O' @@ -309,7 +314,7 @@ Let's dive in! itself before the first keyword-only argument, indented the same as the parameter lines. - (``pickle.Pickler.dump`` has neither, so our sample is unchanged.) + (``_pickle.Pickler.dump`` has neither, so our sample is unchanged.) 10. If the existing C function calls :c:func:`PyArg_ParseTuple` @@ -327,12 +332,12 @@ Let's dive in! Sample:: /*[clinic input] - module pickle - class pickle.Pickler + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" [clinic start generated code]*/ /*[clinic input] - pickle.Pickler.dump + _pickle.Pickler.dump obj: 'O' / @@ -354,12 +359,12 @@ Let's dive in! Sample:: /*[clinic input] - module pickle - class pickle.Pickler + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" [clinic start generated code]*/ /*[clinic input] - pickle.Pickler.dump + _pickle.Pickler.dump obj: 'O' The object to be pickled. @@ -373,13 +378,13 @@ Let's dive in! the file in your text editor to see:: /*[clinic input] - module pickle - class pickle.Pickler + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" [clinic start generated code]*/ /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ /*[clinic input] - pickle.Pickler.dump + _pickle.Pickler.dump obj: 'O' The object to be pickled. @@ -388,12 +393,12 @@ Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ - PyDoc_STRVAR(pickle_Pickler_dump__doc__, + PyDoc_STRVAR(_pickle_Pickler_dump__doc__, "Write a pickled representation of obj to the open file.\n" "\n" ... static PyObject * - pickle_Pickler_dump_impl(PyObject *self, PyObject *obj) + _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ Obviously, if Argument Clinic didn't produce any output, it's because @@ -428,8 +433,8 @@ Let's dive in! 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__}, + #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. @@ -463,13 +468,13 @@ Let's dive in! Sample:: /*[clinic input] - module pickle - class pickle.Pickler + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" [clinic start generated code]*/ /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ /*[clinic input] - pickle.Pickler.dump + _pickle.Pickler.dump obj: 'O' The object to be pickled. @@ -478,12 +483,12 @@ Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ - PyDoc_STRVAR(pickle_Pickler_dump__doc__, + PyDoc_STRVAR(__pickle_Pickler_dump__doc__, "Write a pickled representation of obj to the open file.\n" "\n" ... static PyObject * - pickle_Pickler_dump_impl(PyObject *self, PyObject *obj) + _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ { /* Check whether the Pickler was initialized correctly (issue3664). @@ -515,8 +520,8 @@ Let's dive in! Sample:: static struct PyMethodDef Pickler_methods[] = { - _PICKLE_PICKLER_DUMP_METHODDEF - _PICKLE_PICKLER_CLEAR_MEMO_METHODDEF + __PICKLE_PICKLER_DUMP_METHODDEF + __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -1106,15 +1111,16 @@ Using a "self converter" ------------------------ Argument Clinic automatically adds a "self" parameter for you -using a default converter. However, you can override +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 ``self_converter`` or a subclass thereof. -What's the point? This lets you automatically cast ``self`` -from ``PyObject *`` to a custom type, just like ``object()`` -does with its ``type`` parameter. +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``, @@ -1502,6 +1508,8 @@ preset configurations, as follows: 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 all most of the output from Clinic, to be written into your file near the end. For Python files implementing modules @@ -1554,7 +1562,7 @@ The ``new`` subcommand works like this:: This creates a new destination with name ```` and type ````. -There are five destination types:: +There are five destination types: ``suppress`` Throws the text away. @@ -1575,12 +1583,18 @@ There are five destination types:: The template can use three strings internally that will be replaced by bits of the filename: - {filename} - The full filename. + {path} + The full path to the file, including directory and full filename. + {dirname} + The name of the directory the file is in. {basename} - Everything up to but not including the last '.'. - {extension} - The last '.' and everything after it. + 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}" From 1d0b93f7547b5bde8ac05f7228c0f167895c6970 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Fri, 31 Jan 2014 22:03:12 -0800 Subject: [PATCH 132/538] including correctly generating code for Clinic blocks inside C preprocessor conditional blocks. GitHub-Issue-Link: https://github.com/python/cpython/issues/64655 --- Doc/howto/clinic.rst | 172 +++++++++++++++++++++++++------------------ 1 file changed, 100 insertions(+), 72 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 8fcc2e82f..750ddbe07 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -561,8 +561,8 @@ in ``Lib/inspect.py``. to allow full expressions like ``CONSTANT - 1``.) -Renaming the C functions generated by Argument Clinic ------------------------------------------------------ +Renaming the 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 @@ -584,6 +584,25 @@ The base function would now be named ``pickler_dumper()``, and the impl function would now be named ``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! + Converting functions using PyArg_UnpackTuple -------------------------------------------- @@ -1308,74 +1327,6 @@ them ``__new__`` or ``__init__`` as appropriate. Notes: (If your function doesn't support keywords, the parsing function generated will throw an exception if it receives any.) -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 you'll have:: - - #ifdef HAVE_FUNCTIONNAME - {'functionname', ... }, - #endif /* HAVE_FUNCTIONNAME */ - -In this scenario, you should change the code to look like the following:: - - #ifdef HAVE_FUNCTIONNAME - /*[clinic input] - module.functionname - ... - [clinic start generated code]*/ - static module_functionname(...) - { - ... - } - #endif /* HAVE_FUNCTIONNAME */ - -Run Argument Clinic on the code in this state, then refresh the file in -your editor. Now you'll have the generated code, including the #define -for the ``PyMethodDef``, like so:: - - #ifdef HAVE_FUNCTIONNAME - /*[clinic input] - ... - [clinic start generated code]*/ - ... - #define MODULE_FUNCTIONNAME \ - {'functionname', ... }, - ... - /*[clinic end generated code: checksum=...]*/ - static module_functionname(...) - { - ... - } - #endif /* HAVE_FUNCTIONNAME */ - -Change the #endif at the bottom as follows:: - - #else - #define MODULE_FUNCTIONNAME - #endif /* HAVE_FUNCTIONNAME */ - -Now you can remove the #ifdefs around the ``PyMethodDef`` structure -at the end, and replace those three lines with ``MODULE_FUNCTIONNAME``. -If the function is available, the macro turns into the ``PyMethodDef`` -static value, including the trailing comma; if the function isn't -available, the macro turns into nothing. Perfect! - -(This is the preferred approach for optional functions; in the future, -Argument Clinic may generate the entire ``PyMethodDef`` structure.) - - Changing and redirecting Clinic's output ---------------------------------------- @@ -1491,8 +1442,9 @@ previous configuration. ``output preset`` sets Clinic's output to one of several built-in preset configurations, as follows: - ``original`` - Clinic's starting configuration. + ``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``. @@ -1640,6 +1592,82 @@ it in a Clinic block lets Clinic use its existing checksum functionality to ensu the file was not modified by hand before it gets overwritten. +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:: + + #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 ``PyMethodDef`` structure, +replacing them with the macro Argument Clinic generated:: + + 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 decativated 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:: + + 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 ``PyMethodDef`` structure where that macro is used. + + + Using Argument Clinic in Python files ------------------------------------- From bfcc6cf1c22227ec38082ccbe99465be7e1a291b Mon Sep 17 00:00:00 2001 From: Donald Stufft Date: Tue, 20 May 2014 12:58:38 -0400 Subject: [PATCH 133/538] Fix Issue #21528 - Fix documentation typos GitHub-Issue-Link: https://github.com/python/cpython/issues/65727 --- Doc/howto/clinic.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 750ddbe07..ca8e1cb87 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -886,7 +886,7 @@ Argument Clinic generates code that does it for you (in the parsing function). Advanced converters ------------------- -Remeber those format units you skipped for your first +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 @@ -1020,12 +1020,12 @@ any of the default arguments you can omit the parentheses. the ``"as"`` should come before the return converter.) There's one additional complication when using return converters: how do you -indicate an error has occured? Normally, a function returns a valid (non-``NULL``) +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 (``PyErr_Occurred()`` returns a true -value), then the generated code will propogate the error. Otherwise it will +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:: @@ -1573,7 +1573,7 @@ The fourth new directive is ``set``:: ``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 suport two format strings: +Both of these support two format strings: ``{block comment start}`` Turns into the string ``/*``, the start-comment text sequence for C files. From 93bb96d4a00907d5484896b5764f133a4231c7ae Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Thu, 7 May 2015 23:30:09 -0700 Subject: [PATCH 134/538] Issue #24000: Improved Argument Clinic's mapping of converters to legacy "format units". Updated the documentation to match. GitHub-Issue-Link: https://github.com/python/cpython/issues/68188 --- Doc/howto/clinic.rst | 70 +++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index ca8e1cb87..cb208d50b 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -758,6 +758,14 @@ All Argument Clinic converters accept the following arguments: 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, @@ -772,39 +780,27 @@ of these arguments, along with their meanings: Only supported for strings. Specifies the encoding to use when converting this string from a Python str (Unicode) value into a C ``char *`` value. - ``length`` - Only supported for strings. If true, requests that the length of the - string be passed in to the impl function, just after the string parameter, - in a parameter named ``_length``. - - ``nullable`` - Only supported for strings. If true, this parameter may also be set to - ``None``, in which case the C parameter will be set to ``NULL``. ``subclass_of`` Only supported for the ``object`` converter. Requires that the Python value be a subclass of a Python type, as expressed in C. - ``types`` - Only supported for the ``object`` (and ``self``) converter. Specifies + ``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 *"``. - ``types`` - A string containing a list 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.) - ``zeroes`` Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are - permitted inside the value. + 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. -Often these arguments are implemented internally by specific ``PyArg_ParseTuple`` +Usually these arguments are implemented by specific ``PyArg_ParseTuple`` *format units*, with specific behavior. For example, currently you cannot -call ``str`` and pass in ``zeroes=True`` without also specifying an ``encoding``; -although it's perfectly reasonable to think this would work, these semantics don't +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.) @@ -816,13 +812,13 @@ on the right is the text you'd replace it with. ``'B'`` ``unsigned_char(bitwise=True)`` ``'b'`` ``unsigned_char`` ``'c'`` ``char`` -``'C'`` ``int(types='str')`` +``'C'`` ``int(accept={str})`` ``'d'`` ``double`` ``'D'`` ``Py_complex`` -``'es#'`` ``str(encoding='name_of_encoding', length=True, zeroes=True)`` ``'es'`` ``str(encoding='name_of_encoding')`` -``'et#'`` ``str(encoding='name_of_encoding', types='bytes bytearray str', length=True)`` -``'et'`` ``str(encoding='name_of_encoding', types='bytes bytearray str')`` +``'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)`` @@ -832,27 +828,27 @@ on the right is the text you'd replace it with. ``'K'`` ``unsigned_PY_LONG_LONG(bitwise=True)`` ``'L'`` ``PY_LONG_LONG`` ``'n'`` ``Py_ssize_t`` +``'O'`` ``object`` ``'O!'`` ``object(subclass_of='&PySomething_Type')`` ``'O&'`` ``object(converter='name_of_c_function')`` -``'O'`` ``object`` ``'p'`` ``bool`` -``'s#'`` ``str(length=True)`` ``'S'`` ``PyBytesObject`` ``'s'`` ``str`` -``'s*'`` ``Py_buffer(types='str bytes bytearray buffer')`` -``'u#'`` ``Py_UNICODE(length=True)`` -``'u'`` ``Py_UNICODE`` +``'s#'`` ``str(zeroes=True)`` +``'s*'`` ``Py_buffer(accept={buffer, str})`` ``'U'`` ``unicode`` -``'w*'`` ``Py_buffer(types='bytearray rwbuffer')`` -``'y#'`` ``str(types='bytes', length=True)`` +``'u'`` ``Py_UNICODE`` +``'u#'`` ``Py_UNICODE(zeroes=True)`` +``'w*'`` ``Py_buffer(accept={rwbuffer})`` ``'Y'`` ``PyByteArrayObject`` -``'y'`` ``str(types='bytes')`` +``'y'`` ``str(accept={bytes})`` +``'y#'`` ``str(accept={robuffer}, zeroes=True)`` ``'y*'`` ``Py_buffer`` -``'Z#'`` ``Py_UNICODE(nullable=True, length=True)`` -``'z#'`` ``str(nullable=True, length=True)`` -``'Z'`` ``Py_UNICODE(nullable=True)`` -``'z'`` ``str(nullable=True)`` -``'z*'`` ``Py_buffer(types='str bytes bytearray buffer', nullable=True)`` +``'Z'`` ``Py_UNICODE(accept={str, NoneType})`` +``'Z#'`` ``Py_UNICODE(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 From 3a037bb407301eec8613d30a4cdc6b9b4236eab7 Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Sat, 16 May 2015 14:12:15 +0300 Subject: [PATCH 135/538] Argument Clinic: added missing bit of info in howto --- Doc/howto/clinic.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index cb208d50b..4ff475fb3 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -826,6 +826,7 @@ on the right is the text you'd replace it with. ``'I'`` ``unsigned_int(bitwise=True)`` ``'k'`` ``unsigned_long(bitwise=True)`` ``'K'`` ``unsigned_PY_LONG_LONG(bitwise=True)`` +``'l'`` ``long`` ``'L'`` ``PY_LONG_LONG`` ``'n'`` ``Py_ssize_t`` ``'O'`` ``object`` From 68c76ed408b928c9a1252a89416124947e7e2417 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Tue, 19 May 2015 01:36:55 +0300 Subject: [PATCH 136/538] =?UTF-8?q?Issue=20#24232:=20Fix=20typos.=20Patch?= =?UTF-8?q?=20by=20Ville=20Skytt=C3=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub-Issue-Link: https://github.com/python/cpython/issues/68420 --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 4ff475fb3..7524c4ad9 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1495,7 +1495,7 @@ preset configurations, as follows: the ``buffer`` preset. Suppresses the ``impl_prototype``, write the ``docstring_definition`` - and ``parser_defintion`` to ``buffer``, write everything else to ``block``. + and ``parser_definition`` to ``buffer``, write everything else to ``block``. The third new directive is ``destination``:: From c4a0b9cde850e3f10f3b1e9e8c50da6e0a759364 Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Fri, 20 Nov 2015 08:13:35 +0000 Subject: [PATCH 137/538] Issue #25626: Change zlib to accept Py_ssize_t and cap to UINT_MAX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub-Issue-Link: https://github.com/python/cpython/issues/69812 The underlying zlib library stores sizes in “unsigned int”. The corresponding Python parameters are all sizes of buffers filled in by zlib, so it is okay to reduce higher values to the UINT_MAX internal cap. OverflowError is still raised for sizes that do not fit in Py_ssize_t. Sizes are now limited to Py_ssize_t rather than unsigned long, because Python byte strings cannot be larger than Py_ssize_t. Previously this could result in a SystemError on 32-bit platforms. This resolves a regression in the gzip module when reading more than UINT_MAX or LONG_MAX bytes in one call, introduced by revision 62723172412c. --- Doc/howto/clinic.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 7524c4ad9..b04edea18 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1249,18 +1249,18 @@ Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c`` /*[python input] - class uint_converter(CConverter): + class capped_uint_converter(CConverter): type = 'unsigned int' - converter = 'uint_converter' + converter = 'capped_uint_converter' [python start generated code]*/ - /*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ -This block adds a converter to Argument Clinic named ``uint``. Parameters -declared as ``uint`` will be declared as type ``unsigned int``, and will -be parsed by the ``'O&'`` format unit, which will call the ``uint_converter`` -converter function. -``uint`` variables automatically support default values. +This block adds a converter to Argument Clinic named ``capped_uint``. Parameters +declared as ``capped_uint`` will be declared as type ``unsigned int``, and will +be parsed by the ``'O&'`` format unit, which will call the +``capped_uint_converter`` converter function. ``capped_uint`` variables +automatically support default values. More sophisticated custom converters can insert custom C code to handle initialization and cleanup. From b57ec578f214a76dd8d5fb454381d5acc062079a Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Sat, 23 Jul 2016 03:02:07 +0000 Subject: [PATCH 138/538] =?UTF-8?q?Issue=20#27130:=20Fix=20handling=20of?= =?UTF-8?q?=20buffers=20exceeding=20UINT=5FMAX=20in=20=E2=80=9Czlib?= =?UTF-8?q?=E2=80=9D=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch by Xiang Zhang. GitHub-Issue-Link: https://github.com/python/cpython/issues/71317 --- Doc/howto/clinic.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index b04edea18..7f275a465 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1249,17 +1249,17 @@ Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c`` /*[python input] - class capped_uint_converter(CConverter): - type = 'unsigned int' - converter = 'capped_uint_converter' + 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 to Argument Clinic named ``capped_uint``. Parameters -declared as ``capped_uint`` will be declared as type ``unsigned int``, and will +This block adds a converter to Argument Clinic named ``ssize_t``. Parameters +declared as ``ssize_t`` will be declared as type ``Py_ssize_t``, and will be parsed by the ``'O&'`` format unit, which will call the -``capped_uint_converter`` converter function. ``capped_uint`` variables +``ssize_t_converter`` converter function. ``ssize_t`` variables automatically support default values. More sophisticated custom converters can insert custom C code to From 954571129db0aa2e8d54f33741a67496073ee13c Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Thu, 28 Jul 2016 01:11:04 +0000 Subject: [PATCH 139/538] Issue #27626: Spelling fixes in docs, comments and internal names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on patch by Ville Skyttä. GitHub-Issue-Link: https://github.com/python/cpython/issues/71813 --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 7f275a465..82eae01e7 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1583,7 +1583,7 @@ called ``preserve``:: preserve -This tells Clinic that the current contents of the output should be kept, unmodifed. +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. From f6911260bf14e891bf2db12709373a860a0e67a3 Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Tue, 26 Jul 2016 11:18:21 +0200 Subject: [PATCH 140/538] Issue #26462: Doc: reduce literal_block warnings, fix syntax highlighting. Patch by Julien Palard. GitHub-Issue-Link: https://github.com/python/cpython/issues/70649 --- Doc/howto/clinic.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 82eae01e7..5a69ca8ab 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -152,7 +152,9 @@ Let's dive in! For my example I'm using ``_pickle.Pickler.dump()``. 2. If the call to the ``PyArg_Parse`` function uses any of the - following format units:: + following format units: + + .. code-block:: none O& O! From 78eb4516b365a47078e1f720e18bb575c8aabd8a Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Fri, 12 Aug 2016 12:02:03 +0000 Subject: [PATCH 141/538] Issue #27745: Fix some typos in Argument Clinic howto, by Lele Gaifax GitHub-Issue-Link: https://github.com/python/cpython/issues/71932 --- Doc/howto/clinic.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 5a69ca8ab..caa497521 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -653,7 +653,7 @@ can *only* be used with positional-only parameters. 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 sigantures in Python, because Python just + cannot have accurate signatures in Python, because Python just doesn't understand the concept. Please avoid using optional groups wherever possible. @@ -1337,7 +1337,7 @@ 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 befire it is defined. +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 @@ -1381,7 +1381,7 @@ Let's start with defining some terminology: ``buffer`` A text buffer where you can save text for later. Text sent - here is appended to the end of any exsiting text. It's an + 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. @@ -1653,7 +1653,7 @@ 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 decativated by the ``#ifdef``. (That's the whole point!) +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:: From 945022bb2052ae3b7d59b873ea55ebc0882506d2 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 8 Sep 2016 09:29:11 -0700 Subject: [PATCH 142/538] clinic: PY_LONG_LONG -> long long --- Doc/howto/clinic.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index caa497521..f43588408 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -827,9 +827,9 @@ on the right is the text you'd replace it with. ``'i'`` ``int`` ``'I'`` ``unsigned_int(bitwise=True)`` ``'k'`` ``unsigned_long(bitwise=True)`` -``'K'`` ``unsigned_PY_LONG_LONG(bitwise=True)`` +``'K'`` ``unsigned_long_long(bitwise=True)`` ``'l'`` ``long`` -``'L'`` ``PY_LONG_LONG`` +``'L'`` ``long long`` ``'n'`` ``Py_ssize_t`` ``'O'`` ``object`` ``'O!'`` ``object(subclass_of='&PySomething_Type')`` From f1bb7b6abd01073d8704932b6d0cb2ba8d8b9786 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sun, 20 Nov 2016 11:30:36 -0800 Subject: [PATCH 143/538] Issue 28753: Argument Clinic howto docfix, courtesy Julien Palard. GitHub-Issue-Link: https://github.com/python/cpython/issues/72939 --- Doc/howto/clinic.rst | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index f43588408..0316901c9 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -375,15 +375,12 @@ Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ -12. Save and close the file, then run ``Tools/clinic/clinic.py`` on it. - With luck everything worked and your block now has output! Reopen - the file in your text editor to see:: +12. Save and close the file, then run ``Tools/clinic/clinic.py`` on + it. With luck everything worked--your block now has output, and + a ``.c.h`` file has been generated! Reopen the file in your + text editor to see: - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + .. code-block:: c /*[clinic input] _pickle.Pickler.dump @@ -395,18 +392,22 @@ Let's dive in! 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]*/ + _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 ``.c.h`` + file. You'll need to include that in your original ``.c`` file, + typically right after the clinic module block: + + .. code-block:: c + + #include "clinic/_pickle.c.h" + 13. Double-check that the argument-parsing code Argument Clinic generated looks basically the same as the existing code. From 5b0b4269112050696c654b80e15eb108e89dd70b Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Mon, 21 Nov 2016 00:15:20 +0000 Subject: [PATCH 144/538] Change double hyphens (en dashes) to em (longer) dashes --- Doc/howto/clinic.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 0316901c9..956120f3d 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -30,7 +30,7 @@ Argument Clinic's primary goal is to take over responsibility for all argument parsing code inside CPython. This means that, when you convert a function to work with Argument Clinic, that function should no longer -do any of its own argument parsing--the code generated by +do any of its own argument parsing—the code generated by Argument Clinic should be a "black box" to you, where CPython calls in at the top, and your code gets called at the bottom, with ``PyObject *args`` (and maybe ``PyObject *kwargs``) @@ -43,12 +43,12 @@ redundant information in a surprising number of places. When you use Argument Clinic, you don't have to repeat yourself. Obviously, no one would want to use Argument Clinic unless -it's solving their problem--and without creating new problems of +it's solving their problem—and without creating new problems of its own. So it's paramount that Argument Clinic generate correct code. It'd be nice if the code was faster, too, but at the very least it should not introduce a major speed regression. (Eventually Argument -Clinic *should* make a major speedup possible--we could +Clinic *should* make a major speedup possible—we could rewrite its code generator to produce tailor-made argument parsing code, rather than calling the general-purpose CPython argument parsing library. That would make for the fastest @@ -113,7 +113,7 @@ line. However, if the input hasn't changed, the output won't change either. You should never modify the output portion of an Argument Clinic block. Instead, change the input until it produces the output you want. (That's the purpose of the -checksum--to detect if someone changed the output, as these edits would be lost +checksum—to detect if someone changed the output, as these edits would be lost the next time Argument Clinic writes out fresh output.) For the sake of clarity, here's the terminology we'll use with Argument Clinic: @@ -166,7 +166,7 @@ Let's dive in! or if it has multiple calls to :c:func:`PyArg_ParseTuple`, you should choose a different function. Argument Clinic *does* support all of these scenarios. But these are advanced - topics--let's do something simpler for your first function. + topics—let's do something simpler for your first function. Also, if the function has multiple calls to :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different @@ -188,7 +188,7 @@ Let's dive in! 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 ``help()`` on your builtin in the future, + anymore—when you use ``help()`` on your builtin in the future, the first line will be built automatically based on the function's signature.) @@ -209,7 +209,7 @@ Let's dive in! 6. 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, + 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. @@ -275,7 +275,7 @@ Let's dive in! 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 + 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. @@ -425,7 +425,7 @@ Let's dive in! (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.) + usage help, this change is harmless—don't worry about it.) Third, for parameters whose format units require two arguments (like a length variable, or an encoding string, or a pointer @@ -638,7 +638,7 @@ an optional argument on the *left* side of its required argument! Another example is ``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 +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 @@ -889,7 +889,7 @@ 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 +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 @@ -1003,7 +1003,7 @@ Using a return converter By default the impl function Argument Clinic generates for you returns ``PyObject *``. But your C function often computes some C type, then converts it into the ``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 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 @@ -1185,7 +1185,7 @@ Writing a custom converter As we hinted at in the previous section... you can write your own converters! A converter is simply a Python class that inherits from ``CConverter``. The main purpose of a custom converter is if you have a parameter using -the ``O&`` format unit--parsing this parameter means calling +the ``O&`` format unit—parsing this parameter means calling a :c:func:`PyArg_ParseTuple` "converter function". Your converter class should be named ``*something*_converter``. @@ -1227,7 +1227,7 @@ to specify in your subclass. Here's the current list: The default value used to initialize the C variable when there is no default, but not specifying a default may result in an "uninitialized variable" warning. This can - easily happen when using option groups--although + easily happen when using option groups—although properly-written code will never actually use this value, the variable does get passed in to the impl, and the C compiler will complain about the "use" of the @@ -1403,7 +1403,7 @@ Let's start with defining some terminology: all of processing, even from Clinic blocks *after* the ``suppress`` - The text is suppressed--thrown away. + The text is suppressed—thrown away. Clinic defines five new directives that let you reconfigure its output. From 0597580357656b5e49a2e94260f804a180e84d28 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 21 Nov 2016 13:40:45 +0200 Subject: [PATCH 145/538] Change an en-dash to an em-dash. --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 956120f3d..e586aa62a 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -376,7 +376,7 @@ Let's dive in! [clinic start generated code]*/ 12. Save and close the file, then run ``Tools/clinic/clinic.py`` on - it. With luck everything worked--your block now has output, and + it. With luck everything worked---your block now has output, and a ``.c.h`` file has been generated! Reopen the file in your text editor to see: From 71ec6589da75e9b0aa3065047328741e09e30a9c Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Sat, 10 Dec 2016 04:10:45 +0000 Subject: [PATCH 146/538] Issue #28755: Improve syntax highlighting in Arg Clinic howto GitHub-Issue-Link: https://github.com/python/cpython/issues/72941 --- Doc/howto/clinic.rst | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index e586aa62a..eaab20ad9 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1,3 +1,5 @@ +.. highlightlang:: c + ********************** Argument Clinic How-To ********************** @@ -78,17 +80,23 @@ Basic Concepts And Usage ======================== Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. -If you run that script, specifying a C file as an argument:: +If you run that script, specifying a C file as an argument: + +.. code-block:: shell-session - % python3 Tools/clinic/clinic.py foo.c + $ python3 Tools/clinic/clinic.py foo.c Argument Clinic will scan over the file looking for lines that -look exactly like this:: +look exactly like this: + +.. code-block:: none /*[clinic input] When it finds one, it reads everything up to a line that looks -exactly like this:: +exactly like this: + +.. code-block:: none [clinic start generated code]*/ @@ -99,7 +107,9 @@ lines, are collectively called an Argument Clinic "block". When Argument Clinic parses one of these blocks, it generates output. This output is rewritten into the C file immediately after the block, followed by a comment containing a checksum. -The Argument Clinic block now looks like this:: +The Argument Clinic block now looks like this: + +.. code-block:: none /*[clinic input] ... clinic input goes here ... @@ -378,9 +388,7 @@ Let's dive in! 12. Save and close the file, then run ``Tools/clinic/clinic.py`` on it. With luck everything worked---your block now has output, and a ``.c.h`` file has been generated! Reopen the file in your - text editor to see: - - .. code-block:: c + text editor to see:: /*[clinic input] _pickle.Pickler.dump @@ -402,9 +410,7 @@ Let's dive in! For readability, most of the glue code has been generated to a ``.c.h`` file. You'll need to include that in your original ``.c`` file, - typically right after the clinic module block: - - .. code-block:: c + typically right after the clinic module block:: #include "clinic/_pickle.c.h" @@ -1028,7 +1034,9 @@ that value, and an error has been set (``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:: +Currently Argument Clinic supports only a few return converters: + +.. code-block:: none bool int @@ -1607,7 +1615,9 @@ code probably looks like this:: #endif /* HAVE_FUNCTIONNAME */ And then in the ``PyMethodDef`` structure at the bottom the existing code -will have:: +will have: + +.. code-block:: none #ifdef HAVE_FUNCTIONNAME {'functionname', ... }, @@ -1657,7 +1667,9 @@ extra code when using the "block" output preset? It can't go in the output bloc 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:: +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. @@ -1677,7 +1689,9 @@ 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:: +blocks embedded in Python files look slightly different. They look like this: + +.. code-block:: python3 #/*[python input] #print("def foo(): pass") From a878bd3f2f51ba2d94cb02981e43bd6c65a6d49c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 30 Mar 2017 10:01:03 +0300 Subject: [PATCH 147/538] bpo-29918: Add missed "const" modifiers in C API documentation. (#846) GitHub-Issue-Link: https://github.com/python/cpython/issues/74104 --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index eaab20ad9..b5c14d3af 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1050,7 +1050,7 @@ Currently Argument Clinic supports only a few return converters: DecodeFSDefault None of these take parameters. For the first three, return -1 to indicate -error. For ``DecodeFSDefault``, the return type is ``char *``; return a NULL +error. For ``DecodeFSDefault``, the return type is ``const char *``; return a NULL pointer to indicate an error. (There's also an experimental ``NoneType`` converter, which lets you From 355e339f4c5f4c488dc386056ac9f8398070c4e6 Mon Sep 17 00:00:00 2001 From: gfyoung Date: Tue, 6 Jun 2017 15:23:52 -0400 Subject: [PATCH 148/538] bpo-29596: Improve clinic howto documentation (GH-1710) Clarify that `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. GitHub-Issue-Link: https://github.com/python/cpython/issues/73782 --- Doc/howto/clinic.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index b5c14d3af..d3c7d6689 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1407,8 +1407,8 @@ Let's start with defining some terminology: ``two-pass`` A buffer like ``buffer``. However, a two-pass buffer can only - be written once, and it prints out all text sent to it during - all of processing, even from Clinic blocks *after* the + 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. @@ -1471,7 +1471,7 @@ preset configurations, as follows: The default filename is ``"{dirname}/clinic/{basename}.h"``. ``buffer`` - Save up all most of the output from Clinic, to be written into + 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 From f8890e508576751d1b65c409d14bb8870f439a41 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 8 Apr 2018 19:18:04 +0300 Subject: [PATCH 149/538] Improve highlighting of some code blocks. (python/cpython#6401) --- Doc/howto/clinic.rst | 68 +++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index d3c7d6689..788a0eee2 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -267,12 +267,16 @@ Let's dive in! 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:: + 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:: + converter: + + .. code-block:: none name_of_parameter: converter = default_value @@ -925,13 +929,17 @@ Parameter default values ------------------------ Default values for parameters can be any of a number of values. -At their simplest, they can be string, int, or float literals:: +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:: +They can also use any of Python's built-in constants: + +.. code-block:: none yep: bool = True nope: bool = False @@ -959,7 +967,9 @@ 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:: +Consider the following example: + +.. code-block:: none foo: Py_ssize_t = sys.maxsize - 1 @@ -970,7 +980,9 @@ 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 "``max_widgets``", you may simply use it:: +attribute called "``max_widgets``", you may simply use it: + +.. code-block:: none foo: Py_ssize_t = max_widgets @@ -982,7 +994,9 @@ 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:: +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 @@ -1359,7 +1373,9 @@ Let's start with defining some terminology: A field, in this context, is a subsection of Clinic's output. For example, the ``#define`` for the ``PyMethodDef`` structure is a field, called ``methoddef_define``. Clinic has seven - different fields it can output per function definition:: + different fields it can output per function definition: + + .. code-block:: none docstring_prototype docstring_definition @@ -1416,7 +1432,9 @@ Let's start with defining some terminology: Clinic defines five new directives that let you reconfigure its output. -The first new directive is ``dump``:: +The first new directive is ``dump``: + +.. code-block:: none dump @@ -1425,7 +1443,9 @@ 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:: +is like this: + +.. code-block:: none output @@ -1433,7 +1453,9 @@ 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:: +``output`` has a number of other functions: + +.. code-block:: none output push output pop @@ -1508,7 +1530,9 @@ preset configurations, as follows: Suppresses the ``impl_prototype``, write the ``docstring_definition`` and ``parser_definition`` to ``buffer``, write everything else to ``block``. -The third new directive is ``destination``:: +The third new directive is ``destination``: + +.. code-block:: none destination [...] @@ -1516,7 +1540,9 @@ This performs an operation on the destination named ``name``. There are two defined subcommands: ``new`` and ``clear``. -The ``new`` subcommand works like this:: +The ``new`` subcommand works like this: + +.. code-block:: none destination new @@ -1564,7 +1590,9 @@ There are five destination types: A two-pass buffer, like the "two-pass" builtin destination above. -The ``clear`` subcommand works like this:: +The ``clear`` subcommand works like this: + +.. code-block:: none destination clear @@ -1572,7 +1600,9 @@ 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``:: +The fourth new directive is ``set``: + +.. code-block:: none set line_prefix "string" set line_suffix "string" @@ -1590,7 +1620,9 @@ Both of these support two format strings: 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``:: +called ``preserve``: + +.. code-block:: none preserve @@ -1638,7 +1670,9 @@ like so:: #endif /* HAVE_FUNCTIONNAME */ Then, remove those three lines from the ``PyMethodDef`` structure, -replacing them with the macro Argument Clinic generated:: +replacing them with the macro Argument Clinic generated: + +.. code-block:: none MODULE_FUNCTIONNAME_METHODDEF From 26b8c6f18683710c982865fd33551ade9cc17553 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Sun, 20 May 2018 07:38:01 -0700 Subject: [PATCH 150/538] Docs: be less specific about python versions (python/cpython#6985) CPython 3.5 is old now, and we don't bump this version often, so lets avoid using specific versions. --- Doc/howto/clinic.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 788a0eee2..695fbb1be 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -22,8 +22,8 @@ Argument Clinic How-To compatibility for future versions. In other words: if you maintain an external C extension for CPython, you're welcome to experiment with Argument Clinic in your own code. But the - version of Argument Clinic that ships with CPython 3.5 *could* - be totally incompatible and break all your code. + version of Argument Clinic that ships with the next version + of CPython *could* be totally incompatible and break all your code. The Goals Of Argument Clinic ============================ From 2630d188f473ecfd2bb51d27efffd4652aad517b Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 26 Jul 2018 13:22:16 +0300 Subject: [PATCH 151/538] bpo-20260: Implement non-bitwise unsigned int converters for Argument Clinic. (python/cpython#8434) GitHub-Issue-Link: https://github.com/python/cpython/issues/64459 --- Doc/howto/clinic.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 695fbb1be..c75c31c98 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -878,6 +878,12 @@ converter:: 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. From 3cf43cbc98c0eff20a70b6f85e63681f3c32441c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Wirtel?= Date: Sat, 27 Oct 2018 00:58:26 +0200 Subject: [PATCH 152/538] bpo-35042: Use the :pep: role where a PEP is specified (python/cpython#10036) GitHub-Issue-Link: https://github.com/python/cpython/issues/79223 --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index c75c31c98..5b2457a16 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -765,7 +765,7 @@ All Argument Clinic converters accept the following arguments: ``annotation`` The annotation value for this parameter. Not currently supported, - because PEP 8 mandates that the Python library may not use + because :pep:`8` mandates that the Python library may not use annotations. In addition, some converters accept additional arguments. Here is a list From 244f0be41356bf78500f7a31f2bf51c2775c31b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Wirtel?= Date: Fri, 17 May 2019 11:55:34 +0200 Subject: [PATCH 153/538] Doc: Replace the deprecated highlightlang directive by highlight. (python/cpython#13377) highlightlang is deprecated since April 2018 in Sphinx. See https://github.com/sphinx-doc/sphinx/pull/4845 --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 5b2457a16..cfd9f2e40 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1,4 +1,4 @@ -.. highlightlang:: c +.. highlight:: c ********************** Argument Clinic How-To From a0695540633c8781fb1ceda388173b40ec6e8291 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 30 Oct 2019 21:37:16 +0200 Subject: [PATCH 154/538] bpo-38600: NULL -> ``NULL``. (python/cpython#17001) Also fix some other formatting. GitHub-Issue-Link: https://github.com/python/cpython/issues/82781 --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index cfd9f2e40..50041829b 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1070,7 +1070,7 @@ Currently Argument Clinic supports only a few return converters: DecodeFSDefault None of these take parameters. For the first three, return -1 to indicate -error. For ``DecodeFSDefault``, the return type is ``const char *``; return a NULL +error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL`` pointer to indicate an error. (There's also an experimental ``NoneType`` converter, which lets you From f314e512e2ff5a6ffc08cb59bcb1fc968e020c4d Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Wed, 20 Jan 2021 12:19:57 +0100 Subject: [PATCH 155/538] bpo-42048: Clinic Howto: Document AC's defining_class converter (python/cpython#23978) GitHub-Issue-Link: https://github.com/python/cpython/issues/86214 --- Doc/howto/clinic.rst | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 50041829b..3a3653a5e 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1206,6 +1206,68 @@ type for ``self``, it's best to create your own converter, subclassing [clinic start generated code]*/ +Using a "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 ``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 +``__text_signature__``. + +The ``defining_class`` converter is not compatible with ``__init__`` and ``__new__`` +methods, which cannot use the ``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 ``_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 +``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`. + Writing a custom converter -------------------------- From 219b7e9352261b8bdbb57ae5d721180b861e2639 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 20 Oct 2021 21:48:55 +0300 Subject: [PATCH 156/538] bpo-45320: Remove long-deprecated inspect methods (python/cpython#28618) GitHub-Issue-Link: https://github.com/python/cpython/issues/89483 --- Doc/howto/clinic.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 3a3653a5e..a3c433029 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -567,9 +567,6 @@ expression. Currently the following are explicitly supported: * Simple symbolic constants like ``sys.maxsize``, which must start with the name of the module -In case you're curious, this is implemented in ``from_builtin()`` -in ``Lib/inspect.py``. - (In the future, this may need to get even more elaborate, to allow full expressions like ``CONSTANT - 1``.) From 67be7bd4de15934db6b02cdcbc2743cc8ee7a910 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 11 Feb 2022 17:22:11 +0100 Subject: [PATCH 157/538] bpo-46613: Add PyType_GetModuleByDef to the public API (python/cpython#31081) * Make PyType_GetModuleByDef public (remove underscore) Co-authored-by: Victor Stinner GitHub-Issue-Link: https://github.com/python/cpython/issues/90771 --- Doc/howto/clinic.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index a3c433029..04b1a2cac 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1249,15 +1249,15 @@ The ``defining_class`` converter is not compatible with ``__init__`` and ``__new methods, which cannot use the ``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 ``_PyType_GetModuleByDef`` to -look up the module and then :c:func:`PyModule_GetState` to fetch the module +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 ``Modules/_threadmodule.c``:: static int local_setattro(localobject *self, PyObject *name, PyObject *v) { - PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module); + PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &thread_module); thread_module_state *state = get_thread_state(module); ... } From 09f1afa48be96c3401d813e5417666d16f89a5c7 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Thu, 12 May 2022 14:48:38 +0900 Subject: [PATCH 158/538] python/cpython#92536: PEP 623: Remove wstr and legacy APIs from Unicode (python/cpython#92537) --- Doc/howto/clinic.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 04b1a2cac..989527b65 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -848,15 +848,15 @@ on the right is the text you'd replace it with. ``'s#'`` ``str(zeroes=True)`` ``'s*'`` ``Py_buffer(accept={buffer, str})`` ``'U'`` ``unicode`` -``'u'`` ``Py_UNICODE`` -``'u#'`` ``Py_UNICODE(zeroes=True)`` +``'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'`` ``Py_UNICODE(accept={str, NoneType})`` -``'Z#'`` ``Py_UNICODE(accept={str, NoneType}, zeroes=True)`` +``'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})`` From d11b3b7b36f53354a04cd137d9b73835235c8a3f Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Fri, 13 May 2022 14:10:16 +0200 Subject: [PATCH 159/538] Document Py_ssize_t. (python/cpython#92512) It fixes 252 errors from a Sphinx nitpicky run (sphinx-build -n). But there's 8182 errors left. Co-authored-by: Ezio Melotti --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 989527b65..7959bc3a5 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1347,7 +1347,7 @@ Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c`` /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ This block adds a converter to Argument Clinic named ``ssize_t``. Parameters -declared as ``ssize_t`` will be declared as type ``Py_ssize_t``, and will +declared as ``ssize_t`` will be declared as type :c:type:`Py_ssize_t`, and will be parsed by the ``'O&'`` format unit, which will call the ``ssize_t_converter`` converter function. ``ssize_t`` variables automatically support default values. From 4bb10efb843ce0c0b5c949432b2c56b6d3528e64 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 5 Jul 2022 05:16:10 -0400 Subject: [PATCH 160/538] Docs: remove redundant "adverb-adjective" hyphens from compound modifiers (python/cpython#94551) Discussion: https://discuss.python.org/t/17021 --- Doc/howto/clinic.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 7959bc3a5..2d368966b 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -541,7 +541,7 @@ Let's dive in! 16. 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. + and there should be no externally visible change to Python's behavior. Well, except for one difference: ``inspect.signature()`` run on your function should now provide a valid signature! @@ -1117,7 +1117,7 @@ Here's the syntax for cloning a function:: ``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 +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 @@ -1315,7 +1315,7 @@ to specify in your subclass. Here's the current list: there is no default, but not specifying a default may result in an "uninitialized variable" warning. This can easily happen when using option groups—although - properly-written code will never actually use this value, + properly written code will never actually use this value, the variable does get passed in to the impl, and the C compiler will complain about the "use" of the uninitialized value. This value should always be a From 2f81c6b32407988c977a227afa5b5f961c38b8b1 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Mon, 1 Aug 2022 16:07:35 +0300 Subject: [PATCH 161/538] python/cpython#95007: Remove the NoneType return converter from Argument Clinic Doc (python/cpython#95529) The converter was removed in python/cpython@74b5e4ce80858ac5c7d03411cb8cce7e6865f181 --- Doc/howto/clinic.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 2d368966b..d634c4b47 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1070,11 +1070,6 @@ None of these take parameters. For the first three, return -1 to indicate error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL`` pointer to indicate an error. -(There's also an experimental ``NoneType`` converter, which lets you -return ``Py_None`` on success or ``NULL`` on failure, without having -to increment the reference count on ``Py_None``. I'm not sure it adds -enough clarity to be worth using.) - 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. From e630cce8211c75d11ada611328ea43d277c16114 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Fri, 7 Oct 2022 21:54:45 +0300 Subject: [PATCH 162/538] python/cpython#97956: Mention `generate_global_objects.py` in `AC How-To` (python/cpython#97957) --- Doc/howto/clinic.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index d634c4b47..b8afc7e6d 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -539,7 +539,15 @@ Let's dive in! }; -16. Compile, then run the relevant portions of the regression-test suite. +16. 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 ``Tools/scripts/generate_global_objects.py`` + to regenerate the list of precompiled identifiers at this point. + + +17. 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. From d49557b908ebc1d53b43dc080813336ff5000278 Mon Sep 17 00:00:00 2001 From: Stanley <46876382+slateny@users.noreply.github.com> Date: Tue, 25 Oct 2022 20:26:28 -0700 Subject: [PATCH 163/538] docs: Change links to label refs (python/cpython#98454) Co-authored-by: C.A.M. Gerlach --- Doc/howto/clinic.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index b8afc7e6d..a97f1d23f 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1,5 +1,7 @@ .. highlight:: c +.. _howto-clinic: + ********************** Argument Clinic How-To ********************** From 980ec861703c422b886d5fd07f4fb621ab8651ed Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Wed, 11 Jan 2023 11:05:41 +0100 Subject: [PATCH 164/538] python/cpython#98763: Prefer "python" over "python3" for command line examples in docs. (python/cpython#98761) --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index a97f1d23f..8a10fe327 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -86,7 +86,7 @@ If you run that script, specifying a C file as an argument: .. code-block:: shell-session - $ python3 Tools/clinic/clinic.py foo.c + $ python Tools/clinic/clinic.py foo.c Argument Clinic will scan over the file looking for lines that look exactly like this: From 769053fae0becbc5c77a22adb25c5f6ee7ccfd42 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 5 May 2023 13:32:00 +0200 Subject: [PATCH 165/538] python/cpython#64658: Expand Argument Clinic return converter docs (python/cpython#104175) --- Doc/howto/clinic.rst | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 8a10fe327..6ebc2d9b0 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1033,19 +1033,36 @@ you're not permitted to use: Using a return converter ------------------------ -By default the impl function Argument Clinic generates for you returns ``PyObject *``. -But your C function often computes some C type, then converts it into the ``PyObject *`` +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 ``PyObject *``. +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. Return converters behave much the same as parameter converters; +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. @@ -1066,19 +1083,17 @@ Currently Argument Clinic supports only a few return converters: .. code-block:: none bool + double + float int - unsigned int long - unsigned int - size_t Py_ssize_t - float - double - DecodeFSDefault + size_t + unsigned int + unsigned long -None of these take parameters. For the first three, return -1 to indicate -error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL`` -pointer to indicate an error. +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), From 9e49475fe7d48d28ba5f5d7b1144b9913409109c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 12 May 2023 10:34:00 +0200 Subject: [PATCH 166/538] python/cpython#104389: Add 'unused' keyword to Argument Clinic C converters (python/cpython#104390) Use the unused keyword param in the converter to explicitly mark an argument as unused: /*[clinic input] SomeBaseClass.stubmethod flag: bool(unused=True) [clinic start generated code]*/ --- Doc/howto/clinic.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 6ebc2d9b0..4620b4617 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -775,6 +775,9 @@ All Argument Clinic converters accept the following arguments: 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: From ce62dfbd46ff39d9d4e70eacaf9732233729d9ee Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 16 Jul 2023 00:42:58 +0200 Subject: [PATCH 167/538] Docs: Normalize Argument Clinic How-To section capitalization (python/cpython#106788) --- Doc/howto/clinic.rst | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 4620b4617..0f99cb649 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -27,7 +27,8 @@ Argument Clinic How-To version of Argument Clinic that ships with the next version of CPython *could* be totally incompatible and break all your code. -The Goals Of Argument Clinic + +The goals of Argument Clinic ============================ Argument Clinic's primary goal @@ -78,7 +79,7 @@ and it should be able to do many interesting and smart things with all the information you give it. -Basic Concepts And Usage +Basic concepts and usage ======================== Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. @@ -141,7 +142,7 @@ For the sake of clarity, here's the terminology we'll use with Argument Clinic: a block.) -Converting Your First Function +Converting your first function ============================== The best way to get a sense of how Argument Clinic works is to @@ -558,7 +559,8 @@ Let's dive in! Congratulations, you've ported your first function to work with Argument Clinic! -Advanced Topics + +Advanced topics =============== Now that you've had some experience working with Argument Clinic, it's time @@ -636,7 +638,8 @@ after the last argument). Currently the generated code will use :c:func:`PyArg_ParseTuple`, but this will change soon. -Optional Groups + +Optional groups --------------- Some legacy functions have a tricky approach to parsing their arguments: @@ -899,6 +902,7 @@ 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. + Py_buffer --------- @@ -908,7 +912,6 @@ 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). - Advanced converters ------------------- @@ -975,6 +978,7 @@ 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``. + Expressions specified as default values --------------------------------------- @@ -1032,7 +1036,6 @@ you're not permitted to use: * Tuple/list/set/dict literals. - Using a return converter ------------------------ @@ -1146,6 +1149,7 @@ 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. + Calling Python code ------------------- @@ -1380,6 +1384,7 @@ 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``. + Writing a custom return converter --------------------------------- @@ -1394,8 +1399,9 @@ write your own return converter, please read ``Tools/clinic/clinic.py``, specifically the implementation of ``CReturnConverter`` and all its subclasses. + METH_O and METH_NOARGS ----------------------------------------------- +---------------------- To convert a function using ``METH_O``, make sure the function's single argument is using the ``object`` converter, and mark the @@ -1415,8 +1421,9 @@ any arguments. You can still use a self converter, a return converter, and specify a ``type`` argument to the object converter for ``METH_O``. + tp_new and tp_init functions ----------------------------------------------- +---------------------------- You can convert ``tp_new`` and ``tp_init`` functions. Just name them ``__new__`` or ``__init__`` as appropriate. Notes: @@ -1437,6 +1444,7 @@ them ``__new__`` or ``__init__`` as appropriate. Notes: (If your function doesn't support keywords, the parsing function generated will throw an exception if it receives any.) + Changing and redirecting Clinic's output ---------------------------------------- @@ -1721,7 +1729,7 @@ the file was not modified by hand before it gets overwritten. 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 @@ -1801,7 +1809,6 @@ Argument Clinic added to your file (it'll be at the very bottom), then move it above the ``PyMethodDef`` structure where that macro is used. - Using Argument Clinic in Python files ------------------------------------- From d48d70b84fb552eec3aaf33170d344627e7924b7 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 18 Jul 2023 10:50:17 +0200 Subject: [PATCH 168/538] Docs: Normalise Argument Clinic advanced topics headings (python/cpython#106842) Co-authored-by: Ezio Melotti --- Doc/howto/clinic.rst | 95 +++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 0f99cb649..12d7a77d4 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -560,15 +560,12 @@ Let's dive in! Congratulations, you've ported your first function to work with Argument Clinic! -Advanced topics -=============== +How-to guides +============= -Now that you've had some experience working with Argument Clinic, it's time -for some advanced topics. - -Symbolic default values ------------------------ +How to use symbolic default values +---------------------------------- The default value you provide for a parameter can't be any arbitrary expression. Currently the following are explicitly supported: @@ -583,8 +580,8 @@ expression. Currently the following are explicitly supported: to allow full expressions like ``CONSTANT - 1``.) -Renaming the C functions and variables generated by Argument Clinic -------------------------------------------------------------------- +How to 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 @@ -626,8 +623,8 @@ array) would be ``file``, but the C variable would be named ``file_obj``. You can use this to rename the ``self`` parameter too! -Converting functions using PyArg_UnpackTuple --------------------------------------------- +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 @@ -639,8 +636,8 @@ Currently the generated code will use :c:func:`PyArg_ParseTuple`, but this will change soon. -Optional groups ---------------- +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 @@ -732,8 +729,8 @@ Notes: use optional groups for new code. -Using real Argument Clinic converters, instead of "legacy converters" ---------------------------------------------------------------------- +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 @@ -903,8 +900,8 @@ it accepts, along with the default value for each parameter. Just run ``Tools/clinic/clinic.py --converters`` to see the full list. -Py_buffer ---------- +How to use the ``Py_buffer`` converter +-------------------------------------- When using the ``Py_buffer`` converter (or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters), @@ -912,8 +909,8 @@ 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). -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. @@ -944,8 +941,8 @@ hard-coded encoding strings for parameters whose format units start with ``e``. .. _default_values: -Parameter 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: @@ -968,8 +965,8 @@ There's also special support for a default value of ``NULL``, and for simple expressions, documented in the following sections. -The ``NULL`` default value --------------------------- +How to use 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 @@ -979,8 +976,8 @@ behaves like a default value of ``None``, but the C variable is initialized with ``NULL``. -Expressions specified as default values ---------------------------------------- +How to use 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 @@ -1036,8 +1033,8 @@ you're not permitted to use: * Tuple/list/set/dict literals. -Using a return converter ------------------------- +How to use return converters +---------------------------- By default, the impl function Argument Clinic generates for you returns :c:type:`PyObject * `. @@ -1106,8 +1103,8 @@ their parameters (if any), just run ``Tools/clinic/clinic.py --converters`` for the full list. -Cloning existing functions --------------------------- +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, @@ -1150,8 +1147,8 @@ Also, the function you are cloning from must have been previously defined in the current file. -Calling Python code -------------------- +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 @@ -1178,8 +1175,8 @@ variable to the C code:: /*[python checksum:...]*/ -Using a "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`` @@ -1230,8 +1227,8 @@ type for ``self``, it's best to create your own converter, subclassing [clinic start generated code]*/ -Using a "defining class" converter ----------------------------------- +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 @@ -1293,8 +1290,8 @@ state. Example from the ``setattro`` slot method in See also :pep:`573`. -Writing a custom converter --------------------------- +How to write a custom converter +------------------------------- As we hinted at in the previous section... you can write your own converters! A converter is simply a Python class that inherits from ``CConverter``. @@ -1385,8 +1382,8 @@ You can see more examples of custom converters in the CPython source tree; grep the C files for the string ``CConverter``. -Writing a custom return converter ---------------------------------- +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 @@ -1400,8 +1397,8 @@ specifically the implementation of ``CReturnConverter`` and all its subclasses. -METH_O and METH_NOARGS ----------------------- +How to convert ``METH_O`` and ``METH_NOARGS`` functions +------------------------------------------------------- To convert a function using ``METH_O``, make sure the function's single argument is using the ``object`` converter, and mark the @@ -1422,8 +1419,8 @@ You can still use a self converter, a return converter, and specify a ``type`` argument to the object converter for ``METH_O``. -tp_new and tp_init functions ----------------------------- +How to convert ``tp_new`` and ``tp_init`` functions +--------------------------------------------------- You can convert ``tp_new`` and ``tp_init`` functions. Just name them ``__new__`` or ``__init__`` as appropriate. Notes: @@ -1445,8 +1442,8 @@ them ``__new__`` or ``__init__`` as appropriate. Notes: generated will throw an exception if it receives any.) -Changing and redirecting Clinic's output ----------------------------------------- +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: @@ -1728,8 +1725,8 @@ it in a Clinic block lets Clinic use its existing checksum functionality to ensu the file was not modified by hand before it gets overwritten. -The #ifdef trick ----------------- +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 @@ -1809,8 +1806,8 @@ Argument Clinic added to your file (it'll be at the very bottom), then move it above the ``PyMethodDef`` structure where that macro is used. -Using Argument Clinic in Python files -------------------------------------- +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 From 5122701b72717d3e30031e6d56fd1b11bf52f0e8 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 00:46:50 +0200 Subject: [PATCH 169/538] Docs: Argument Clinic: Group guides about default values (python/cpython#106872) Previous ToC layout (excerpt): - How to use symbolic default values ... - How to assign default values to parameter - How to use the ``NULL`` default value - How to use expressions as default values New layout: - How to assign default values to parameter - The ``NULL`` default value - Symbolic default values - Expressions as default values --- Doc/howto/clinic.rst | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 12d7a77d4..efeb22c61 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -564,22 +564,6 @@ How-to guides ============= -How to use 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 ``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``.) - - How to to rename C functions and variables generated by Argument Clinic ----------------------------------------------------------------------- @@ -965,8 +949,8 @@ There's also special support for a default value of ``NULL``, and for simple expressions, documented in the following sections. -How to use the ``NULL`` default value -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +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 @@ -976,8 +960,24 @@ behaves like a default value of ``None``, but the C variable is initialized with ``NULL``. -How to use expressions as default values -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +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 ``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 From 9f20a1230cc22cbde7a2caf321780e506429ab62 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 21 Jul 2023 08:05:41 +0200 Subject: [PATCH 170/538] Docs: Argument Clinic: Add Background and Tutorial top-level sections (python/cpython#106904) Add Background as a toplevel section with the following subsections: - Background - The goals of Argument Clinic - Basic concepts and usage Rename "Converting your first function" to Tutorial. Add anchors for Background, Tutorial, and How-to Guides: - :ref:`clinic-background` - :ref:`clinic-tutorial` - :ref:`clinic-howtos` Link to these from within the Abstract. Break the compatibility paragraph out of Abstract and make it a note. Co-authored-by: Ezio Melotti --- Doc/howto/clinic.rst | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index efeb22c61..f6bf1d223 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -13,12 +13,20 @@ Argument Clinic How-To Argument Clinic is a preprocessor for CPython C files. Its purpose is to automate all the boilerplate involved - with writing argument parsing code for "builtins". - This document shows you how to convert your first C - function to work with Argument Clinic, and then introduces - some advanced topics on Argument Clinic usage. + with writing argument parsing code for "builtins", + module level functions, and class methods. + This document is divided in three major sections: - Currently Argument Clinic is considered internal-only + * :ref:`clinic-background` talks about the basic concepts and goals of + Argument Clinic. + * :ref:`clinic-tutorial` guides you through all the steps required to + adapt an existing C function to Argument Clinic. + * :ref:`clinic-howtos` details how to handle specific tasks. + + +.. note:: + + Argument Clinic is considered internal-only for CPython. Its use is not supported for files outside CPython, and no guarantees are made regarding backwards compatibility for future versions. In other words: if you @@ -28,8 +36,14 @@ Argument Clinic How-To of CPython *could* be totally incompatible and break all your code. +.. _clinic-background: + +Background +========== + + The goals of Argument Clinic -============================ +---------------------------- Argument Clinic's primary goal is to take over responsibility for all argument parsing code @@ -80,7 +94,7 @@ things with all the information you give it. Basic concepts and usage -======================== +------------------------ Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. If you run that script, specifying a C file as an argument: @@ -142,8 +156,10 @@ For the sake of clarity, here's the terminology we'll use with Argument Clinic: a block.) -Converting your first function -============================== +.. _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 @@ -560,6 +576,8 @@ Let's dive in! Congratulations, you've ported your first function to work with Argument Clinic! +.. _clinic-howtos: + How-to guides ============= From c9ef00506ca2af230307c4ca74a5247d2268aa0f Mon Sep 17 00:00:00 2001 From: Hakan Celik Date: Mon, 24 Jul 2023 14:54:39 +0300 Subject: [PATCH 171/538] Docs: Remove duplicate word in Argument Clinic howto heading (python/cpython#107169) --- Doc/howto/clinic.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index f6bf1d223..933fecab9 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -582,8 +582,8 @@ How-to guides ============= -How to to rename C functions and variables generated by Argument Clinic ------------------------------------------------------------------------ +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 From 1bb1c456a91c13142913882f0c30ff34a05fd04a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 24 Jul 2023 17:22:18 +0200 Subject: [PATCH 172/538] Docs: Add missing markup to Argument Clinic docs (python/cpython#106876) Co-authored-by: Ezio Melotti Co-authored-by: Serhiy Storchaka --- Doc/howto/clinic.rst | 269 +++++++++++++++++++++++-------------------- 1 file changed, 143 insertions(+), 126 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 933fecab9..98d3632ff 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -96,7 +96,8 @@ things with all the information you give it. Basic concepts and usage ------------------------ -Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. +Argument Clinic ships with CPython; you'll find it in +:source:`Tools/clinic/clinic.py`. If you run that script, specifying a C file as an argument: .. code-block:: shell-session @@ -178,9 +179,10 @@ Let's dive in! 1. 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 my example I'm using ``_pickle.Pickler.dump()``. + For my example I'm using + :py:meth:`_pickle.Pickler.dump `. -2. If the call to the ``PyArg_Parse`` function uses any of the +2. If the call to the :c:func:`!PyArg_Parse*` function uses any of the following format units: .. code-block:: none @@ -197,10 +199,10 @@ Let's dive in! support all of these scenarios. But these are advanced topics—let's do something simpler for your first function. - Also, if the function has multiple calls to :c:func:`PyArg_ParseTuple` + 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 - PyArg_Parse functions to parse its arguments, it probably + :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. @@ -217,7 +219,7 @@ Let's dive in! 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 ``help()`` on your builtin in the future, + 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.) @@ -264,7 +266,7 @@ Let's dive in! 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. + this class, and a pointer to the :c:type:`!PyTypeObject` for this class. Sample:: @@ -313,10 +315,10 @@ Let's dive in! Clinic easier. For each parameter, copy the "format unit" for that - parameter from the ``PyArg_Parse()`` format argument and + parameter from the :c:func:`PyArg_Parse` format argument and specify *that* as its converter, as a quoted string. ("format unit" is the formal name for the one-to-three - character substring of the ``format`` parameter that tells + 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`.) @@ -349,7 +351,7 @@ Let's dive in! itself before the first keyword-only argument, indented the same as the parameter lines. - (``_pickle.Pickler.dump`` has neither, so our sample is unchanged.) + (:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged.) 10. If the existing C function calls :c:func:`PyArg_ParseTuple` @@ -410,7 +412,7 @@ Let's dive in! 12. Save and close the file, then run ``Tools/clinic/clinic.py`` on it. With luck everything worked---your block now has output, and - a ``.c.h`` file has been generated! Reopen the file in your + a :file:`.c.h` file has been generated! Reopen the file in your text editor to see:: /*[clinic input] @@ -431,8 +433,8 @@ Let's dive in! 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 ``.c.h`` - file. You'll need to include that in your original ``.c`` file, + 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" @@ -446,8 +448,8 @@ Let's dive in! 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 + 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. @@ -469,7 +471,7 @@ Let's dive in! {"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. + :c:type:`!PyMethodDef` structure for this builtin. If any of these items differ in *any way*, adjust your Argument Clinic function specification and rerun @@ -539,14 +541,14 @@ Let's dive in! ... 15. Remember the macro with the :c:type:`PyMethodDef` structure for this - function? Find the existing :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. So when you - replace the existing static :c:type:`PyMethodDef` structure with the macro, + replace the existing static :c:type:`!PyMethodDef` structure with the macro, *don't* add a comma to the end. Sample:: @@ -562,7 +564,7 @@ Let's dive in! &_Py_ID(new_unique_py_id) - If it does, you'll have to run ``Tools/scripts/generate_global_objects.py`` + If it does, you'll have to run ``make regen-global-objects`` to regenerate the list of precompiled identifiers at this point. @@ -570,7 +572,7 @@ Let's dive in! This change should not introduce any new compile-time warnings or errors, and there should be no externally visible change to Python's behavior. - Well, except for one difference: ``inspect.signature()`` run on your function + Well, 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! @@ -594,15 +596,15 @@ 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 -``pickle.Pickler.dump``, it'd look like this:: +: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 ``pickler_dumper()``, -and the impl function would now be named ``pickler_dumper_impl()``. +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 @@ -620,9 +622,9 @@ using the same ``"as"`` syntax:: 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``. +array) would be *file*, but the C variable would be named ``file_obj``. -You can use this to rename the ``self`` parameter too! +You can use this to rename the *self* parameter too! How to convert functions using ``PyArg_UnpackTuple`` @@ -630,7 +632,7 @@ 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 +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). @@ -649,16 +651,16 @@ 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, +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 ``range()``, which has +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 ``curses.window.addch()``, which has a group of two +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.) +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. @@ -679,7 +681,7 @@ can *only* be used with positional-only parameters. 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 ``curses.window.addch`` +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:: @@ -765,25 +767,25 @@ the same converters. All arguments to Argument Clinic converters are keyword-only. All Argument Clinic converters accept the following arguments: - ``c_default`` + *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`` + *annotation* The annotation value for this parameter. Not currently supported, because :pep:`8` mandates that the Python library may not use annotations. - ``unused`` + *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`` + *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 @@ -791,38 +793,38 @@ of these arguments, along with their meanings: To accept ``None``, add ``NoneType`` to this set. - ``bitwise`` + *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`` + *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`` + *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`` + *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`` + *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`` + *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 ``PyArg_ParseTuple`` +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 @@ -922,19 +924,19 @@ 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``). +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 +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 ``PyUnicode_Type``, you probably want +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 -``PyArg_Parse`` call by hand, you could theoretically decide at runtime what -encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must +: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 @@ -987,7 +989,7 @@ expression. Currently the following are explicitly supported: * Numeric constants (integer and float) * String constants * ``True``, ``False``, and ``None`` -* Simple symbolic constants like ``sys.maxsize``, which must +* 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, @@ -1008,28 +1010,28 @@ Consider the following example: foo: Py_ssize_t = sys.maxsize - 1 -``sys.maxsize`` can have different values on different platforms. Therefore +: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 "``max_widgets``", you may simply use it: +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 -``sys.modules``. That's how it can find ``sys.maxsize`` for example. (Since you -don't know in advance what modules the user will load into their interpreter, +: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: +in C, using the *c_default* parameter to the converter: .. code-block:: none @@ -1095,7 +1097,7 @@ indicate an error has occurred? Normally, a function returns a valid (non-``NUL 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 (``PyErr_Occurred()`` returns a true +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. @@ -1201,9 +1203,9 @@ 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 +Just add your own *self* parameter as the first parameter in a block, and ensure that its converter is an instance of -``self_converter`` or a subclass thereof. +: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. @@ -1211,7 +1213,7 @@ 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:: +passing in the type you want to use as the *type* parameter:: /*[clinic input] @@ -1226,7 +1228,7 @@ passing in the type you want to use as the ``type`` parameter:: 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 -``self_converter`` but overwriting the ``type`` member:: +:class:`!self_converter` but overwriting the :py:attr:`!type` member:: /*[python input] class PicklerObject_converter(self_converter): @@ -1254,8 +1256,8 @@ 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 ``Modules/zlibmodule.c``. First, ``defining_class`` is added to -the clinic input:: +Example from :source:`Modules/zlibmodule.c`. +First, ``defining_class`` is added to the clinic input:: /*[clinic input] zlib.Compress.compress @@ -1285,16 +1287,17 @@ module state:: 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 -``__text_signature__``. +:py:attr:`!__text_signature__`. -The ``defining_class`` converter is not compatible with ``__init__`` and ``__new__`` -methods, which cannot use the ``METH_METHOD`` convention. +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 -``Modules/_threadmodule.c``:: +:source:`Modules/_threadmodule.c`:: static int local_setattro(localobject *self, PyObject *name, PyObject *v) @@ -1312,7 +1315,7 @@ How to write a custom converter ------------------------------- As we hinted at in the previous section... you can write your own converters! -A converter is simply a Python class that inherits from ``CConverter``. +A converter is simply a Python class that inherits from :py:class:`!CConverter`. The main purpose of a custom converter is if you have a parameter using the ``O&`` format unit—parsing this parameter means calling a :c:func:`PyArg_ParseTuple` "converter function". @@ -1323,61 +1326,74 @@ will be automatically registered with Argument Clinic; its name will be the name of your class with the ``_converter`` suffix stripped off. (This is accomplished with a metaclass.) -You shouldn't subclass ``CConverter.__init__``. Instead, you should -write a ``converter_init()`` function. ``converter_init()`` -always accepts a ``self`` parameter; after that, all additional +You shouldn't subclass :py:meth:`!CConverter.__init__`. Instead, you should +write a :py:meth:`!converter_init` function. :py:meth:`!converter_init` +always accepts a *self* parameter; after that, all additional parameters *must* be keyword-only. Any arguments passed in to the converter in Argument Clinic will be passed along to your -``converter_init()``. +:py:meth:`!converter_init`. -There are some additional members of ``CConverter`` you may wish +There are some additional members of :py:class:`!CConverter` you may wish to specify in your subclass. Here's the current list: -``type`` - The C type to use for this variable. - ``type`` should be a Python string specifying the type, e.g. ``int``. - If this is a pointer type, the type string should end with ``' *'``. +.. module:: clinic -``default`` - The Python default value for this parameter, as a Python value. - Or the magic value ``unspecified`` if there is no default. +.. class:: CConverter -``py_default`` - ``default`` as it should appear in Python code, - as a string. - Or ``None`` if there is no default. + .. attribute:: type -``c_default`` - ``default`` as it should appear in C code, - as a string. - Or ``None`` if there is no default. + The C type to use for this variable. + :attr:`!type` should be a Python string specifying the type, + e.g. ``'int'``. + If this is a pointer type, the type string should end with ``' *'``. -``c_ignored_default`` - The default value used to initialize the C variable when - there is no default, but not specifying a default may - result in an "uninitialized variable" warning. This can - easily happen when using option groups—although - properly written code will never actually use this value, - the variable does get passed in to the impl, and the - C compiler will complain about the "use" of the - uninitialized value. This value should always be a - non-empty string. + .. attribute:: default -``converter`` - The name of the C converter function, as a string. + The Python default value for this parameter, as a Python value. + Or the magic value ``unspecified`` if there is no default. -``impl_by_reference`` - A boolean value. If true, - Argument Clinic will add a ``&`` in front of the name of - the variable when passing it into the impl function. + .. attribute:: py_default -``parse_by_reference`` - 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`. + :attr:`!default` as it should appear in Python code, + as a string. + Or ``None`` if there is no default. + .. attribute:: c_default -Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``:: + :attr:`!default` as it should appear in C code, + as a string. + Or ``None`` if there is no default. + + .. attribute:: c_ignored_default + + The default value used to initialize the C variable when + there is no default, but not specifying a default may + result in an "uninitialized variable" warning. This can + easily happen when using option groups—although + properly written code will never actually use this value, + the variable does get passed in to the impl, and the + C compiler will complain about the "use" of the + uninitialized value. This value should always be a + non-empty string. + + .. attribute:: converter + + The name of the C converter function, as a string. + + .. attribute:: impl_by_reference + + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into the impl function. + + .. attribute:: parse_by_reference + + 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`. + + +Here's the simplest example of a custom converter, from :source:`Modules/zlibmodule.c`:: /*[python input] @@ -1397,7 +1413,7 @@ 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``. +source tree; grep the C files for the string :py:class:`!CConverter`. How to write a custom return converter @@ -1407,18 +1423,18 @@ 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 ``CReturnConverter``. +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 ``Tools/clinic/clinic.py``, -specifically the implementation of ``CReturnConverter`` and +write your own return converter, please read :source:`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 ``METH_O``, make sure the function's +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:: @@ -1430,24 +1446,25 @@ arguments as positional-only:: [clinic start generated code]*/ -To convert a function using ``METH_NOARGS``, just don't specify +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 ``METH_O``. +a *type* argument to the object converter for :c:macro:`METH_O`. How to convert ``tp_new`` and ``tp_init`` functions --------------------------------------------------- -You can convert ``tp_new`` and ``tp_init`` functions. Just name -them ``__new__`` or ``__init__`` as appropriate. Notes: +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 ``PyMethodDef`` ``#define`` is generated for these functions. +* No :c:type:`PyMethodDef` ``#define`` is generated for these functions. * ``__init__`` functions return ``int``, not ``PyObject *``. @@ -1482,7 +1499,7 @@ 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 ``PyMethodDef`` structure + 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: @@ -1526,8 +1543,8 @@ Let's start with defining some terminology: 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 ``_pickle.c`` would be written to - ``_pickle.clinic.c``.) + 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!** @@ -1780,7 +1797,7 @@ like so:: } #endif /* HAVE_FUNCTIONNAME */ -Then, remove those three lines from the ``PyMethodDef`` structure, +Then, remove those three lines from the :c:type:`PyMethodDef` structure, replacing them with the macro Argument Clinic generated: .. code-block:: none @@ -1821,7 +1838,7 @@ This may mean that you get a complaint from Argument Clinic: 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 ``PyMethodDef`` structure where that macro is used. +move it above the :c:type:`PyMethodDef` structure where that macro is used. How to use Argument Clinic in Python files From ce97b5200174e7a5ce21a47f52ee30678b5cb80e Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 26 Jul 2023 22:54:25 +0200 Subject: [PATCH 173/538] Docs: Remove the numbered steps from the Argument Clinic tutorial (python/cpython#107203) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead, order the tutorial as one body of prose, making it easier to align the tutorial according to Diátaxis principles. --- Doc/howto/clinic.rst | 624 +++++++++++++++++++++---------------------- 1 file changed, 310 insertions(+), 314 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 98d3632ff..ea3b4537d 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -167,23 +167,23 @@ 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 advanced concepts you'll see later on in -the document (like "return converters" and "self converters"). +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. -Let's dive in! +First, make sure you're working with a freshly updated checkout +of the CPython trunk. -0. 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 `. -1. 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 my example I'm using - :py:meth:`_pickle.Pickler.dump `. - -2. If the call to the :c:func:`!PyArg_Parse*` function uses any of the - following format units: +If the call to the :c:func:`!PyArg_Parse*` function uses any of the +following format units...: .. code-block:: none @@ -194,388 +194,377 @@ Let's dive in! et et# - or if it has multiple calls to :c:func:`PyArg_ParseTuple`, - you should choose a different function. Argument Clinic *does* - support all of these scenarios. But these are advanced - topics—let's do something simpler for your first function. - - 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. - -3. Add the following boilerplate above the function, creating our block:: - - /*[clinic input] - [clinic start generated code]*/ - -4. 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.) - - Sample:: +... 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.) - /*[clinic input] - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -5. 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. - - (Our example docstring consists solely of a summary line, so the sample - code doesn't have to change for this step.) +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. -6. 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. - - Sample:: +Next, add the following boilerplate above the function, +creating our input block:: /*[clinic input] - _pickle.Pickler.dump - - Write a pickled representation of obj to the open file. [clinic start generated code]*/ -7. 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.) +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. - 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. +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. - 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. +Example docstring summary line:: - Sample:: - - /*[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]*/ - - - - -8. 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 + /*[clinic input] + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - name_of_parameter: converter = default_value +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.) - Argument Clinic's support for "default values" is quite sophisticated; - please see :ref:`the section below on default values ` - for more information. +Our example docstring consists solely of a summary line, so the sample +code doesn't have to change for this step. - Add a blank line below the parameters. +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. - 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. +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`:: - 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. ("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`.) + /*[clinic input] + _pickle.Pickler.dump - For multicharacter format units like ``z#``, use the - entire two-or-three character string. + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - Sample:: +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. - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ +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. - /*[clinic input] - _pickle.Pickler.dump +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:: - obj: 'O' + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ + /*[clinic input] + _pickle.Pickler.dump -9. 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. + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - 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. +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: - (:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged.) +.. code-block:: none + name_of_parameter: converter -10. If the existing C function calls :c:func:`PyArg_ParseTuple` - (as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its - arguments are positional-only. +If the parameter has a default value, add that after the +converter: - To mark all parameters as positional-only in Argument Clinic, - add a ``/`` on a line by itself after the last parameter, - indented the same as the parameter lines. +.. code-block:: none - Currently this is all-or-nothing; either all parameters are - positional-only, or none of them are. (In the future Argument - Clinic may relax this restriction.) + name_of_parameter: converter = default_value - Sample:: +Argument Clinic's support for "default values" is quite sophisticated; +see :ref:`clinic-howto-default-values` for more information. - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ +Next, add a blank line below the parameters. - /*[clinic input] - _pickle.Pickler.dump +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. - obj: 'O' - / +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`. - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ +For multicharacter format units like ``z#``, +use the entire two-or-three character string. -11. It's helpful to write a per-parameter docstring for each parameter. - But per-parameter docstrings are optional; you can skip this step - if you prefer. +Sample:: - 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. + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ - Sample:: + /*[clinic input] + _pickle.Pickler.dump - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ + obj: 'O' - /*[clinic input] - _pickle.Pickler.dump + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - obj: 'O' - The object to be pickled. - / +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. - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ +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. -12. 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! Reopen the file in your - text editor to see:: +:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged. - /*[clinic input] - _pickle.Pickler.dump +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. - obj: 'O' - The object to be pickled. - / +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. - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ +Sample:: - static PyObject * - _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) - /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ - 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. + /*[clinic input] + _pickle.Pickler.dump - 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:: + obj: 'O' + / - #include "clinic/_pickle.c.h" + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ -13. Double-check that the argument-parsing code Argument Clinic generated - looks basically the same as the existing 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. - 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. +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. - 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. +Sample:: - (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.) + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ - Third, for parameters whose format units require two arguments - (like a length variable, or an encoding string, or a pointer - to a conversion function), ensure that the second argument is - *exactly* the same between the two invocations. + /*[clinic input] + _pickle.Pickler.dump - 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:: + obj: 'O' + The object to be pickled. + / - #define __PICKLE_PICKLER_DUMP_METHODDEF \ - {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__}, + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - This static structure should be *exactly* the same as the existing static - :c:type:`!PyMethodDef` structure for this builtin. +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:: - 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. + /*[clinic input] + _pickle.Pickler.dump + obj: 'O' + The object to be pickled. + / -14. 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. + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - Let's reiterate, just because it's kind of weird. Your code should now - look like this:: + static PyObject * + _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) + /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ - static return_type - your_function_impl(...) - /*[clinic end generated code: checksum=...]*/ - { - ... +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. - 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. +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:: - Sample:: + #include "clinic/_pickle.c.h" - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +Double-check that the argument-parsing code Argument Clinic generated +looks basically the same as the existing code. - /*[clinic input] - _pickle.Pickler.dump +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. - obj: 'O' - The object to be pickled. - / +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. - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ +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. - 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; - } +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. - if (_Pickler_ClearBuffer(self) < 0) - return NULL; +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__}, -15. 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.) +This static structure should be *exactly* the same as the existing static +:c:type:`!PyMethodDef` structure for this builtin. - Note that the body of the macro contains a trailing comma. So when you - replace the existing static :c:type:`!PyMethodDef` structure with the macro, - *don't* add a comma to the end. +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. - Sample:: +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. - static struct PyMethodDef Pickler_methods[] = { - __PICKLE_PICKLER_DUMP_METHODDEF - __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF - {NULL, NULL} /* sentinel */ - }; +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=...]*/ + { + ... -16. Argument Clinic may generate new instances of ``_Py_ID``. For example:: +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. - &_Py_ID(new_unique_py_id) +Sample:: - If it does, you'll have to run ``make regen-global-objects`` - to regenerate the list of precompiled identifiers at this point. + /*[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 -17. 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. + obj: 'O' + The object to be pickled. + / - Well, except for one difference: :py:func:`inspect.signature` run on your function - should now provide a valid signature! + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - Congratulations, you've ported your first function to work with Argument Clinic! + 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! .. _clinic-howtos: @@ -913,6 +902,8 @@ 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 ------------------------------ @@ -943,6 +934,7 @@ This restriction doesn't seem unreasonable; CPython itself always passes in stat 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 @@ -1053,6 +1045,8 @@ you're not permitted to use: * Tuple/list/set/dict literals. +.. _clinic-howto-return-converters: + How to use return converters ---------------------------- @@ -1195,6 +1189,8 @@ variable to the C code:: /*[python checksum:...]*/ +.. _clinic-howto-self-converter: + How to use the "self converter" ------------------------------- From e60b3280b96d634a517eee6535fc0e3eb4630fc7 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 27 Jul 2023 00:08:43 +0200 Subject: [PATCH 174/538] Docs: Argument Clinic: Restructure "Basic concepts and usage" (python/cpython#106981) Split "Basic concepts and usage" into: - Reference - Terminology - CLI reference - Background - Basic concepts Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Alex Waygood Co-authored-by: Ezio Melotti --- Doc/howto/clinic.rst | 172 ++++++++++++++++++++++++++++++++----------- 1 file changed, 129 insertions(+), 43 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index ea3b4537d..7aafd4871 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -8,6 +8,7 @@ Argument Clinic How-To :author: Larry Hastings +**Source code:** :source:`Tools/clinic/clinic.py`. .. topic:: Abstract @@ -15,10 +16,12 @@ Argument Clinic How-To Its purpose is to automate all the boilerplate involved with writing argument parsing code for "builtins", module level functions, and class methods. - This document is divided in three major sections: + This document is divided in four major sections: * :ref:`clinic-background` talks about the basic concepts and goals of Argument Clinic. + * :ref:`clinic-reference` describes the command-line interface and Argument + Clinic terminology. * :ref:`clinic-tutorial` guides you through all the steps required to adapt an existing C function to Argument Clinic. * :ref:`clinic-howtos` details how to handle specific tasks. @@ -93,39 +96,29 @@ and it should be able to do many interesting and smart things with all the information you give it. -Basic concepts and usage ------------------------- +Basic concepts +-------------- -Argument Clinic ships with CPython; you'll find it in -:source:`Tools/clinic/clinic.py`. -If you run that script, specifying a C file as an argument: - -.. code-block:: shell-session - - $ python Tools/clinic/clinic.py foo.c - -Argument Clinic will scan over the file looking for lines that -look exactly like this: +When Argument Clinic is run on a file, either via the :ref:`clinic-cli` +or via ``make clinic``, it will scan over the input files looking for +:term:`start lines `: .. code-block:: none /*[clinic input] -When it finds one, it reads everything up to a line that looks -exactly like this: +When it finds one, it reads everything up to the :term:`end line`: .. code-block:: none [clinic start generated code]*/ -Everything in between these two lines is input for Argument Clinic. -All of these lines, including the beginning and ending comment -lines, are collectively called an Argument Clinic "block". - -When Argument Clinic parses one of these blocks, it -generates output. This output is rewritten into the C file -immediately after the block, followed by a comment containing a checksum. -The Argument Clinic block now looks like this: +Everything in between these two lines is Argument Clinic :term:`input`. +When Argument Clinic parses input, it generates :term:`output`. +The output is rewritten into the C file immediately after the input, +followed by a :term:`checksum line`. +All of these lines, including the :term:`start line` and :term:`checksum line`, +are collectively called an Argument Clinic :term:`block`: .. code-block:: none @@ -133,28 +126,121 @@ The Argument Clinic block now looks like this: ... clinic input goes here ... [clinic start generated code]*/ ... clinic output goes here ... - /*[clinic end generated code: checksum=...]*/ + /*[clinic end generated code: ...]*/ If you run Argument Clinic on the same file a second time, Argument Clinic -will discard the old output and write out the new output with a fresh checksum -line. However, if the input hasn't changed, the output won't change either. - -You should never modify the output portion of an Argument Clinic block. Instead, -change the input until it produces the output you want. (That's the purpose of the -checksum—to detect if someone changed the output, as these edits would be lost -the next time Argument Clinic writes out fresh output.) - -For the sake of clarity, here's the terminology we'll use with Argument Clinic: - -* The first line of the comment (``/*[clinic input]``) is the *start line*. -* The last line of the initial comment (``[clinic start generated code]*/``) is the *end line*. -* The last line (``/*[clinic end generated code: checksum=...]*/``) is the *checksum line*. -* In between the start line and the end line is the *input*. -* In between the end line and the checksum line is the *output*. -* All the text collectively, from the start line to the checksum line inclusively, - is the *block*. (A block that hasn't been successfully processed by Argument - Clinic yet doesn't have output or a checksum line, but it's still considered - a block.) +will discard the old :term:`output` and write out the new output with a fresh +:term:`checksum line`. +If the :term:`input` hasn't changed, the output won't change either. + +.. note:: + + You should never modify the output of an Argument Clinic block, + as any change will be lost in future Argument Clinic runs; + Argument Clinic will detect an output checksum mismatch and regenerate the + correct output. + If you are not happy with the generated output, + you should instead change the input until it produces the output you want. + + +.. _clinic-reference: + +Reference +========= + + +.. _clinic-terminology: + +Terminology +----------- + +.. glossary:: + + start line + The line ``/*[clinic input]``. + This line marks the beginning of Argument Clinic input. + Note that the *start line* opens a C block comment. + + end line + The line ``[clinic start generated code]*/``. + The *end line* marks the _end_ of Argument Clinic :term:`input`, + but at the same time marks the _start_ of Argument Clinic :term:`output`, + thus the text *"clinic start start generated code"* + Note that the *end line* closes the C block comment opened + by the *start line*. + + checksum + A hash to distinguish unique :term:`inputs ` + and :term:`outputs `. + + checksum line + A line that looks like ``/*[clinic end generated code: ...]*/``. + The three dots will be replaced by a :term:`checksum` generated from the + :term:`input`, and a :term:`checksum` generated from the :term:`output`. + The checksum line marks the end of Argument Clinic generated code, + and is used by Argument Clinic to determine if it needs to regenerate + output. + + input + The text between the :term:`start line` and the :term:`end line`. + Note that the start and end lines open and close a C block comment; + the *input* is thus a part of that same C block comment. + + output + The text between the :term:`end line` and the :term:`checksum line`. + + block + All text from the :term:`start line` to the :term:`checksum line` inclusively. + + +.. _clinic-cli: + +Command-line interface +---------------------- + +The Argument Clinic :abbr:`CLI (Command-Line Interface)` is typically used to +process a single source file, like this: + +.. code-block:: shell-session + + $ python3 ./Tools/clinic/clinic.py foo.c + +The CLI supports the following options: + +.. program:: ./Tools/clinic/clinic.py [-h] [-f] [-o OUTPUT] [-v] \ + [--converters] [--make] [--srcdir SRCDIR] [FILE ...] + +.. option:: -h, --help + + Print CLI usage. + +.. option:: -f, --force + + Force output regeneration. + +.. option:: -o, --output OUTPUT + + Redirect file output to OUTPUT + +.. option:: -v, --verbose + + Enable verbose mode. + +.. option:: --converters + + Print a list of all supported converters and return converters. + +.. option:: --make + + Walk :option:`--srcdir` to run over all relevant files. + +.. option:: --srcdir SRCDIR + + The directory tree to walk in :option:`--make` mode. + +.. option:: FILE ... + + The list of files to process. .. _clinic-tutorial: From 5326a443a1c50999fb616c4d7ce0c10678b3f8e6 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 31 Jul 2023 23:33:13 +0200 Subject: [PATCH 175/538] python/cpython#107507: Replace 'The goals of Argument Clinic' with a summary (python/cpython#107508) Summarise the goals of Argument Clinic in a single sentence. Mention that Argument Clinic was introduced with PEP-436. --- Doc/howto/clinic.rst | 58 +++----------------------------------------- 1 file changed, 4 insertions(+), 54 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 7aafd4871..9c9a4f45d 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -13,8 +13,10 @@ Argument Clinic How-To .. topic:: Abstract Argument Clinic is a preprocessor for CPython C files. - Its purpose is to automate all the boilerplate involved - with writing argument parsing code for "builtins", + It was introduced in Python 3.4 with :pep:`436`, + in order to provide introspection signatures, + and to generate performant and tailor-made boilerplate code + for argument parsing in CPython builtins, module level functions, and class methods. This document is divided in four major sections: @@ -44,58 +46,6 @@ Argument Clinic How-To Background ========== - -The goals of Argument Clinic ----------------------------- - -Argument Clinic's primary goal -is to take over responsibility for all argument parsing code -inside CPython. This means that, when you convert a function -to work with Argument Clinic, that function should no longer -do any of its own argument parsing—the code generated by -Argument Clinic should be a "black box" to you, where CPython -calls in at the top, and your code gets called at the bottom, -with ``PyObject *args`` (and maybe ``PyObject *kwargs``) -magically converted into the C variables and types you need. - -In order for Argument Clinic to accomplish its primary goal, -it must be easy to use. Currently, working with CPython's -argument parsing library is a chore, requiring maintaining -redundant information in a surprising number of places. -When you use Argument Clinic, you don't have to repeat yourself. - -Obviously, no one would want to use Argument Clinic unless -it's solving their problem—and without creating new problems of -its own. -So it's paramount that Argument Clinic generate correct code. -It'd be nice if the code was faster, too, but at the very least -it should not introduce a major speed regression. (Eventually Argument -Clinic *should* make a major speedup possible—we could -rewrite its code generator to produce tailor-made argument -parsing code, rather than calling the general-purpose CPython -argument parsing library. That would make for the fastest -argument parsing possible!) - -Additionally, Argument Clinic must be flexible enough to -work with any approach to argument parsing. Python has -some functions with some very strange parsing behaviors; -Argument Clinic's goal is to support all of them. - -Finally, the original motivation for Argument Clinic was -to provide introspection "signatures" for CPython builtins. -It used to be, the introspection query functions would throw -an exception if you passed in a builtin. With Argument -Clinic, that's a thing of the past! - -One idea you should keep in mind, as you work with -Argument Clinic: the more information you give it, the -better job it'll be able to do. -Argument Clinic is admittedly relatively simple right -now. But as it evolves it will get more sophisticated, -and it should be able to do many interesting and smart -things with all the information you give it. - - Basic concepts -------------- From 58d8d34f9e2845cf13f56620abeac2f8d3838ad8 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 5 Aug 2023 22:19:37 +0200 Subject: [PATCH 176/538] Docs: Argument Clinic: Improve 'How to write a custom converter' (python/cpython#107328) - Omit unneccesary wording and sentences - Don't mention implementation details (no digression, explanation) Co-authored-by: Ezio Melotti --- Doc/howto/clinic.rst | 50 +++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 9c9a4f45d..dcede13a0 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1343,35 +1343,37 @@ state. Example from the ``setattro`` slot method in See also :pep:`573`. +.. _clinic-howto-custom-converter: + How to write a custom converter ------------------------------- -As we hinted at in the previous section... you can write your own converters! -A converter is simply a Python class that inherits from :py:class:`!CConverter`. -The main purpose of a custom converter is if you have a parameter using -the ``O&`` format unit—parsing this parameter means calling +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 ``*something*_converter``. -If the name follows this convention, then your converter class -will be automatically registered with Argument Clinic; its name -will be the name of your class with the ``_converter`` suffix -stripped off. (This is accomplished with a metaclass.) - -You shouldn't subclass :py:meth:`!CConverter.__init__`. Instead, you should -write a :py:meth:`!converter_init` function. :py:meth:`!converter_init` -always accepts a *self* parameter; after that, all additional -parameters *must* be keyword-only. Any arguments passed in to -the converter in Argument Clinic will be passed along to your -:py:meth:`!converter_init`. +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. -There are some additional members of :py:class:`!CConverter` you may wish -to specify in your subclass. Here's the current list: +Instead of subclassing :py:meth:`!CConverter.__init__`, +write a :py:meth:`!converter_init` method. +Apart for the *self* parameter, all additional :py:meth:`!converter_init` +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. .. module:: clinic .. class:: CConverter + The base class for all converters. + See :ref:`clinic-howto-custom-converter` for how to subclass this class. + .. attribute:: type The C type to use for this variable. @@ -1436,16 +1438,16 @@ Here's the simplest example of a custom converter, from :source:`Modules/zlibmod [python start generated code]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ -This block adds a converter to Argument Clinic named ``ssize_t``. Parameters -declared as ``ssize_t`` will be declared as type :c:type:`Py_ssize_t`, and will -be parsed by the ``'O&'`` format unit, which will call the -``ssize_t_converter`` converter function. ``ssize_t`` variables -automatically support default values. +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 :py:class:`!CConverter`. +source tree; grep the C files for the string ``CConverter``. How to write a custom return converter From 75ab88f4c80709c78f9aa6f9f7e328b5756d9531 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 7 Aug 2023 02:08:34 +0200 Subject: [PATCH 177/538] Docs: Argument Clinic: Move the CConverter class to the reference (python/cpython#107671) --- Doc/howto/clinic.rst | 133 ++++++++++++++++++++++--------------------- 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index dcede13a0..e8e6aace3 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -193,6 +193,71 @@ The CLI supports the following options: The list of files to process. +.. _clinic-classes: + +Classes for extending Argument Clinic +------------------------------------- + +.. module:: clinic + +.. class:: CConverter + + The base class for all converters. + See :ref:`clinic-howto-custom-converter` for how to subclass this class. + + .. attribute:: type + + The C type to use for this variable. + :attr:`!type` should be a Python string specifying the type, + e.g. ``'int'``. + If this is a pointer type, the type string should end with ``' *'``. + + .. attribute:: default + + The Python default value for this parameter, as a Python value. + Or the magic value ``unspecified`` if there is no default. + + .. attribute:: py_default + + :attr:`!default` as it should appear in Python code, + as a string. + Or ``None`` if there is no default. + + .. attribute:: c_default + + :attr:`!default` as it should appear in C code, + as a string. + Or ``None`` if there is no default. + + .. attribute:: c_ignored_default + + The default value used to initialize the C variable when + there is no default, but not specifying a default may + result in an "uninitialized variable" warning. This can + easily happen when using option groups—although + properly written code will never actually use this value, + the variable does get passed in to the impl, and the + C compiler will complain about the "use" of the + uninitialized value. This value should always be a + non-empty string. + + .. attribute:: converter + + The name of the C converter function, as a string. + + .. attribute:: impl_by_reference + + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into the impl function. + + .. attribute:: parse_by_reference + + 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 @@ -1348,7 +1413,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:`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". @@ -1360,73 +1425,13 @@ your converter class with the ``_converter`` suffix stripped off. Instead of subclassing :py:meth:`!CConverter.__init__`, write a :py:meth:`!converter_init` method. -Apart for the *self* parameter, all additional :py:meth:`!converter_init` -parameters **must** be keyword-only. +: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 +See :py:class:`CConverter` for a list of members you may wish to specify in your subclass. -.. module:: clinic - -.. class:: CConverter - - The base class for all converters. - See :ref:`clinic-howto-custom-converter` for how to subclass this class. - - .. attribute:: type - - The C type to use for this variable. - :attr:`!type` should be a Python string specifying the type, - e.g. ``'int'``. - If this is a pointer type, the type string should end with ``' *'``. - - .. attribute:: default - - The Python default value for this parameter, as a Python value. - Or the magic value ``unspecified`` if there is no default. - - .. attribute:: py_default - - :attr:`!default` as it should appear in Python code, - as a string. - Or ``None`` if there is no default. - - .. attribute:: c_default - - :attr:`!default` as it should appear in C code, - as a string. - Or ``None`` if there is no default. - - .. attribute:: c_ignored_default - - The default value used to initialize the C variable when - there is no default, but not specifying a default may - result in an "uninitialized variable" warning. This can - easily happen when using option groups—although - properly written code will never actually use this value, - the variable does get passed in to the impl, and the - C compiler will complain about the "use" of the - uninitialized value. This value should always be a - non-empty string. - - .. attribute:: converter - - The name of the C converter function, as a string. - - .. attribute:: impl_by_reference - - A boolean value. If true, - Argument Clinic will add a ``&`` in front of the name of - the variable when passing it into the impl function. - - .. attribute:: parse_by_reference - - 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`. - - Here's the simplest example of a custom converter, from :source:`Modules/zlibmodule.c`:: /*[python input] From 62b9d3401c16abc8bbf9c5410cf59adf8635a4da Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 7 Aug 2023 13:28:08 +0200 Subject: [PATCH 178/538] python/cpython#95065: Add Argument Clinic support for deprecating positional use of parameters (python/cpython#95151) It is now possible to deprecate passing parameters positionally with Argument Clinic, using the new '* [from X.Y]' syntax. (To be read as "keyword-only from Python version X.Y") Co-authored-by: Alex Waygood Co-authored-by: Serhiy Storchaka --- Doc/howto/clinic.rst | 88 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index e8e6aace3..286623c24 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1898,3 +1898,91 @@ blocks embedded in Python files look slightly different. They look like this: #[python start generated code]*/ def foo(): pass #/*[python checksum:...]*/ + + +.. _clinic-howto-deprecate-positional: + +How to deprecate passing parameters positionally +------------------------------------------------ + +Argument Clinic provides syntax that makes it possible to generate code that +deprecates passing :term:`arguments ` positionally. +For example, say we've got a module-level function :py:func:`!foo.myfunc` +that has three :term:`parameters `: +positional-or-keyword parameters *a* and *b*, and a keyword-only parameter *c*:: + + /*[clinic input] + module foo + myfunc + a: int + b: int + * + c: int + [clinic start generated output]*/ + +We now want to make the *b* parameter keyword-only; +however, we'll have to wait two releases before making this change, +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 the *b* parameter is passed positionally, +and we'll be allowed to make it keyword-only 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 above the *b* parameter:: + + /*[clinic input] + module foo + myfunc + a: int + * [from 3.14] + b: int + * + c: 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` *b* is passed positionally. +C preprocessor directives are also generated for emitting +compiler warnings if the ``* [from ...]`` line has 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:83:8: warning: Update 'b' in 'myfunc' in 'foomodule.c' to be keyword-only. [-W#warnings] + # warning "Update 'b' in 'myfunc' in 'foomodule.c' to be keyword-only." + ^ + +We now close the deprecation phase by making *b* keyword-only; +replace the ``* [from ...]``` line above *b* +with the ``*`` from the line above *c*:: + + /*[clinic input] + module foo + myfunc + a: int + * + b: int + c: 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 78318c1631f31f5a22a211adee1d1d7634d5b685 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 8 Aug 2023 08:42:08 +0200 Subject: [PATCH 179/538] python/cpython#86457: Add docs for Argument Clinic @text_signature directive (python/cpython#107747) Co-authored-by: Alex Waygood --- Doc/howto/clinic.rst | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 286623c24..743c7c9cb 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1900,6 +1900,40 @@ blocks embedded in Python files look slightly different. They look like this: #/*[python checksum:...]*/ +.. _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 :source:`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:: + + Doc_STRVAR(code_replace__doc__, + "replace($self, /, **changes)\n" + "--\n" + "\n" + "Return a copy of the code object with new values for the specified fields."); + + .. _clinic-howto-deprecate-positional: How to deprecate passing parameters positionally From 2d0204d36accfcaa8b3d4be9a8fbeda4431189c6 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 8 Aug 2023 22:50:54 +0200 Subject: [PATCH 180/538] python/cpython#104683: Add --exclude option to Argument Clinic CLI (python/cpython#107770) Co-authored-by: Serhiy Storchaka --- Doc/howto/clinic.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 743c7c9cb..2d89ccc20 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -188,6 +188,11 @@ The CLI supports the following options: The directory tree to walk in :option:`--make` mode. +.. option:: --exclude EXCLUDE + + A file to exclude in :option:`--make` mode. + This option can be given multiple times. + .. option:: FILE ... The list of files to process. From 1cf395b571cc5f75fdc1a33143c933fc941ca4ad Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 9 Aug 2023 09:43:02 +0200 Subject: [PATCH 181/538] Docs: clean up Argument Clinic howto's (python/cpython#107797) - fix formatting in @text_signature howto and NEWS entry - fix formatting and example text in deprecate-positionals howto --- Doc/howto/clinic.rst | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 2d89ccc20..463a938fa 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1930,13 +1930,14 @@ Example from :source:`Objects/codeobject.c`:: 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:: +The generated docstring ends up looking like this: - Doc_STRVAR(code_replace__doc__, - "replace($self, /, **changes)\n" - "--\n" - "\n" - "Return a copy of the code object with new values for the specified fields."); +.. code-block:: none + + replace($self, /, **changes) + -- + + Return a copy of the code object with new values for the specified fields. .. _clinic-howto-deprecate-positional: @@ -1968,7 +1969,7 @@ whenever the *b* parameter is passed positionally, and we'll be allowed to make it keyword-only in Python 3.14 at the earliest. We can use Argument Clinic to emit the desired deprecation warnings -using the ``* [from ...]``` syntax, +using the ``* [from ...]`` syntax, by adding the line ``* [from 3.14]`` right above the *b* parameter:: /*[clinic input] @@ -2000,12 +2001,12 @@ Luckily for us, compiler warnings are now generated: .. code-block:: none In file included from Modules/foomodule.c:139: - Modules/clinic/foomodule.c.h:83:8: warning: Update 'b' in 'myfunc' in 'foomodule.c' to be keyword-only. [-W#warnings] - # warning "Update 'b' in 'myfunc' in 'foomodule.c' to be keyword-only." + Modules/clinic/foomodule.c.h:139:8: warning: In 'foomodule.c', update parameter(s) 'a' and 'b' in the clinic input of 'mymod.myfunc' to be keyword-only. [-W#warnings] + # warning "In 'foomodule.c', update parameter(s) 'a' and 'b' in the clinic input of 'mymod.myfunc' to be keyword-only. [-W#warnings]" ^ We now close the deprecation phase by making *b* keyword-only; -replace the ``* [from ...]``` line above *b* +replace the ``* [from ...]`` line above *b* with the ``*`` from the line above *c*:: /*[clinic input] From b59f9cd888443d57506531141176e5ff69153e2f Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 9 Aug 2023 15:51:35 +0200 Subject: [PATCH 182/538] Add clinic.rst with history --- {Doc/howto => development-tools}/clinic.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {Doc/howto => development-tools}/clinic.rst (100%) diff --git a/Doc/howto/clinic.rst b/development-tools/clinic.rst similarity index 100% rename from Doc/howto/clinic.rst rename to development-tools/clinic.rst From 7ef9a8e9ab490264bd4bcf8dc8273e085e323ed2 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 9 Aug 2023 15:52:52 +0200 Subject: [PATCH 183/538] Add clinic.rst to Development Tools --- development-tools/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/development-tools/index.rst b/development-tools/index.rst index d8e8453cf..d7b88bf6d 100644 --- a/development-tools/index.rst +++ b/development-tools/index.rst @@ -5,6 +5,7 @@ Development tools .. toctree:: :maxdepth: 5 + clinic gdb clang coverity From 4baaf762189cd37d48ec9283a15914aa39c6a3f6 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 9 Aug 2023 16:05:32 +0200 Subject: [PATCH 184/538] Adapt clinic.rst - Use ``:cpy-file:`` instead of ``:source:`` - Fix Sphinx complaint about 'range' - Mark up the abstract similar to other pages in the devguide --- development-tools/clinic.rst | 48 ++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index 463a938fa..c03f4e9b3 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -1,32 +1,26 @@ .. highlight:: c -.. _howto-clinic: +.. _clinic: -********************** -Argument Clinic How-To -********************** +*************** +Argument Clinic +*************** :author: Larry Hastings -**Source code:** :source:`Tools/clinic/clinic.py`. +**Source code:** :cpy-file:`Tools/clinic/clinic.py`. -.. topic:: Abstract +Argument Clinic is a preprocessor for CPython C files. +It was introduced in Python 3.4 with :pep:`436`, +in order to provide introspection signatures, +and to generate performant and tailor-made boilerplate code +for argument parsing in CPython builtins, module level functions, and class methods. +This document is divided in four major sections: - Argument Clinic is a preprocessor for CPython C files. - It was introduced in Python 3.4 with :pep:`436`, - in order to provide introspection signatures, - and to generate performant and tailor-made boilerplate code - for argument parsing in CPython builtins, - module level functions, and class methods. - This document is divided in four major sections: - - * :ref:`clinic-background` talks about the basic concepts and goals of - Argument Clinic. - * :ref:`clinic-reference` describes the command-line interface and Argument - Clinic terminology. - * :ref:`clinic-tutorial` guides you through all the steps required to - adapt an existing C function to Argument Clinic. - * :ref:`clinic-howtos` details how to handle specific tasks. +* :ref:`clinic-background` talks about the basic concepts and goals of Argument Clinic. +* :ref:`clinic-reference` describes the command-line interface and Argument Clinic terminology. +* :ref:`clinic-tutorial` guides you through all the steps required to adapt an existing C function to Argument Clinic. +* :ref:`clinic-howtos` details how to handle specific tasks. .. note:: @@ -749,7 +743,7 @@ 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 +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 @@ -1358,7 +1352,7 @@ 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 :source:`Modules/zlibmodule.c`. +Example from :cpy-file:`Modules/zlibmodule.c`. First, ``defining_class`` is added to the clinic input:: /*[clinic input] @@ -1399,7 +1393,7 @@ 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 -:source:`Modules/_threadmodule.c`:: +:cpy-file:`Modules/_threadmodule.c`:: static int local_setattro(localobject *self, PyObject *name, PyObject *v) @@ -1437,7 +1431,7 @@ 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 :source:`Modules/zlibmodule.c`:: +Here's the simplest example of a custom converter, from :cpy-file:`Modules/zlibmodule.c`:: /*[python input] @@ -1470,7 +1464,7 @@ 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 :source:`Tools/clinic/clinic.py`, +write your own return converter, please read :cpy-file:`Tools/clinic/clinic.py`, specifically the implementation of :py:class:`!CReturnConverter` and all its subclasses. @@ -1917,7 +1911,7 @@ 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 :source:`Objects/codeobject.c`:: +Example from :cpy-file:`Objects/codeobject.c`:: /*[clinic input] @text_signature "($self, /, **changes)" From 8bdf73768f5c293d3ae47b9ceb8529349f4fe430 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Fri, 29 Sep 2023 17:25:45 +0100 Subject: [PATCH 185/538] Enable nit-picky mode in ``conf.py`` (#1170) --- Makefile | 2 +- conf.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 17141ac2d..6e25d9389 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ PYTHON = python3 VENVDIR = ./venv BUILDDIR = _build -SPHINXOPTS = -W --keep-going -n +SPHINXOPTS = -W --keep-going SPHINXBUILD = $(VENVDIR)/bin/sphinx-build SPHINXLINT = $(VENVDIR)/bin/sphinx-lint PAPER = diff --git a/conf.py b/conf.py index 32d46e581..06b4c68a1 100644 --- a/conf.py +++ b/conf.py @@ -32,6 +32,8 @@ '.github', ] +nitpicky = True + html_theme = 'furo' html_theme_options = { From fd1c58ff5c04c7c1c403ceb3ad7cbb9e6ec31a25 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 29 Sep 2023 21:36:07 +0200 Subject: [PATCH 186/538] Clarify that PyUnstable macros use "PyUnstable" prefix (#1158) Discussion: https://github.com/python/cpython/pull/108440#issuecomment-1699105964 --- developer-workflow/c-api.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index 3525cb81f..8097354c3 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -217,6 +217,8 @@ Moving an API from the public tier to Unstable ---------------------------------------------- * Expose the API under its new name, with the ``PyUnstable_`` prefix. + The ``PyUnstable_`` prefix must be used for all symbols (functions, macros, + variables, etc.). * Make the old name an alias (e.g. a ``static inline`` function calling the new function). * Deprecate the old name, typically using :c:macro:`Py_DEPRECATED`. From 7a3e94ca9770dcb242f8ce32eb2bde97bf3c73ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 08:51:45 +0300 Subject: [PATCH 187/538] Update sphinx requirement from ~=7.2.5 to ~=7.2.6 (#1172) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 260c90752..2a1e944b6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Sphinx~=7.2.5 +Sphinx~=7.2.6 furo>=2022.6.4 jinja2 sphinx-lint==0.6.8 From 30dfd7c6fe533c8ca5879193d54bc81108c5735a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 19 Aug 2023 10:13:35 +0300 Subject: [PATCH 188/538] python/cpython#107704: Argument Clinic: add support for deprecating keyword use of parameters (python/cpython#107984) It is now possible to deprecate passing keyword arguments for keyword-or-positional parameters with Argument Clinic, using the new '/ [from X.Y]' syntax. (To be read as "positional-only from Python version X.Y") Co-authored-by: Erlend E. Aasland Co-authored-by: Alex Waygood --- development-tools/clinic.rst | 65 ++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index c03f4e9b3..28fe4b6e3 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -1935,54 +1935,70 @@ The generated docstring ends up looking like this: .. _clinic-howto-deprecate-positional: +.. _clinic-howto-deprecate-keyword: -How to deprecate passing parameters positionally ------------------------------------------------- +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 ` positionally. +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 three :term:`parameters `: -positional-or-keyword parameters *a* and *b*, and a keyword-only parameter *c*:: +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 keyword-only; -however, we'll have to wait two releases before making this change, +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 the *b* parameter is passed positionally, -and we'll be allowed to make it keyword-only in Python 3.14 at the earliest. +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 above the *b* parameter:: +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 - * [from 3.14] + / 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` *b* is passed positionally. +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 ...]`` line has not been removed +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. @@ -1995,21 +2011,26 @@ 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 parameter(s) 'a' and 'b' in the clinic input of 'mymod.myfunc' to be keyword-only. [-W#warnings] - # warning "In 'foomodule.c', update parameter(s) 'a' and 'b' in the clinic input of 'mymod.myfunc' to be keyword-only. [-W#warnings]" + 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 *b* keyword-only; -replace the ``* [from ...]`` line above *b* -with the ``*`` from the line above *c*:: +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, From 01280182632b0a2fdb72b0d1eb7edfd4fbe1e90a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 30 Aug 2023 16:02:48 +0200 Subject: [PATCH 189/538] python/cpython#108494: Argument Clinic: Document how to generate code that uses the limited C API (python/cpython#108584) Co-authored-by: Alex Waygood Co-authored-by: Erlend E. Aasland --- development-tools/clinic.rst | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index 28fe4b6e3..eade2b990 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -152,7 +152,7 @@ process a single source file, like this: The CLI supports the following options: .. program:: ./Tools/clinic/clinic.py [-h] [-f] [-o OUTPUT] [-v] \ - [--converters] [--make] [--srcdir SRCDIR] [FILE ...] + [--converters] [--make] [--srcdir SRCDIR] [--limited] [FILE ...] .. option:: -h, --help @@ -187,6 +187,11 @@ The CLI supports the following options: A file to exclude in :option:`--make` mode. This option can be given multiple times. +.. option:: --limited + + Use the :ref:`Limited API ` to parse arguments in the generated C code. + See :ref:`clinic-howto-limited-capi`. + .. option:: FILE ... The list of files to process. @@ -1899,6 +1904,22 @@ blocks embedded in Python files look slightly different. They look like this: #/*[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 From d8d11a0c8b5a3748910a02018d07bffa3640666c Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 1 Oct 2023 17:06:33 -0400 Subject: [PATCH 190/538] Remove mention of fullcoverage (#1173) It stopped working and was removed from CPython builds in https://github.com/python/cpython/issues/88054 Coverage.py will be removing the code soon. --- testing/coverage.rst | 38 +------------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/testing/coverage.rst b/testing/coverage.rst index a28fb06db..ebd28b677 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -193,43 +193,6 @@ This will lead to the report stating not only what lines were not covered, but also what branch paths were not executed. -Coverage results for modules imported early on -'''''''''''''''''''''''''''''''''''''''''''''' - -For the *truly truly* daring, you can use a hack to get coverage.py to include -coverage for modules that are imported early on during CPython's startup (e.g. -the encodings module). Do not worry if you can't get this to work or it doesn't -make any sense; it's entirely optional and only important for a small number of -modules. - -If you still choose to try this, the first step is to make sure coverage.py's -C extension is installed. You can check this with:: - - ./python COVERAGEDIR --version - -If it says 'without C extension', then you will need to build the C extension. -Assuming that coverage.py's clone is at ``COVERAGEDIR`` and your clone of CPython -is at ``CPYTHONDIR``, you can do this by executing the following in your coverage.py -clone:: - - CPPFLAGS="-I CPYTHONDIR -I CPYTHONDIR/Include" CPYTHONDIR/python setup.py build_ext --inplace - -This will build coverage.py's C extension code in-place, allowing the previous -instructions on how to gather coverage to continue to work. - -To get coverage.py to be able to gather the most accurate coverage data on as -many modules as possible -**with a HORRIBLE HACK that you should NEVER use in your own code**, run the -following from your CPython clone:: - - PYTHONPATH=COVERAGEDIR/coverage/fullcoverage ./python COVERAGEDIR run --pylib Lib/test/regrtest.py - -This will give you the most complete coverage possible for CPython's standard -library. - -.. _coverage.py: https://coverage.readthedocs.io/en/latest/ - - .. _coverage_by_regrtest: Using test.regrtest @@ -293,3 +256,4 @@ about 20 to 30 minutes on a modern computer. .. _issue tracker: https://github.com/python/cpython/issues .. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html .. _lcov: https://ltp.sourceforge.net/coverage/lcov.php +.. _coverage.py: https://coverage.readthedocs.io/en/latest/ From 323f9cf9438730fb64ed71b40a3cb343b6724841 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Mon, 2 Oct 2023 16:59:05 +0100 Subject: [PATCH 191/538] Latest and greatest (3.12.0) (#1174) --- 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 38c0fd2ba..79a4ce6cc 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -10,7 +10,7 @@ "3.12": { "branch": "3.12", "pep": 693, - "status": "prerelease", + "status": "stable", "first_release": "2023-10-02", "end_of_life": "2028-10", "release_manager": "Thomas Wouters" From 8de1731b4954eacde52e29a32e2edab1d04e41c0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 2 Oct 2023 13:04:24 -0600 Subject: [PATCH 192/538] Python 3.12 is now in bugfix (#1175) --- 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 79a4ce6cc..8acf9b4c1 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -10,7 +10,7 @@ "3.12": { "branch": "3.12", "pep": 693, - "status": "stable", + "status": "bugfix", "first_release": "2023-10-02", "end_of_life": "2028-10", "release_manager": "Thomas Wouters" From e6b4ed1fa1e9ff1430510dc20bd36b9bcc8bbd67 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 3 Oct 2023 11:32:35 -0600 Subject: [PATCH 193/538] Avoid the deprecated .. cmdoption:: directive (#1176) --- documentation/markup.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index 0a0d51a63..ade1df3a7 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -575,12 +575,12 @@ The directives are: Describes a Python :term:`bytecode` instruction. -.. describe:: cmdoption +.. describe:: option Describes a Python command line option or switch. Option argument names should be enclosed in angle brackets. Example:: - .. cmdoption:: -m + .. option:: -m Run a module as a script. From c5d1b7cf218f1c3b175a6795a3bf4eb1a7a46745 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Fri, 6 Oct 2023 06:14:56 -0500 Subject: [PATCH 194/538] Note when to backport changes (#1169) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Hugo van Kemenade --- developer-workflow/development-cycle.rst | 8 +++++++- versions.rst | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 935f26653..613af736b 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -77,11 +77,17 @@ releases; the terms are used interchangeably. These releases have a **micro version** number greater than zero. The only changes allowed to occur in a maintenance branch without debate are -bug fixes. Also, a general rule for maintenance branches is that compatibility +bug fixes, test improvements, and edits to the documentation. +Also, a general rule for maintenance branches is that compatibility must not be broken at any point between sibling micro releases (3.5.1, 3.5.2, etc.). For both rules, only rare exceptions are accepted and **must** be discussed first. +Backporting changes reduces the risk of future conflicts. +For documentation, it increases the visibility of improvements, +since most readers access the `stable documentation `__ +rather than the `development documentation `__. + A new maintenance branch is normally created when the next feature release cycle reaches feature freeze, i.e. at its first beta pre-release. From that point on, changes intended for remaining pre-releases, the final diff --git a/versions.rst b/versions.rst index b712dfc6e..6ca0d440d 100644 --- a/versions.rst +++ b/versions.rst @@ -50,7 +50,7 @@ Status key but new source-only versions can be released :end-of-life: release cycle is frozen; no further changes can be pushed to it. -See also the :ref:`devcycle` page for more information about branches. +See also the :ref:`devcycle` page for more information about branches and backporting. By default, the end-of-life is scheduled 5 years after the first release, but can be adjusted by the release manager of each branch. All Python 2 From 43fad8f313647e064575f0bef4d57d2d0a966054 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 9 Oct 2023 14:11:03 +0200 Subject: [PATCH 195/538] Replace 'gh pr checkout' with 'gh co' alias (#1182) --- getting-started/git-boot-camp.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 4746de33b..9b8981eb5 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -430,9 +430,9 @@ Scenario: - Before merging it, you want to be able to test their changes locally. If you've got `GitHub CLI `_ or -`hub `_ installed, you can simply do:: +`hub `_ installed, you can do:: - $ gh pr checkout # GitHub CLI + $ gh co # GitHub CLI $ hub pr checkout # hub Both of these tools will configure a remote URL for the branch, so you can @@ -637,7 +637,7 @@ Examples of useful commands: * Check out another PR:: - gh pr checkout + gh co * Set ``ssh`` as the Git protocol:: From 4d3ef3e84486e6f83d1fb346c42c4009e8960dd5 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 9 Oct 2023 14:11:44 +0200 Subject: [PATCH 196/538] gh-1178: Fix indentation in a few more pages (#1181) --- getting-started/pull-request-lifecycle.rst | 10 ++++---- internals/garbage-collector.rst | 30 +++++++++++----------- internals/parser.rst | 9 ++++--- testing/coverage.rst | 2 +- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 3466a4878..7289a921b 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -241,15 +241,15 @@ should do to help ensure that your pull request is accepted. ``patchcheck`` is a simple automated patch checklist that guides a developer through the common patch generation checks. To run ``patchcheck``: - On *Unix* (including macOS):: +On *Unix* (including macOS):: - make patchcheck + make patchcheck - On *Windows* (after any successful build): +On *Windows* (after any successful build): - .. code-block:: dosbatch +.. code-block:: dosbatch - python.bat Tools\patchcheck\patchcheck.py + python.bat Tools\patchcheck\patchcheck.py The automated patch checklist runs through: diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index c2cbf6d72..2dfba0afd 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -131,15 +131,15 @@ class instances, classes in extension modules, etc. One could think that cycles are uncommon but the truth is that many internal references needed by the interpreter create cycles everywhere. Some notable examples: - * Exceptions contain traceback objects that contain a list of frames that - contain the exception itself. - * Module-level functions reference the module's dict (which is needed to resolve globals), - which in turn contains entries for the module-level functions. - * Instances have references to their class which itself references its module, and the module - contains references to everything that is inside (and maybe other modules) - and this can lead back to the original instance. - * When representing data structures like graphs, it is very typical for them to - have internal links to themselves. +* Exceptions contain traceback objects that contain a list of frames that + contain the exception itself. +* Module-level functions reference the module's dict (which is needed to resolve globals), + which in turn contains entries for the module-level functions. +* Instances have references to their class which itself references its module, and the module + contains references to everything that is inside (and maybe other modules) + and this can lead back to the original instance. +* When representing data structures like graphs, it is very typical for them to + have internal links to themselves. To correctly dispose of these objects once they become unreachable, they need to be identified first. Inside the function that identifies cycles, two doubly linked @@ -417,13 +417,13 @@ word-aligned addresses end in ``000``, leaving the last 3 bits available. The CPython GC makes use of two fat pointers that correspond to the extra fields of ``PyGC_Head`` discussed in the `Memory layout and object structure`_ section: - .. warning:: +.. warning:: - Because the presence of extra information, "tagged" or "fat" pointers cannot be - dereferenced directly and the extra information must be stripped off before - obtaining the real memory address. Special care needs to be taken with - functions that directly manipulate the linked lists, as these functions - normally assume the pointers inside the lists are in a consistent state. + Because the presence of extra information, "tagged" or "fat" pointers cannot be + dereferenced directly and the extra information must be stripped off before + obtaining the real memory address. Special care needs to be taken with + functions that directly manipulate the linked lists, as these functions + normally assume the pointers inside the lists are in a consistent state. * The ``_gc_prev`` field is normally used as the "previous" pointer to maintain the diff --git a/internals/parser.rst b/internals/parser.rst index f05d59b4a..d98ce8705 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -890,7 +890,7 @@ To activate verbose mode you can add the ``-d`` flag when executing Python: $ python -d file_to_test.py This will print **a lot** of output to ``stderr`` so is probably better to dump it to a file for further analysis. The output -consists of trace lines with the following structure: +consists of trace lines with the following structure:: ('>'|'-'|'+'|'!') []: ... @@ -902,9 +902,10 @@ character marks the type of the trace: * ``+`` indicates that a rule has been parsed correctly. * ``!`` indicates that an exception or an error has been detected and the parser is unwinding. -The part indicates the current index in the token array, the - part indicates what rule is being parsed and the part -indicates what alternative within that rule is being attempted. +The ```` part indicates the current index in the token array, +the ```` part indicates what rule is being parsed and +the ```` part indicates what alternative within that rule +is being attempted. References diff --git a/testing/coverage.rst b/testing/coverage.rst index ebd28b677..0ebaf4b02 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -111,7 +111,7 @@ long as your venv is activated. For more info on venv see `Virtual Environment 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. -To do this you should clone/check out the development version of coverage.py: +To do this you should clone/check out the development version of coverage.py:: git clone https://github.com/nedbat/coveragepy From c2de3bcabe9328ee3acea45dad9efcce88762ee6 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 9 Oct 2023 14:12:26 +0200 Subject: [PATCH 197/538] gh-1178: Fix indentation in the argument clinic page (#1180) --- development-tools/clinic.rst | 278 +++++++++++++++++------------------ 1 file changed, 139 insertions(+), 139 deletions(-) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index eade2b990..08ba17cbf 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -290,14 +290,14 @@ For this tutorial, we'll be using If the call to the :c:func:`!PyArg_Parse*` function uses any of the following format units...: - .. code-block:: none +.. code-block:: none - O& - O! - es - es# - et - et# + O& + O! + es + es# + et + et# ... or if it has multiple calls to :c:func:`PyArg_ParseTuple`, you should choose a different function. @@ -861,61 +861,61 @@ 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. +*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. +*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. +*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.) +*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. + 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. +*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. +*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. +*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. +*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 *"``. +*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``. +*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` @@ -1643,63 +1643,63 @@ 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``. +``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``: @@ -1721,44 +1721,44 @@ This creates a new destination with name ```` and type ````. There are five destination types: - ``suppress`` - Throws the text away. +``suppress`` + Throws the text away. - ``block`` - Writes the text to the current block. This is what Clinic - originally did. +``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. +``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: +``file`` + A text file. The file destination takes an extra argument, + a template to use for building the filename, like so:: - destination new + destination new - The template can use three strings internally that will be replaced - by bits of the filename: + 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. + ``{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}"." + 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. +``two-pass`` + A two-pass buffer, like the "two-pass" builtin destination above. The ``clear`` subcommand works like this: @@ -1784,11 +1784,11 @@ The fourth new directive is ``set``: Both of these support two format strings: - ``{block comment start}`` - Turns into the string ``/*``, the start-comment text sequence for C files. +``{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. +``{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``: From 40e97a8b25ff19cf87470844b2600f6df37e42a5 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 9 Oct 2023 14:12:58 +0200 Subject: [PATCH 198/538] gh-1178: Fix indentation in the buildbot page (#1179) --- testing/new-buildbot-worker.rst | 196 ++++++++++++++++---------------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index 01692fa31..cbe039064 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -70,28 +70,28 @@ if you choose that path. For Linux: - * If your package manager provides the buildbot worker software, that is - probably the best way to install it; it may create the buildbot user for - you, in which case you can skip that step. Otherwise, do ``pip install - buildbot-worker``. - * Create a ``buildbot`` user (using, eg: ``useradd``) if necessary. - * Log in as the buildbot user. +* If your package manager provides the buildbot worker software, that is + probably the best way to install it; it may create the buildbot user for + you, in which case you can skip that step. Otherwise, do ``pip install + buildbot-worker``. +* Create a ``buildbot`` user (using, eg: ``useradd``) if necessary. +* Log in as the buildbot user. For Mac: - * Create a buildbot user using the OS/X control panel user admin. It - should be a "standard" user. - * Log in as the buildbot user. - * Install the buildbot worker [#]_ by running ``pip install buildbot-worker``. +* Create a buildbot user using the OS/X control panel user admin. It + should be a "standard" user. +* Log in as the buildbot user. +* Install the buildbot worker [#]_ by running ``pip install buildbot-worker``. For Windows: - * Create a buildbot user as a "standard" user. - * Install the latest version of Python from python.org. - * Open a Command Prompt. - * Execute ``python -m pip install pypiwin32 buildbot-worker`` (note that - ``python.exe`` is not added to ``PATH`` by default, making the - ``python`` command accessible is left as an exercise for the user). +* Create a buildbot user as a "standard" user. +* Install the latest version of Python from python.org. +* Open a Command Prompt. +* Execute ``python -m pip install pypiwin32 buildbot-worker`` (note that + ``python.exe`` is not added to ``PATH`` by default, making the + ``python`` command accessible is left as an exercise for the user). In a terminal window for the buildbot user, issue the following commands (you can put the ``buildarea`` wherever you want to):: @@ -113,73 +113,73 @@ machine reboots: For Linux: - * Add the following line to ``/etc/crontab``:: +* Add the following line to ``/etc/crontab``:: - @reboot buildbot-worker restart /path/to/buildarea + @reboot buildbot-worker restart /path/to/buildarea - Note that we use ``restart`` rather than ``start`` in case a crash has - left a ``twistd.pid`` file behind. + Note that we use ``restart`` rather than ``start`` in case a crash has + left a ``twistd.pid`` file behind. For OSX: - * Create a bin directory for your buildbot user:: - - mkdir bin - - * Place the following script, named ``run_worker.sh``, into that directory:: - - #!/bin/bash - export PATH=/usr/local/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:$PATH - export LC_CTYPE=en_US.utf-8 - cd /Users/buildbot/buildarea - twistd --nodaemon --python=buildbot.tac --logfile=buildbot.log --prefix=worker - - If you use pip with Apple's system python, add '/System' to the front of - the path to the Python bin directory. - - * Place a file with the following contents into ``/Library/LaunchDaemons``: - - .. code-block:: xml - - - - - - Label - net.buildbot.worker - UserName - buildbot - WorkingDirectory - /Users/buildbot/buildarea - ProgramArguments - - /Users/buildbot/bin/run_worker.sh - - StandardOutPath - twistd.log - StandardErrorPath - twistd.log - KeepAlive - - SessionCreate - - - - - The recommended name for the file is ``net.buildbot.worker``. +* Create a bin directory for your buildbot user:: + + mkdir bin + +* Place the following script, named ``run_worker.sh``, into that directory:: + + #!/bin/bash + export PATH=/usr/local/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:$PATH + export LC_CTYPE=en_US.utf-8 + cd /Users/buildbot/buildarea + twistd --nodaemon --python=buildbot.tac --logfile=buildbot.log --prefix=worker + + If you use pip with Apple's system python, add '/System' to the front of + the path to the Python bin directory. + +* Place a file with the following contents into ``/Library/LaunchDaemons``: + + .. code-block:: xml + + + + + + Label + net.buildbot.worker + UserName + buildbot + WorkingDirectory + /Users/buildbot/buildarea + ProgramArguments + + /Users/buildbot/bin/run_worker.sh + + StandardOutPath + twistd.log + StandardErrorPath + twistd.log + KeepAlive + + SessionCreate + + + + + The recommended name for the file is ``net.buildbot.worker``. For Windows: - * Add a Scheduled Task to run ``buildbot-worker start buildarea`` as the - buildbot user "when the computer starts up". It is best to provide - absolute paths to the ``buildbot-worker`` command and the :file:`buildarea` - directory. It is also recommended to set the task to run in the - directory that contains the :file:`buildarea` directory. +* Add a Scheduled Task to run ``buildbot-worker start buildarea`` as the + buildbot user "when the computer starts up". It is best to provide + absolute paths to the ``buildbot-worker`` command and the :file:`buildarea` + directory. It is also recommended to set the task to run in the + directory that contains the :file:`buildarea` directory. - * Alternatively (note: don't do both!), set up the worker - service as described in the `buildbot documentation - `_. +* 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:: @@ -203,20 +203,20 @@ 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 - conventional worker. - * After the instance is fully set up as a conventional worker (including - worker name and password, and admin and host information), create an AMI - from the instance and stop the instance. - * Contact the buildmaster administrator who gave you your worker - name and password and give them the following information: - - * Instance size (such as ``m4.large``) - * Full region specification (such as ``us-west-2``) - * AMI ID (such as ``ami-1234beef``) - * An Access Key ID and Access Key. It is recommended to set up - a separate IAM user with full access to EC2 and provide the access key - information for that user rather than for your main account. +* Start an instance of your chosen base AMI and set it up as a + conventional worker. +* After the instance is fully set up as a conventional worker (including + worker name and password, and admin and host information), create an AMI + from the instance and stop the instance. +* Contact the buildmaster administrator who gave you your worker + name and password and give them the following information: + + * Instance size (such as ``m4.large``) + * Full region specification (such as ``us-west-2``) + * AMI ID (such as ``ami-1234beef``) + * An Access Key ID and Access Key. It is recommended to set up + a separate IAM user with full access to EC2 and provide the access key + information for that user rather than for your main account. The buildmaster cannot guarantee that it will always shut down your instance(s), so it is recommended to periodically check and make sure @@ -231,13 +231,13 @@ or other software updates, but when to do such maintenance is largely up to you as the worker owner. There are a couple different options for doing such updates: - * Start an instance from your existing AMI, do updates on that instance, - and save a new AMI from the updated instance. Note that (especially for - Windows workers) you should do at least one restart of the instance after - doing updates to be sure that any post-reboot update work is done before - creating the new AMI. - * Create an entirely new setup from a newer base AMI using your existing - worker name and password. +* Start an instance from your existing AMI, do updates on that instance, + and save a new AMI from the updated instance. Note that (especially for + Windows workers) you should do at least one restart of the instance after + doing updates to be sure that any post-reboot update work is done before + creating the new AMI. +* Create an entirely new setup from a newer base AMI using your existing + worker name and password. Whichever way you choose to update your AMI, you'll need to provide the buildmaster administrators with the new AMI ID. @@ -312,9 +312,9 @@ Based on the last time we did a `survey buildbot requirements, the recommended resource allocations for a python buildbot are at least: - * 2 CPUs - * 512 MB RAM - * 30 GB free disk space +* 2 CPUs +* 512 MB RAM +* 30 GB free disk space The bigmem tests won't run in this configuration, since they require substantially more memory, but these resources should be sufficient to ensure From 25eb16f1776ea68c5f029b2b0b8a3e9c291e8b4d Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Tue, 10 Oct 2023 10:55:34 +0200 Subject: [PATCH 199/538] Fix wrongly indented nested list in `compiler.rst` (#1183) --- internals/compiler.rst | 143 +++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 69 deletions(-) diff --git a/internals/compiler.rst b/internals/compiler.rst index d7853456d..775540f54 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -511,107 +511,112 @@ Important files =============== * :cpy-file:`Parser/` - * :cpy-file:`Parser/Python.asdl`: ASDL syntax file. - * :cpy-file:`Parser/asdl.py`: Parser for ASDL definition files. - Reads in an ASDL description and parses it into an AST that describes it. + * :cpy-file:`Parser/Python.asdl`: ASDL syntax file. - * :cpy-file:`Parser/asdl_c.py`: Generate C code from an ASDL description. - Generates :cpy-file:`Python/Python-ast.c` and - :cpy-file:`Include/internal/pycore_ast.h`. + * :cpy-file:`Parser/asdl.py`: Parser for ASDL definition files. + Reads in an ASDL description and parses it into an AST that describes it. - * :cpy-file:`Parser/parser.c`: The new PEG parser introduced in Python 3.9. - Generated by :cpy-file:`Tools/peg_generator/pegen/c_generator.py` - from the grammar :cpy-file:`Grammar/python.gram`. Creates the AST from - source code. Rule functions for their corresponding production rules - are found here. + * :cpy-file:`Parser/asdl_c.py`: Generate C code from an ASDL description. + Generates :cpy-file:`Python/Python-ast.c` and + :cpy-file:`Include/internal/pycore_ast.h`. - * :cpy-file:`Parser/peg_api.c`: Contains high-level functions which are - used by the interpreter to create an AST from source code. + * :cpy-file:`Parser/parser.c`: The new PEG parser introduced in Python 3.9. + Generated by :cpy-file:`Tools/peg_generator/pegen/c_generator.py` + from the grammar :cpy-file:`Grammar/python.gram`. Creates the AST from + source code. Rule functions for their corresponding production rules + are found here. - * :cpy-file:`Parser/pegen.c`: Contains helper functions which are used - by functions in :cpy-file:`Parser/parser.c` to construct the AST. - Also contains helper functions which help raise better error messages - when parsing source code. + * :cpy-file:`Parser/peg_api.c`: Contains high-level functions which are + used by the interpreter to create an AST from source code. - * :cpy-file:`Parser/pegen.h`: Header file for the corresponding - :cpy-file:`Parser/pegen.c`. Also contains definitions of the ``Parser`` - and ``Token`` structs. + * :cpy-file:`Parser/pegen.c`: Contains helper functions which are used + by functions in :cpy-file:`Parser/parser.c` to construct the AST. + Also contains helper functions which help raise better error messages + when parsing source code. + + * :cpy-file:`Parser/pegen.h`: Header file for the corresponding + :cpy-file:`Parser/pegen.c`. Also contains definitions of the ``Parser`` + and ``Token`` structs. * :cpy-file:`Python/` - * :cpy-file:`Python/Python-ast.c`: Creates C structs corresponding to - the ASDL types. Also contains code for marshalling AST nodes (core - ASDL types have marshalling code in :cpy-file:`Python/asdl.c`). - "File automatically generated by :cpy-file:`Parser/asdl_c.py`". - This file must be committed separately after every grammar change - is committed since the ``__version__`` value is set to the latest - grammar change revision number. - * :cpy-file:`Python/asdl.c`: Contains code to handle the ASDL sequence type. - Also has code to handle marshalling the core ASDL types, such as number - and identifier. Used by :cpy-file:`Python/Python-ast.c` for marshalling - AST nodes. + * :cpy-file:`Python/Python-ast.c`: Creates C structs corresponding to + the ASDL types. Also contains code for marshalling AST nodes (core + ASDL types have marshalling code in :cpy-file:`Python/asdl.c`). + "File automatically generated by :cpy-file:`Parser/asdl_c.py`". + This file must be committed separately after every grammar change + is committed since the ``__version__`` value is set to the latest + grammar change revision number. + + * :cpy-file:`Python/asdl.c`: Contains code to handle the ASDL sequence type. + Also has code to handle marshalling the core ASDL types, such as number + and identifier. Used by :cpy-file:`Python/Python-ast.c` for marshalling + AST nodes. - * :cpy-file:`Python/ast.c`: Used for validating the AST. + * :cpy-file:`Python/ast.c`: Used for validating the AST. - * :cpy-file:`Python/ast_opt.c`: Optimizes the AST. + * :cpy-file:`Python/ast_opt.c`: Optimizes the AST. - * :cpy-file:`Python/ast_unparse.c`: Converts the AST expression node - back into a string (for string annotations). + * :cpy-file:`Python/ast_unparse.c`: Converts the AST expression node + back into a string (for string annotations). - * :cpy-file:`Python/ceval.c`: Executes byte code (aka, eval loop). + * :cpy-file:`Python/ceval.c`: Executes byte code (aka, eval loop). - * :cpy-file:`Python/compile.c`: Emits bytecode based on the AST. + * :cpy-file:`Python/compile.c`: Emits bytecode based on the AST. - * :cpy-file:`Python/symtable.c`: Generates a symbol table from AST. + * :cpy-file:`Python/symtable.c`: Generates a symbol table from AST. - * :cpy-file:`Python/pyarena.c`: Implementation of the arena memory manager. + * :cpy-file:`Python/pyarena.c`: Implementation of the arena memory manager. - * :cpy-file:`Python/opcode_targets.h`: One of the files that must be - modified if :cpy-file:`Lib/opcode.py` is. + * :cpy-file:`Python/opcode_targets.h`: One of the files that must be + modified if :cpy-file:`Lib/opcode.py` is. * :cpy-file:`Include/` - * :cpy-file:`Include/cpython/code.h`: Header file for - :cpy-file:`Objects/codeobject.c`; contains definition of ``PyCodeObject``. - * :cpy-file:`Include/opcode.h`: One of the files that must be modified if - :cpy-file:`Lib/opcode.py` is. + * :cpy-file:`Include/cpython/code.h`: Header file for + :cpy-file:`Objects/codeobject.c`; contains definition of ``PyCodeObject``. + + * :cpy-file:`Include/opcode.h`: One of the files that must be modified if + :cpy-file:`Lib/opcode.py` is. - * :cpy-file:`Include/internal/pycore_ast.h`: Contains the actual definitions - of the C structs as generated by :cpy-file:`Python/Python-ast.c`. - "Automatically generated by :cpy-file:`Parser/asdl_c.py`". + * :cpy-file:`Include/internal/pycore_ast.h`: Contains the actual definitions + of the C structs as generated by :cpy-file:`Python/Python-ast.c`. + "Automatically generated by :cpy-file:`Parser/asdl_c.py`". - * :cpy-file:`Include/internal/pycore_asdl.h`: Header for the corresponding - :cpy-file:`Python/ast.c`. + * :cpy-file:`Include/internal/pycore_asdl.h`: Header for the corresponding + :cpy-file:`Python/ast.c`. - * :cpy-file:`Include/internal/pycore_ast.h`: Declares ``_PyAST_Validate()`` - external (from :cpy-file:`Python/ast.c`). + * :cpy-file:`Include/internal/pycore_ast.h`: Declares ``_PyAST_Validate()`` + external (from :cpy-file:`Python/ast.c`). - * :cpy-file:`Include/internal/pycore_symtable.h`: Header for - :cpy-file:`Python/symtable.c`. ``struct symtable`` and ``PySTEntryObject`` - are defined here. + * :cpy-file:`Include/internal/pycore_symtable.h`: Header for + :cpy-file:`Python/symtable.c`. ``struct symtable`` and ``PySTEntryObject`` + are defined here. - * :cpy-file:`Include/internal/pycore_parser.h`: Header for the - corresponding :cpy-file:`Parser/peg_api.c`. + * :cpy-file:`Include/internal/pycore_parser.h`: Header for the + corresponding :cpy-file:`Parser/peg_api.c`. - * :cpy-file:`Include/internal/pycore_pyarena.h`: Header file for the - corresponding :cpy-file:`Python/pyarena.c`. + * :cpy-file:`Include/internal/pycore_pyarena.h`: Header file for the + corresponding :cpy-file:`Python/pyarena.c`. * :cpy-file:`Objects/` - * :cpy-file:`Objects/codeobject.c`: Contains PyCodeObject-related code - (originally in :cpy-file:`Python/compile.c`). - * :cpy-file:`Objects/frameobject.c`: Contains the ``frame_setlineno()`` - function which should determine whether it is allowed to make a jump - between two points in a bytecode. + * :cpy-file:`Objects/codeobject.c`: Contains PyCodeObject-related code + (originally in :cpy-file:`Python/compile.c`). + + * :cpy-file:`Objects/frameobject.c`: Contains the ``frame_setlineno()`` + function which should determine whether it is allowed to make a jump + between two points in a bytecode. * :cpy-file:`Lib/` - * :cpy-file:`Lib/opcode.py`: Master list of bytecode; if this file is - modified you must modify several other files accordingly - (see "`Introducing New Bytecode`_") - * :cpy-file:`Lib/importlib/_bootstrap_external.py`: Home of the magic number - (named ``MAGIC_NUMBER``) for bytecode versioning. + * :cpy-file:`Lib/opcode.py`: Master list of bytecode; if this file is + modified you must modify several other files accordingly + (see "`Introducing New Bytecode`_") + + * :cpy-file:`Lib/importlib/_bootstrap_external.py`: Home of the magic number + (named ``MAGIC_NUMBER``) for bytecode versioning. Known compiler-related experiments From 862e98dfe59c2c81b0aec09b6ac3d0f5495db403 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Tue, 10 Oct 2023 17:10:28 +0200 Subject: [PATCH 200/538] Fix wrongly indented nested list. (#1184) --- index.rst | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/index.rst b/index.rst index 20bc228b0..c4450e1e0 100644 --- a/index.rst +++ b/index.rst @@ -180,14 +180,20 @@ Key resources ------------- * Coding style guides - * :PEP:`7` (Style Guide for C Code) - * :PEP:`8` (Style Guide for Python Code) + + * :PEP:`7` (Style Guide for C Code) + * :PEP:`8` (Style Guide for Python Code) + * `Issue tracker`_ - * :ref:`experts` + + * :ref:`experts` + * `Buildbot status`_ * Source code - * `Browse online `_ - * `Snapshot of the *main* branch `_ + + * `Browse online `_ + * `Snapshot of the *main* branch `_ + * PEPs_ (Python Enhancement Proposals) * :ref:`help` * :ref:`developers` @@ -198,22 +204,24 @@ Key resources Additional resources -------------------- -* Anyone can clone the sources for this guide. See - :ref:`devguide`. +* Anyone can clone the sources for this guide. See :ref:`devguide`. * Help with ... - * :ref:`exploring` - * :ref:`grammar` - * :ref:`parser` - * :ref:`compiler` - * :ref:`garbage_collector` + + * :ref:`exploring` + * :ref:`grammar` + * :ref:`parser` + * :ref:`compiler` + * :ref:`garbage_collector` + * Tool support - * :ref:`gdb` - * :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 `_ -* `python.org maintenance`_ + * :ref:`gdb` + * :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 `_ + +* `python.org maintenance`_ * :ref:`Search this guide ` From 6861814b478d4d1a23afe735a57290714bcb234b Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Wed, 11 Oct 2023 15:33:32 +1000 Subject: [PATCH 201/538] Update details for Alyssa Coghlan (#1185) --- core-developers/developers.csv | 2 +- core-developers/motivations.rst | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index a0635a8b3..70b349bfe 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -121,7 +121,7 @@ Steven Bethard,,2006-04-27,2017-02-10,For PEP access and SourceForge maintenance Gerhard Häring,,2006-04-23,2017-02-10,Did not make the GitHub transition George Yoshida,,2006-04-17,2017-02-10,For tracker administration; did not make GitHub transition Ronald Oussoren,ronaldoussoren,2006-03-03,,For Mac-related work -Nick Coghlan,ncoghlan,2005-10-16,, +Alyssa Coghlan,ncoghlan,2005-10-16,,also contributed as Nick Coghlan (prior to 2023-08-04) Georg Brandl,birkenfeld,2005-05-28,, Terry Jan Reedy,terryjreedy,2005-04-07,, Bob Ippolito,etrepum,2005-03-02,2017-02-10,For Mac-related work diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index a15490891..164bdcb64 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -101,21 +101,23 @@ participating in the CPython core development process: * Microsoft (Software Developer) * Python Software Foundation (Fellow) -.. topic:: Nick Coghlan (Australia) +.. topic:: Alyssa Coghlan (Australia) * Personal site: `Curious Efficiency `_ * `Extended bio `__ - * `Tritium `__ (Software Developer) * Python Software Foundation (Fellow, Packaging Working Group) - Nick began using Python as a testing and prototyping language while working + Alyssa began using Python as a testing and prototyping language while working for Boeing Defence Australia, and continues to use it for that purpose today. - As a core developer, he is primarily interested in helping to ensure Python's + As a core developer, she is primarily interested in helping to ensure Python's continued suitability for educational, testing and data analysis use cases, as well as in encouraging good architectural practices when assembling Python applications and test harnesses from open source components. + Note: prior to August 2023, Alyssa used her birth name (Nick Coghlan). Some records + (e.g. mailing list archives, version control history) will still reference that name. + .. topic:: Steve Dower (United States/Australia) * Microsoft (Software Developer) From 941598dc1446963b40ba5e4f3d10bd8028f46a55 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Wed, 11 Oct 2023 11:56:04 +0200 Subject: [PATCH 202/538] Clarify close as not planned for triage (#1186) --- triage/triaging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triage/triaging.rst b/triage/triaging.rst index 6ad96eeff..89919450d 100644 --- a/triage/triaging.rst +++ b/triage/triaging.rst @@ -22,7 +22,7 @@ Checklist for triaging * You might also leave a brief comment about the proposed next action needed. If there is a long message list, a summary can be very helpful. * If the issue is clearly invalid (unrelated to CPython, duplicate, spam, etc), - you can close it as "not planned". + you can use GitHub's "Close as not planned" option. Assignees --------- From 147f1576130acc9e34c62a24e1355c96305640c1 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Wed, 11 Oct 2023 17:44:51 +0200 Subject: [PATCH 203/538] Fix wrong indentation in nested list. (#1189) --- triage/triage-team.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/triage/triage-team.rst b/triage/triage-team.rst index a3e703595..6255ea429 100644 --- a/triage/triage-team.rst +++ b/triage/triage-team.rst @@ -35,9 +35,10 @@ following: * PRs proposing solely cosmetic changes * PRs proposing changes to deprecated modules * PRs that are no longer relevant. This includes: - - PRs proposing fixes for bugs that can no longer be reproduced - - PRs proposing changes that have been rejected by Python core developers - elsewhere (e.g. in an issue or a PEP rejection notice) + + - PRs proposing fixes for bugs that can no longer be reproduced + - PRs proposing changes that have been rejected by Python core developers + elsewhere (e.g. in an issue or a PEP rejection notice) If a triager has any doubt about whether to close a PR, they should consult a core developer before taking any action. From 642fc4335ae6e48b1f71e26ecbaf15a526f3fa2e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 13 Oct 2023 10:13:55 +0200 Subject: [PATCH 204/538] Update checklist: remove new core devs from triage team (#1191) * Update checklist: remove new core devs from triage team * Punctuate list full sentences * Link to Committers Discourse category * Improve wording Co-authored-by: Ezio Melotti * Update core-developers/become-core-developer.rst Co-authored-by: Hugo van Kemenade --------- Co-authored-by: Ezio Melotti Co-authored-by: Carol Willing --- core-developers/become-core-developer.rst | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index 057ef509b..a0b2a1053 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -31,8 +31,8 @@ are granted through these steps: #. A core developer (submitter, usually the mentor) starts a poll in the `Committers category`_ on the `Python Discourse`_. - - Open for 7 days - - Results shown upon close + - open for 7 days + - results shown upon close #. If the candidate receives at least two-thirds positive votes when the poll closes (as per :pep:`13`), the submitter `emails the steering council @@ -43,18 +43,19 @@ are granted through these steps: (approver) 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 + to the PSF Conduct WG. #. Once the candidate has provided the pertinent details, the approver will: - - enable the various new privileges; - - add the new committer's details to - `🔒 python/voters `_; - - update the devguide to publicly list the new committer's team membership - at :ref:`developers`; - - send an announcement email to the Committers Discourse category. + - 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`. + - Send an announcement email to the `Committers Discourse category + `_. .. _Code of Conduct: https://www.python.org/psf/conduct/ .. _Committers category: https://discuss.python.org/c/committers/5 From 74e016547c4b8934a615e51b606548a8cd75b538 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Fri, 13 Oct 2023 10:33:33 +0200 Subject: [PATCH 205/538] Add recommended locales to the testing document (#1187) * Add recommended locales to the testing document * Apply Ezio's review suggestion Co-authored-by: Ezio Melotti * Add reference to locale command for linux/mac --------- Co-authored-by: Ezio Melotti --- testing/run-write-tests.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/testing/run-write-tests.rst b/testing/run-write-tests.rst index 14ef0c686..7efe8307b 100644 --- a/testing/run-write-tests.rst +++ b/testing/run-write-tests.rst @@ -96,6 +96,25 @@ CPython checkout. The script tries to balance speed with thoroughness. But if you want the most thorough tests you should use the strenuous approach shown above. +Locale support +-------------- + +Some tests require specific locales to run successfully. These locales are +often non-default, non-English, non-UTF-8 locales. If a necessary locale is +unavailable, the test is skipped or runs in the dry-run mode. +Additional locales that you may find helpful to set up on developer's machines +or buildbots include: + +* ``en_US`` (``en_US.utf8``, ``en_US.iso88591``) --- the standard default +* ``de_DE`` (``de_DE.UTF-8``) or ``fr_FR`` (``fr_FR.utf8``, ``fr_FR.iso88591``, + ``fr_FR.iso885915@euro``) --- common non-English locales +* ``tr_TR`` (``tr_TR.iso88599``) --- Turkish has different rules for upper/lower + cases of "i" and "I". +* ``ps_AF`` --- used in ``test_decimal`` + +On Linux and macOS, the ``locale`` command can be used to list available +locales and change the settings. Environment variables ``LANG`` and those +prefixed with ``LC_`` can be used to set the locale. Unexpected skips ---------------- From 58e646e86b73cc7f65cea152aa988352cc33bfdc Mon Sep 17 00:00:00 2001 From: Lincoln <71312724+Lincoln-developer@users.noreply.github.com> Date: Fri, 13 Oct 2023 11:50:13 +0300 Subject: [PATCH 206/538] Updated internals section of devguide by deleting the "Known Compiler-related Experiments" (#1161) * Updated compiler page by deleting the Introducing New Bytecode * Updated internals section of devguide by deleting Known Compiler-related Experiments * Removed Introducing New Byte Code section from compiler page * Removed Known compiler-related experiments section from compiler page * Removed unrecognized Bytecode references from compiler page * Update internals/compiler.rst * Update internals/compiler.rst --------- Co-authored-by: Carol Willing --- internals/compiler.rst | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/internals/compiler.rst b/internals/compiler.rst index 775540f54..97810b3d2 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -619,26 +619,6 @@ Important files (named ``MAGIC_NUMBER``) for bytecode versioning. -Known compiler-related experiments -================================== - -This section lists known experiments involving the compiler (including -bytecode). - -Skip Montanaro presented a paper at a Python workshop on a peephole optimizer -[#skip-peephole]_. - -Michael Hudson has a non-active SourceForge project named Bytecodehacks -[#Bytecodehacks]_ that provides functionality for playing with bytecode -directly. - -An opcode to combine the functionality of ``LOAD_ATTR``/``CALL_FUNCTION`` was -created named ``CALL_ATTR`` [#CALL_ATTR]_. Currently only works for classic -classes and for new-style classes rough benchmarking showed an actual slowdown -thanks to having to support both classic and new-style classes. - - - References ========== @@ -649,12 +629,3 @@ References .. _The Zephyr Abstract Syntax Description Language.: https://www.cs.princeton.edu/research/techreps/TR-554-97 - -.. [#skip-peephole] Skip Montanaro's Peephole Optimizer Paper - (https://legacy.python.org/workshops/1998-11/proceedings/papers/montanaro/montanaro.html) - -.. [#Bytecodehacks] Bytecodehacks Project - (https://bytecodehacks.sourceforge.net/bch-docs/bch/index.html) - -.. [#CALL_ATTR] CALL_ATTR opcode - (https://bugs.python.org/issue709744) From 8c5d4cde01c581a624292a02fe9ed179caa0d174 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Fri, 13 Oct 2023 11:54:54 +0200 Subject: [PATCH 207/538] Update internals section index and source code doc (#1192) * Reduce the toctree levels displayed and add an introductory paragraph to index * Simplify code layout doc and add links to CPython docs * Update internals/exploring.rst Co-authored-by: Erlend E. Aasland * Update internals/index.rst Co-authored-by: Erlend E. Aasland --------- Co-authored-by: Erlend E. Aasland --- internals/exploring.rst | 43 ++++++++++++++++++----------------------- internals/index.rst | 8 +++++++- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/internals/exploring.rst b/internals/exploring.rst index 3a812d1a9..8f4a565fb 100644 --- a/internals/exploring.rst +++ b/internals/exploring.rst @@ -1,61 +1,56 @@ .. _exploring: -======================== -Exploring the internals -======================== +=================== +CPython source code +=================== -This is a quick guide for people who are interested in learning more about -CPython's internals. It provides a summary of the source code structure -and contains references to resources providing a more in-depth view. +This section gives an overview of CPython's code structure and provides +a summary of file locations for modules and built-ins. -CPython source code layout -========================== +Source code layout +================== -This guide gives an overview of CPython's code structure. -It serves as a summary of file locations for modules and builtins. - -For Python modules, the typical layout is: +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 extension-only modules, the typical layout is: +For an :term:`extension module`, the typical layout is: * :file:`Modules/{}module.c` * :file:`Lib/test/test_{}.py` * :file:`Doc/library/{}.rst` -For builtin types, the typical layout is: +For :ref:`bltin-types`, the typical layout is: * :file:`Objects/{}object.c` * :file:`Lib/test/test_{}.py` * :cpy-file:`Doc/library/stdtypes.rst` -For builtin functions, the typical layout is: +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: +Some exceptions to these layouts are: -* builtin type ``int`` is at :cpy-file:`Objects/longobject.c` -* builtin type ``str`` is at :cpy-file:`Objects/unicodeobject.c` -* builtin module ``sys`` is at :cpy-file:`Python/sysmodule.c` -* builtin module ``marshal`` is at :cpy-file:`Python/marshal.c` +* 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 ===================== -For over 20 years the CPython code base has been changing and evolving. -Here's a sample of resources about the architecture of CPython aimed at -building your understanding of both the 2.x and 3.x versions of CPython: - +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: .. csv-table:: **Current references** :header: "Title", "Brief", "Author", "Version" diff --git a/internals/index.rst b/internals/index.rst index 4e9d28c83..999e427b2 100644 --- a/internals/index.rst +++ b/internals/index.rst @@ -2,8 +2,14 @@ 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: 5 + :maxdepth: 3 exploring parser From 3793c45469a9336d6cd6632873eb36384c53e425 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Fri, 13 Oct 2023 12:41:52 +0200 Subject: [PATCH 208/538] Move author to a block at end of document for CPython Internals docs on parser and GC (#1193) * Move author to an admonition block at end of document * Update internals/parser.rst Co-authored-by: Erlend E. Aasland --------- Co-authored-by: Erlend E. Aasland --- internals/garbage-collector.rst | 8 ++++++-- internals/parser.rst | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index 2dfba0afd..d25cfc23e 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -6,8 +6,6 @@ Garbage collector design ======================== -:Author: Pablo Galindo Salgado - .. highlight:: none Abstract @@ -497,3 +495,9 @@ tracking status of the object. False >>> gc.is_tracked({"a": []}) True + + +.. admonition:: Document History + :class: note + + Pablo Galindo Salgado - Original Author diff --git a/internals/parser.rst b/internals/parser.rst index d98ce8705..9e2f21656 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -4,8 +4,6 @@ Guide to the parser =================== -:Author: Pablo Galindo Salgado - .. highlight:: none Abstract @@ -919,3 +917,9 @@ References .. [3] Warth et al. http://web.cs.ucla.edu/~todd/research/pepm08.pdf + + +.. admonition:: Document history + :class: note + + Pablo Galindo Salgado - Original author From df97a7324cc382a8349f359bfbdbbc4cf6b7913f Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Fri, 13 Oct 2023 17:52:57 +0200 Subject: [PATCH 209/538] Updating CPython Internals (#1188) * Move bytecode section out of compiler doc * Edits to compiler sections for readability * Add references for Objects and Specializing Adaptive Interpreter * add description of PEP * Add note for moved section on Introducing New Bytecode * fix space * Update internals/compiler.rst Co-authored-by: Pradyun Gedam * Update internals/compiler.rst Co-authored-by: Pradyun Gedam --------- Co-authored-by: Pradyun Gedam --- internals/compiler.rst | 121 +++++++++++++++----------------------- internals/interpreter.rst | 59 +++++++++++++++++++ 2 files changed, 105 insertions(+), 75 deletions(-) diff --git a/internals/compiler.rst b/internals/compiler.rst index 97810b3d2..5dd949d9d 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -11,33 +11,40 @@ Abstract In CPython, the compilation from source code to bytecode involves several steps: -1. Tokenize the source code (:cpy-file:`Parser/tokenizer.c`) +1. Tokenize the source code (:cpy-file:`Parser/tokenizer.c`). 2. Parse the stream of tokens into an Abstract Syntax Tree - (:cpy-file:`Parser/parser.c`) -3. Transform AST into an instruction sequence (:cpy-file:`Python/compile.c`) -4. Construct a Control Flow Graph and apply optimizations to it (:cpy-file:`Python/flowgraph.c`) -5. Emit bytecode based on the Control Flow Graph (:cpy-file:`Python/assemble.c`) + (:cpy-file:`Parser/parser.c`). +3. Transform AST into an instruction sequence (:cpy-file:`Python/compile.c`). +4. Construct a Control Flow Graph and apply optimizations to it (:cpy-file:`Python/flowgraph.c`). +5. Emit bytecode based on the Control Flow Graph (:cpy-file:`Python/assemble.c`). -The purpose of this document is to outline how these steps of the process work. +This document outlines how these steps of the process work. -This document does not touch on how parsing works beyond what is needed -to explain what is needed for compilation. It is also not exhaustive -in terms of the how the entire system works. You will most likely need -to read some source to have an exact understanding of all details. +This document only describes parsing in enough depth to explain what is needed +for understanding compilation. This document provides a detailed, though not +exhaustive, view of the how the entire system works. You will most likely need +to read some source code to have an exact understanding of all details. Parsing ======= As of Python 3.9, Python's parser is a PEG parser of a somewhat -unusual design (since its input is a stream of tokens rather than a -stream of characters as is more common with PEG parsers). +unusual design. It is unusual in the sense that the parser's input is a stream +of tokens rather than a stream of characters which is more common with PEG +parsers. The grammar file for Python can be found in :cpy-file:`Grammar/python.gram`. The definitions for literal tokens (such as ``:``, numbers, etc.) can be found in :cpy-file:`Grammar/Tokens`. Various C files, including :cpy-file:`Parser/parser.c` are generated from -these (see :ref:`grammar`). +these. + +.. seealso:: + + :ref:`parser` for a detailed description of the parser. + + :ref:`grammar` for a detailed description of the grammar. Abstract syntax trees (AST) @@ -133,9 +140,9 @@ Memory management ================= Before discussing the actual implementation of the compiler, a discussion of -how memory is handled is in order. To make memory management simple, an arena -is used. This means that a memory is pooled in a single location for easy -allocation and removal. What this gives us is the removal of explicit memory +how memory is handled is in order. To make memory management simple, an **arena** +is used that pools memory in a single location for easy +allocation and removal. This enables the removal of explicit memory deallocation. Because memory allocation for all needed memory in the compiler registers that memory with the arena, a single call to free the arena is all that is needed to completely free all memory used by the compiler. @@ -153,8 +160,8 @@ used. That freeing is done with ``PyArena_Free()``. This only needs to be called in strategic areas where the compiler exits. As stated above, in general you should not have to worry about memory -management when working on the compiler. The technical details have been -designed to be hidden from you for most cases. +management when working on the compiler. The technical details of memory +management have been designed to be hidden from you for most cases. The only exception comes about when managing a PyObject. Since the rest of Python uses reference counting, there is extra support added @@ -173,7 +180,7 @@ The AST is generated from source code using the function After some checks, a helper function in :cpy-file:`Parser/parser.c` begins applying production rules on the source code it receives; converting source code to tokens and matching these tokens recursively to their corresponding rule. The -rule's corresponding rule function is called on every match. These rule +production rule's corresponding rule function is called on every match. These rule functions follow the format :samp:`xx_rule`. Where *xx* is the grammar rule that the function handles and is automatically derived from :cpy-file:`Grammar/python.gram` @@ -293,7 +300,7 @@ number is passed as the last parameter to each ``stmt_ty`` function. Control flow graphs =================== -A *control flow graph* (often referenced by its acronym, CFG) is a +A **control flow graph** (often referenced by its acronym, **CFG**) is a directed graph that models the flow of a program. A node of a CFG is not an individual bytecode instruction, but instead represents a sequence of bytecode instructions that always execute sequentially. @@ -441,60 +448,6 @@ flattening and then a ``PyCodeObject`` is created. All of this is handled by calling ``assemble()``. -Introducing new bytecode -======================== - -Sometimes a new feature requires a new opcode. But adding new bytecode is -not as simple as just suddenly introducing new bytecode in the AST -> -bytecode step of the compiler. Several pieces of code throughout Python depend -on having correct information about what bytecode exists. - -First, you must choose a name, implement the bytecode in -:cpy-file:`Python/bytecodes.c`, and add a documentation entry in -:cpy-file:`Doc/library/dis.rst`. Then run ``make regen-cases`` to -assign a number for it (see :cpy-file:`Include/opcode_ids.h`) and -regenerate a number of files with the actual implementation of the -bytecodes (:cpy-file:`Python/generated_cases.c.h`) and additional -files with metadata about them. - -With a new bytecode you must also change what is called the magic number for -.pyc files. The variable ``MAGIC_NUMBER`` in -:cpy-file:`Lib/importlib/_bootstrap_external.py` contains the number. -Changing this number will lead to all .pyc files with the old ``MAGIC_NUMBER`` -to be recompiled by the interpreter on import. Whenever ``MAGIC_NUMBER`` is -changed, the ranges in the ``magic_values`` array in :cpy-file:`PC/launcher.c` -must also be updated. Changes to :cpy-file:`Lib/importlib/_bootstrap_external.py` -will take effect only after running ``make regen-importlib``. Running this -command before adding the new bytecode target to :cpy-file:`Python/bytecodes.c` -(followed by ``make regen-cases``) will result in an error. You should only run -``make regen-importlib`` after the new bytecode target has been added. - -.. note:: On Windows, running the ``./build.bat`` script will automatically - regenerate the required files without requiring additional arguments. - -Finally, you need to introduce the use of the new bytecode. Altering -:cpy-file:`Python/compile.c`, :cpy-file:`Python/bytecodes.c` will be the -primary places to change. Optimizations in :cpy-file:`Python/flowgraph.c` -may also need to be updated. -If the new opcode affects a control flow or the block stack, you may have -to update the ``frame_setlineno()`` function in :cpy-file:`Objects/frameobject.c`. -:cpy-file:`Lib/dis.py` may need an update if the new opcode interprets its -argument in a special way (like ``FORMAT_VALUE`` or ``MAKE_FUNCTION``). - -If you make a change here that can affect the output of bytecode that -is already in existence and you do not change the magic number constantly, make -sure to delete your old .py(c|o) files! Even though you will end up changing -the magic number if you change the bytecode, while you are debugging your work -you will be changing the bytecode output without constantly bumping up the -magic number. This means you end up with stale .pyc files that will not be -recreated. -Running ``find . -name '*.py[co]' -exec rm -f '{}' +`` should delete all .pyc -files you have, forcing new ones to be created and thus allow you test out your -new bytecode properly. Run ``make regen-importlib`` for updating the -bytecode of frozen importlib files. You have to run ``make`` again after this -for recompiling generated C files. - - Code objects ============ @@ -613,12 +566,30 @@ Important files * :cpy-file:`Lib/opcode.py`: Master list of bytecode; if this file is modified you must modify several other files accordingly - (see "`Introducing New Bytecode`_") * :cpy-file:`Lib/importlib/_bootstrap_external.py`: Home of the magic number (named ``MAGIC_NUMBER``) for bytecode versioning. +Objects +======= + +* :cpy-file:`Objects/locations.md`: Describes the location table +* :cpy-file:`Objects/frame_layout.md`: Describes the frame stack +* :cpy-file:`Objects/object_layout.md`: Descibes object layout for 3.11 and later +* :cpy-file:`Objects/exception_handling_notes.txt`: Exception handling notes + + +Specializing Adaptive Interpreter +================================= + +Adding a specializing, adaptive interpreter to CPython will bring significant +performance improvements. These documents provide more information: + +* :pep:`659`: Specializing Adaptive Interpreter +* :cpy-file:`Python/adaptive.md`: Adding or extending a family of adaptive instructions + + References ========== diff --git a/internals/interpreter.rst b/internals/interpreter.rst index 003d5de13..a53b6283c 100644 --- a/internals/interpreter.rst +++ b/internals/interpreter.rst @@ -312,3 +312,62 @@ Other topics - Tracing - Setting the current lineno (debugger-induced jumps) - Specialization, inline caches etc. + + +Introducing new bytecode +======================== + +.. note:: + + This section is relevant if you are adding a new bytecode to the interpreter. + + +Sometimes a new feature requires a new opcode. But adding new bytecode is +not as simple as just suddenly introducing new bytecode in the AST -> +bytecode step of the compiler. Several pieces of code throughout Python depend +on having correct information about what bytecode exists. + +First, you must choose a name, implement the bytecode in +:cpy-file:`Python/bytecodes.c`, and add a documentation entry in +:cpy-file:`Doc/library/dis.rst`. Then run ``make regen-cases`` to +assign a number for it (see :cpy-file:`Include/opcode_ids.h`) and +regenerate a number of files with the actual implementation of the +bytecodes (:cpy-file:`Python/generated_cases.c.h`) and additional +files with metadata about them. + +With a new bytecode you must also change what is called the magic number for +.pyc files. The variable ``MAGIC_NUMBER`` in +:cpy-file:`Lib/importlib/_bootstrap_external.py` contains the number. +Changing this number will lead to all .pyc files with the old ``MAGIC_NUMBER`` +to be recompiled by the interpreter on import. Whenever ``MAGIC_NUMBER`` is +changed, the ranges in the ``magic_values`` array in :cpy-file:`PC/launcher.c` +must also be updated. Changes to :cpy-file:`Lib/importlib/_bootstrap_external.py` +will take effect only after running ``make regen-importlib``. Running this +command before adding the new bytecode target to :cpy-file:`Python/bytecodes.c` +(followed by ``make regen-cases``) will result in an error. You should only run +``make regen-importlib`` after the new bytecode target has been added. + +.. note:: On Windows, running the ``./build.bat`` script will automatically + regenerate the required files without requiring additional arguments. + +Finally, you need to introduce the use of the new bytecode. Altering +:cpy-file:`Python/compile.c`, :cpy-file:`Python/bytecodes.c` will be the +primary places to change. Optimizations in :cpy-file:`Python/flowgraph.c` +may also need to be updated. +If the new opcode affects a control flow or the block stack, you may have +to update the ``frame_setlineno()`` function in :cpy-file:`Objects/frameobject.c`. +:cpy-file:`Lib/dis.py` may need an update if the new opcode interprets its +argument in a special way (like ``FORMAT_VALUE`` or ``MAKE_FUNCTION``). + +If you make a change here that can affect the output of bytecode that +is already in existence and you do not change the magic number constantly, make +sure to delete your old .py(c|o) files! Even though you will end up changing +the magic number if you change the bytecode, while you are debugging your work +you will be changing the bytecode output without constantly bumping up the +magic number. This means you end up with stale .pyc files that will not be +recreated. +Running ``find . -name '*.py[co]' -exec rm -f '{}' +`` should delete all .pyc +files you have, forcing new ones to be created and thus allow you test out your +new bytecode properly. Run ``make regen-importlib`` for updating the +bytecode of frozen importlib files. You have to run ``make`` again after this +for recompiling generated C files. From 6b7d82dbf2c5b0edd499f278ffc57f168ed2acab Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 17 Oct 2023 17:15:07 -0700 Subject: [PATCH 210/538] Add Adam Turner to the developer log (#1197) --- core-developers/developers.csv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 70b349bfe..3eee1efa3 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Adam Turner,AA-Turner,2023-10-10,, C.A.M. Gerlach,CAM-Gerlach,2023-04-19,, Barney Gale,barneygale,2023-03-21,, Carl Meyer,carljm,2023-02-28,, @@ -121,7 +122,7 @@ Steven Bethard,,2006-04-27,2017-02-10,For PEP access and SourceForge maintenance Gerhard Häring,,2006-04-23,2017-02-10,Did not make the GitHub transition George Yoshida,,2006-04-17,2017-02-10,For tracker administration; did not make GitHub transition Ronald Oussoren,ronaldoussoren,2006-03-03,,For Mac-related work -Alyssa Coghlan,ncoghlan,2005-10-16,,also contributed as Nick Coghlan (prior to 2023-08-04) +Alyssa Coghlan,ncoghlan,2005-10-16,,Also contributed as Nick Coghlan (prior to 2023-08-04) Georg Brandl,birkenfeld,2005-05-28,, Terry Jan Reedy,terryjreedy,2005-04-07,, Bob Ippolito,etrepum,2005-03-02,2017-02-10,For Mac-related work From 0661704c28629273a98e0b7ceafef0ef0dbd6046 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Wed, 18 Oct 2023 10:18:06 +0100 Subject: [PATCH 211/538] Add Adam Turner to the Experts Index (#1199) --- core-developers/experts.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 419efb42c..24093cb3e 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -181,7 +181,7 @@ pty Yhg1s* pwd py_compile carljm pyclbr isidentical -pydoc +pydoc AA-Turner queue rhettinger* quopri random rhettinger, mdickinson @@ -319,13 +319,15 @@ issue tracker ezio-melotti buildbots zware, pablogsal bytecode benjaminp, 1st1, markshannon, brandtbucher, carljm context managers ncoghlan -core workflow Mariatta, ezio-melotti, hugovk +core workflow Mariatta, ezio-melotti, hugovk, AA-Turner coverity scan tiran, Yhg1s cryptography gpshead, dstufft data formats mdickinson database malemburg -devguide merwok, ezio-melotti, willingc, Mariatta, hugovk -documentation ezio-melotti, merwok, JulienPalard, willingc, hugovk +devguide merwok, ezio-melotti, willingc, Mariatta, hugovk, + AA-Turner +documentation ezio-melotti, merwok, JulienPalard, willingc, hugovk, + AA-Turner emoji Mariatta extension modules encukou, ncoghlan filesystem giampaolo From 173bcb58d545ff9903c60a2f1e76741d91c702ca Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 18 Oct 2023 19:46:27 +0300 Subject: [PATCH 212/538] Add timeout to CI jobs (#1200) --- .github/workflows/ci.yml | 4 ++-- .github/workflows/documentation-links.yml | 1 + .github/workflows/lint.yml | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2b16054d..3f798d074 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,11 +8,11 @@ env: jobs: test: name: Check build, markup, and links - runs-on: ubuntu-latest + timeout-minutes: 10 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3" diff --git a/.github/workflows/documentation-links.yml b/.github/workflows/documentation-links.yml index d95cbd3ab..bacb37d07 100644 --- a/.github/workflows/documentation-links.yml +++ b/.github/workflows/documentation-links.yml @@ -10,6 +10,7 @@ permissions: jobs: documentation-links: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: readthedocs/actions/preview@v1 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c78a4053a..5c9caf026 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -5,9 +5,10 @@ on: [push, pull_request, workflow_dispatch] jobs: lint: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.x" From d4d69b4e8274d31536d791992e755f3cd31a814f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 19 Oct 2023 18:25:25 +0200 Subject: [PATCH 213/538] Re-add cfbolz Carl Friedrich was removed and not re-added during a refactor in 8092deddd0ba27d96055d5eb9b8a9998266638bb. --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 3eee1efa3..c85c48bc8 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -65,6 +65,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,2017-02-10,for stdlib compatibility work for PyPy; did not make GitHub transition 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, From 556817363bf01aa318540599f7a0e83a19da2e41 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 19 Oct 2023 17:33:58 +0100 Subject: [PATCH 214/538] Remove Distutils from the experts index (#1198) --- core-developers/experts.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 24093cb3e..19f685b39 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -100,7 +100,6 @@ dbm decimal facundobatista, rhettinger, mdickinson difflib tim-one (inactive) dis 1st1 -distutils merwok, dstufft doctest tim-one (inactive) email warsaw, bitdancer*, maxking encodings malemburg From 74b312f28638bd26302d693e0787927f62b61041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=81apkiewicz?= <80906036+fipachu@users.noreply.github.com> Date: Thu, 19 Oct 2023 18:38:21 +0200 Subject: [PATCH 215/538] Fix PowerShell command (#1202) Quoting PowerShell: The term 'python.bat' is not recognized as the name of a cmdlet, function, script file, or operable program. .\python.bat however works perfectly. --- getting-started/pull-request-lifecycle.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 7289a921b..e2dde81f6 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -249,7 +249,7 @@ On *Windows* (after any successful build): .. code-block:: dosbatch - python.bat Tools\patchcheck\patchcheck.py + .\python.bat Tools\patchcheck\patchcheck.py The automated patch checklist runs through: From d8a1a3fa65f48aa87508c59458c2e2b62c085916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=81apkiewicz?= <80906036+fipachu@users.noreply.github.com> Date: Thu, 19 Oct 2023 18:47:21 +0200 Subject: [PATCH 216/538] gh-1194: Add Windows command for patchcheck to Quick Reference (#1195) --- index.rst | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/index.rst b/index.rst index c4450e1e0..6c54779d7 100644 --- a/index.rst +++ b/index.rst @@ -57,8 +57,19 @@ instructions please see the :ref:`setup guide `. `_. Trivial issues (e.g. typo fixes) do not require any issue to be created. -6. Once you fixed the issue, run the tests, run ``make patchcheck``, and if - everything is ok, commit. +6. Once you fixed the issue, run the tests, and the patchcheck. + + On Unix and macOS use:: + + make patchcheck + + and on Windows: + + .. code-block:: dosbatch + + .\python.bat Tools\patchcheck\patchcheck.py + + If everything is ok, commit. 7. Push the branch on your fork on GitHub and :ref:`create a pull request `. Include the issue number using ``gh-NNNN`` in the From 0200b0fce906224cfd02afd0e46b58524f48e137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=81apkiewicz?= <80906036+fipachu@users.noreply.github.com> Date: Thu, 19 Oct 2023 21:23:33 +0200 Subject: [PATCH 217/538] Add missing word (#1203) --- getting-started/getting-help.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started/getting-help.rst b/getting-started/getting-help.rst index d1b48f23f..4e5a02c39 100644 --- a/getting-started/getting-help.rst +++ b/getting-started/getting-help.rst @@ -25,7 +25,7 @@ most of which are open for all users to read and post. Those particularly relevant for help contributing to Python itself include: * `Core Development`_ for most general questions and help -* `Ideas`_ to discuss new ideas for the Python +* `Ideas`_ to discuss new ideas for the Python language * `Core Workflow`_ for questions about the dev infrastructure and bots .. seealso:: From c60b692142385bd30edcaac133960d153821aaab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Fri, 20 Oct 2023 21:05:00 +0200 Subject: [PATCH 218/538] Mark cfbolz as active --- core-developers/developers.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index c85c48bc8..2510af384 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -65,7 +65,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,2017-02-10,for stdlib compatibility work for PyPy; did not make GitHub transition +Carl Friedrich 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, @@ -143,7 +143,7 @@ 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 From eaf1ed8d5da0c32f8cb16f2e06cbb7ece4f85eb7 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Sun, 22 Oct 2023 23:01:27 +0100 Subject: [PATCH 219/538] update my `experts` entries (#1204) --- 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 19f685b39..ca52a1532 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -311,12 +311,12 @@ Interest Area Maintainers ================== ========================================================== algorithms rhettinger* argument clinic larryhastings -ast/compiler benjaminp, 1st1, pablogsal, markshannon, isidentical, brandtbucher, carljm +ast/compiler benjaminp, 1st1, pablogsal, markshannon, isidentical, brandtbucher, carljm, iritkatriel autoconf/makefiles Yhg1s* bsd issue tracker ezio-melotti buildbots zware, pablogsal -bytecode benjaminp, 1st1, markshannon, brandtbucher, carljm +bytecode benjaminp, 1st1, markshannon, brandtbucher, carljm, iritkatriel context managers ncoghlan core workflow Mariatta, ezio-melotti, hugovk, AA-Turner coverity scan tiran, Yhg1s From 2a6cbd24aecc6678573fd3ce0f565eabc3bce345 Mon Sep 17 00:00:00 2001 From: Lance Goyke Date: Thu, 26 Oct 2023 01:24:56 -0400 Subject: [PATCH 220/538] Add inline tabs on Quick Reference page for commands on different systems (#1205) * add sphinx-inline-tabs dependency * implement system environment instructions in tabs * sort requirements alphabetically * sort extensions alphabetically * remove whitespace from empty line * move macOS note into macOS tab * remove redundant explanation --- conf.py | 1 + index.rst | 65 +++++++++++++++++++++++++++++++++++++----------- requirements.txt | 1 + 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/conf.py b/conf.py index 06b4c68a1..c0997f017 100644 --- a/conf.py +++ b/conf.py @@ -11,6 +11,7 @@ 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx_copybutton', + 'sphinx_inline_tabs', 'sphinxext.opengraph', 'sphinxext.rediraffe', ] diff --git a/index.rst b/index.rst index 6c54779d7..987f6b4bc 100644 --- a/index.rst +++ b/index.rst @@ -27,27 +27,54 @@ instructions please see the :ref:`setup guide `. git clone https://github.com//cpython cd cpython -3. Build Python, on Unix and macOS use:: +3. Build Python: - ./configure --with-pydebug && make -j + .. tab:: Unix - and on Windows use: + .. code-block:: shell - .. code-block:: dosbatch + ./configure --with-pydebug && make -j - PCbuild\build.bat -e -d + .. tab:: macOS + + .. code-block:: shell + + ./configure --with-pydebug && make -j + + .. tab:: Windows + + .. code-block:: dosbatch + + PCbuild\build.bat -e -d See also :ref:`more detailed instructions `, :ref:`how to install and build dependencies `, and the platform-specific pages for :ref:`Unix `, :ref:`macOS`, and :ref:`Windows `. -4. :ref:`Run the tests `:: +4. :ref:`Run the tests `: + + .. tab:: Unix + + .. code-block:: shell + + ./python -m test -j3 + + .. tab:: macOS - ./python -m test -j3 + .. code-block:: shell - On :ref:`most ` macOS systems, replace :file:`./python` - with :file:`./python.exe`. On Windows, use :file:`python.bat`. + ./python.exe -m test -j3 + + Note: :ref:`Most ` macOS systems use + :file:`./python.exe` in order to avoid filename conflicts with + the ``Python`` directory. + + .. tab:: Windows + + .. code-block:: dosbatch + + .\python.bat -m test -j3 5. Create a new branch where your work for the issue will go, e.g.:: @@ -57,17 +84,25 @@ instructions please see the :ref:`setup guide `. `_. Trivial issues (e.g. typo fixes) do not require any issue to be created. -6. Once you fixed the issue, run the tests, and the patchcheck. +6. Once you fixed the issue, run the tests, and the patchcheck: + + .. tab:: Unix + + .. code-block:: shell + + make patchcheck + + .. tab:: macOS - On Unix and macOS use:: + .. code-block:: shell - make patchcheck + make patchcheck - and on Windows: + .. tab:: Windows - .. code-block:: dosbatch + .. code-block:: dosbatch - .\python.bat Tools\patchcheck\patchcheck.py + .\python.bat Tools\patchcheck\patchcheck.py If everything is ok, commit. diff --git a/requirements.txt b/requirements.txt index 2a1e944b6..ebf044d00 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ Sphinx~=7.2.6 furo>=2022.6.4 jinja2 +sphinx-inline-tabs>=2023.4.21 sphinx-lint==0.6.8 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 From cd06b156397ba3358f76ef3a6b650eebceb3900d Mon Sep 17 00:00:00 2001 From: Lance Goyke Date: Thu, 26 Oct 2023 21:38:39 -0400 Subject: [PATCH 221/538] Add inline tabs on Running and Writing Tests page for commands on different systems (#1206) Remove bit about running tests on Python 2.7 --- testing/run-write-tests.rst | 145 +++++++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 18 deletions(-) diff --git a/testing/run-write-tests.rst b/testing/run-write-tests.rst index 7efe8307b..58e56297d 100644 --- a/testing/run-write-tests.rst +++ b/testing/run-write-tests.rst @@ -17,14 +17,27 @@ Running The shortest, simplest way of running the test suite is the following command from the root directory of your checkout (after you have -:ref:`built Python `):: +:ref:`built Python `): - ./python -m test +.. tab:: Unix -You may need to change this command as follows throughout this section. -On :ref:`most ` macOS systems, replace :file:`./python` -with :file:`./python.exe`. On Windows, use :file:`python.bat`. If using -Python 2.7, replace ``test`` with ``test.regrtest``. + .. code-block:: shell + + ./python -m test + +.. tab:: macOS + + .. code-block:: shell + + ./python.exe -m test + + This works on :ref:`most ` macOS systems. + +.. tab:: Windows + + .. code-block:: dosbatch + + .\python.bat -m test This will run the majority of tests, but exclude a small portion of them; these excluded tests use special kinds of resources: for example, accessing the @@ -32,25 +45,89 @@ Internet, or trying to play a sound or to display a graphical interface on your desktop. They are disabled by default so that running the test suite is not too intrusive. To enable some of these additional tests (and for other flags which can help debug various issues such as reference leaks), read -the help text:: +the help text: + +.. tab:: Unix + + .. code-block:: shell + + ./python -m test -h + +.. tab:: macOS + + .. code-block:: shell + + ./python.exe -m test -h - ./python -m test -h +.. tab:: Windows + + .. code-block:: dosbatch + + .\python.bat -m test -h If you want to run a single test file, simply specify the test file name (without the extension) as an argument. You also probably want to enable -verbose mode (using ``-v``), so that individual failures are detailed:: +verbose mode (using ``-v``), so that individual failures are detailed: + +.. tab:: Unix + + .. code-block:: shell + + ./python -m test -v test_abc + +.. tab:: macOS + + .. code-block:: shell - ./python -m test -v test_abc + ./python.exe -m test -v test_abc + +.. tab:: Windows + + .. code-block:: dosbatch + + .\python.bat -m test -v test_abc To run a single test case, use the ``unittest`` module, providing the import -path to the test case:: +path to the test case: + +.. tab:: Unix + + .. code-block:: shell + + ./python -m unittest -v test.test_abc.TestABC_Py + +.. tab:: macOS - ./python -m unittest -v test.test_abc.TestABC_Py + .. code-block:: shell + + ./python.exe -m unittest -v test.test_abc.TestABC_Py + +.. tab:: Windows + + .. code-block:: dosbatch + + .\python.bat -m unittest -v test.test_abc.TestABC_Py Some test modules also support direct invocation, -which might be useful for IDEs and local debugging:: +which might be useful for IDEs and local debugging: + +.. tab:: Unix + + .. code-block:: shell + + ./python Lib/test/test_typing.py - ./python Lib/test/test_typing.py +.. tab:: macOS + + .. code-block:: shell + + ./python.exe Lib/test/test_typing.py + +.. tab:: Windows + + .. code-block:: dosbatch + + .\python.bat Lib/test/test_typing.py But, there are several important notes: @@ -61,9 +138,25 @@ But, there are several important notes: most likely it does not support direct invocation. If you have a multi-core or multi-CPU machine, you can enable parallel testing -using several Python processes so as to speed up things:: +using several Python processes so as to speed up things: + +.. tab:: Unix + + .. code-block:: shell - ./python -m test -j0 + ./python -m test -j0 + +.. tab:: macOS + + .. code-block:: shell + + ./python.exe -m test -j0 + +.. tab:: Windows + + .. code-block:: dosbatch + + .\python.bat -m test -j0 If you are running a version of Python prior to 3.3 you must specify the number of processes to run simultaneously (e.g. ``-j2``). @@ -71,9 +164,25 @@ of processes to run simultaneously (e.g. ``-j2``). .. _strenuous_testing: Finally, if you want to run tests under a more strenuous set of settings, you -can run ``test`` as:: +can run ``test`` as: + +.. tab:: Unix + + .. code-block:: shell + + ./python -bb -E -Wd -m test -r -w -uall + +.. tab:: macOS + + .. code-block:: shell + + ./python.exe -bb -E -Wd -m test -r -w -uall + +.. tab:: Windows + + .. code-block:: dosbatch - ./python -bb -E -Wd -m test -r -w -uall + .\python.bat -bb -E -Wd -m test -r -w -uall The various extra flags passed to Python cause it to be much stricter about various things (the ``-Wd`` flag should be ``-W error`` at some point, but the From 42fb25979313c2d7e844be87cd5cf5436f600663 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 30 Oct 2023 18:02:14 +0200 Subject: [PATCH 222/538] Refactor `Makefile` to re-use targets via variables (#1207) * Refactor Makefile to re-use targets via variables * Move 'SOURCEDIR OUTPUTDIR' to new line after other options --- Makefile | 107 ++++++++++++++++++++++--------------------------------- 1 file changed, 43 insertions(+), 64 deletions(-) diff --git a/Makefile b/Makefile index 6e25d9389..8ded8f2c6 100644 --- a/Makefile +++ b/Makefile @@ -7,13 +7,17 @@ VENVDIR = ./venv BUILDDIR = _build SPHINXOPTS = -W --keep-going SPHINXBUILD = $(VENVDIR)/bin/sphinx-build +BUILDER = html SPHINXLINT = $(VENVDIR)/bin/sphinx-lint PAPER = # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +ALLSPHINXOPTS = -b $(BUILDER) \ + -d $(BUILDDIR)/doctrees \ + $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) \ + . $(BUILDDIR)/$(BUILDER) .PHONY: help help: @@ -69,111 +73,86 @@ ensure-venv: .PHONY: html html: ensure-venv versions - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + $(SPHINXBUILD) $(ALLSPHINXOPTS) .PHONY: dirhtml -dirhtml: ensure-venv versions - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." +dirhtml: BUILDER = dirhtml +dirhtml: html .PHONY: singlehtml -singlehtml: ensure-venv - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." +singlehtml: BUILDER = singlehtml +singlehtml: html .PHONY: pickle -pickle: ensure-venv - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle +pickle: BUILDER = pickle +pickle: html @echo @echo "Build finished; now you can process the pickle files." .PHONY: json -json: ensure-venv - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json +json: BUILDER = json +json: html @echo @echo "Build finished; now you can process the JSON files." .PHONY: htmlhelp -htmlhelp: ensure-venv - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp +htmlhelp: BUILDER = htmlhelp +htmlhelp: html @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." + ".hhp project file in $(BUILDDIR)/$(BUILDER)." .PHONY: qthelp -qthelp: ensure-venv - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PythonDevelopersGuide.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PythonDevelopersGuide.qhc" +qthelp: BUILDER = qthelp +qthelp: html .PHONY: devhelp -devhelp: ensure-venv - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/PythonDevelopersGuide" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PythonDevelopersGuide" - @echo "# devhelp" +devhelp: BUILDER = devhelp +devhelp: html .PHONY: epub -epub: ensure-venv - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub +epub: BUILDER = epub +epub: html @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + @echo "Build finished. The epub file is in $(BUILDDIR)/$(BUILDER)." .PHONY: latex -latex: ensure-venv - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." +latex: BUILDER = latex +latex: html .PHONY: latexpdf -latexpdf: ensure-venv - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex +latexpdf: BUILDER = latex +latexpdf: html @echo "Running LaTeX files through pdflatex..." make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/$(BUILDER)." .PHONY: text -text: ensure-venv - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." +text: BUILDER = text +text: html .PHONY: man -man: ensure-venv - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man +man: BUILDER = man +man: html @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + @echo "Build finished. The manual pages are in $(BUILDDIR)/$(BUILDER)." .PHONY: changes -changes: ensure-venv - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." +changes: BUILDER = changes +changes: html -linkcheck: ensure-venv - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck +.PHONY: linkcheck +linkcheck: BUILDER = linkcheck +linkcheck: html @echo @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." + "or in $(BUILDDIR)/$(BUILDER)/output.txt." .PHONY: doctest -doctest: ensure-venv - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest +doctest: BUILDER = doctest +doctest: html @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." + "results in $(BUILDDIR)/$(BUILDER)/output.txt." .PHONY: htmlview htmlview: html From 4afd584e2371b297e8518021f7d8a28d09fdc7db Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 31 Oct 2023 04:56:23 +0800 Subject: [PATCH 223/538] Update my experts index (#1209) --- 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 ca52a1532..34edccfd0 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -237,7 +237,7 @@ tracemalloc vstinner tty Yhg1s* turtle gregorlingl^, willingc types 1st1 -typing gvanrossum, Fidget-Spinner, JelleZijlstra*, AlexWaygood*, carljm +typing gvanrossum, JelleZijlstra*, AlexWaygood*, carljm unicodedata malemburg, ezio-melotti unittest voidspace*, ezio-melotti, rbtcollins, gpshead unittest.mock voidspace* @@ -345,7 +345,7 @@ object model benjaminp, Yhg1s packaging tarekziade, malemburg, alexis^, merwok, dstufft, pfmoore pattern matching brandtbucher* peg parser gvanrossum, pablogsal, lysnikolaou -performance vstinner, serhiy-storchaka, 1st1, rhettinger, markshannon, brandtbucher, carljm +performance vstinner, serhiy-storchaka, 1st1, rhettinger, markshannon, brandtbucher, carljm, Fidget-Spinner pip ncoghlan, dstufft, pfmoore, Marcus.Smith^, pradyunsg py3 transition benjaminp release management tarekziade, malemburg, benjaminp, warsaw, From 9a5df92a0395a1ee3f40cc34cb4bc096e6b17b4f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 31 Oct 2023 10:36:19 +0200 Subject: [PATCH 224/538] Add `make autobuild` to rebuild and reload HTML files in your browser (#1208) --- Makefile | 6 ++++++ requirements.txt | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8ded8f2c6..8fe59bdee 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ help: @echo " venv to create a venv with necessary tools" @echo " html to make standalone HTML files" @echo " htmlview to open the index page built by the html target in your browser" + @echo " autobuild to rebuild and reload HTML files in your browser" @echo " clean to remove the venv and build files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @@ -158,6 +159,11 @@ doctest: html htmlview: html $(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('_build/html/index.html'))" +.PHONY: autobuild +autobuild: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild +autobuild: SPHINXOPTS = --re-ignore="/\.idea/|/venv/" +autobuild: html + .PHONY: check check: ensure-venv # Ignore the tools and venv dirs and check that the default role is not used. diff --git a/requirements.txt b/requirements.txt index ebf044d00..2a5a60dbd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,10 @@ -Sphinx~=7.2.6 furo>=2022.6.4 jinja2 +sphinx-autobuild sphinx-inline-tabs>=2023.4.21 sphinx-lint==0.6.8 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 sphinxext-rediraffe +Sphinx~=7.2.6 From da86846034087efaa47dcd2f3d7c3721347d2936 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 08:09:28 +0200 Subject: [PATCH 225/538] Bump sphinx-lint from 0.6.8 to 0.8.1 (#1211) Bumps [sphinx-lint](https://github.com/sphinx-contrib/sphinx-lint) from 0.6.8 to 0.8.1. - [Release notes](https://github.com/sphinx-contrib/sphinx-lint/releases) - [Commits](https://github.com/sphinx-contrib/sphinx-lint/compare/v0.6.8...v0.8.1) --- updated-dependencies: - dependency-name: sphinx-lint dependency-type: direct:production update-type: version-update:semver-minor ... 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 2a5a60dbd..036517fe0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ furo>=2022.6.4 jinja2 sphinx-autobuild sphinx-inline-tabs>=2023.4.21 -sphinx-lint==0.6.8 +sphinx-lint==0.8.1 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 From 2e9e657b53830806d202df70cbed3353afcdb5d1 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 1 Nov 2023 20:56:27 +0200 Subject: [PATCH 226/538] Rename 'make autobuild' to 'make htmllive' (#1212) --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 8fe59bdee..da382ea67 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ help: @echo " venv to create a venv with necessary tools" @echo " html to make standalone HTML files" @echo " htmlview to open the index page built by the html target in your browser" - @echo " autobuild to rebuild and reload HTML files in your browser" + @echo " htmllive to rebuild and reload HTML files in your browser" @echo " clean to remove the venv and build files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @@ -159,10 +159,10 @@ doctest: html htmlview: html $(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('_build/html/index.html'))" -.PHONY: autobuild -autobuild: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild -autobuild: SPHINXOPTS = --re-ignore="/\.idea/|/venv/" -autobuild: html +.PHONY: htmllive +htmllive: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild +htmllive: SPHINXOPTS = --re-ignore="/\.idea/|/venv/" +htmllive: html .PHONY: check check: ensure-venv From 4961fe75195ce39a72f32ff406f34a354ebeee4f Mon Sep 17 00:00:00 2001 From: Shashank <48438739+shashankshet@users.noreply.github.com> Date: Fri, 3 Nov 2023 10:52:32 +0530 Subject: [PATCH 227/538] omitting the "unused" prompt in code example (1210) * omitting the "unused" prompt in code example * updated text as per review comment --- documentation/markup.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index ade1df3a7..0f31e345d 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -611,14 +611,13 @@ preceding paragraph and delimited by indentation. Representing an interactive session requires including the prompts and output along with the Python code. No special markup is required for interactive -sessions. After the last line of input or output presented, there should not be -an "unused" primary prompt; this is an example of what *not* to do: +sessions. After the last line of input or output is presented, there should +be no trailing prompt. An example of correct usage is: .. code-block:: python >>> 1 + 1 2 - >>> Syntax highlighting is handled in a smart way: From 345bbe4bf334b390749640dd1a7015e3ebdc2e8a Mon Sep 17 00:00:00 2001 From: "John P. Rouillard" Date: Fri, 3 Nov 2023 01:25:32 -0400 Subject: [PATCH 228/538] Update issue-tracker.rst - change Roundup link to canonical link (#1213) Use www.roundup-trcker.org rather than roundup.sourceforge.io. --- triage/issue-tracker.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triage/issue-tracker.rst b/triage/issue-tracker.rst index 0f93df9ca..b8384b553 100644 --- a/triage/issue-tracker.rst +++ b/triage/issue-tracker.rst @@ -154,7 +154,7 @@ reason either as ``complete`` or ``not planned``. .. _issue tracker: https://github.com/python/cpython/issues .. _advanced search: https://github.com/search/advanced .. _devguide repo: https://github.com/python/devguide/issues -.. _Roundup: https://roundup.sourceforge.io/ +.. _Roundup: https://www.roundup-tracker.org/ .. _Python Discourse: https://discuss.python.org/ .. _autolinks: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/autolinked-references-and-urls .. _checklists: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/about-task-lists From e95f9085085c580923a883fa15574428e108ba4a Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Fri, 3 Nov 2023 08:54:41 -0700 Subject: [PATCH 229/538] Add a URL for bpo and clarify historical tracker in note (#1214) * Add a URL for bpo and clarify historical tracker in note * Update triage/issue-tracker.rst Co-authored-by: Hugo van Kemenade --------- Co-authored-by: Hugo van Kemenade --- triage/issue-tracker.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/triage/issue-tracker.rst b/triage/issue-tracker.rst index b8384b553..c139f5d36 100644 --- a/triage/issue-tracker.rst +++ b/triage/issue-tracker.rst @@ -17,9 +17,10 @@ If you would like to file an issue about this devguide, please do so at the `devguide repo`_. .. note:: + Prior to moving the issue tracker to GitHub, Python used to use a dedicated `Roundup`_ instance as its issue tracker. - That old bug tracker was hosted under the domain ``bugs.python.org`` - (sometimes called ``bpo`` for short). Currently a read-only version is still + That `old bug tracker`_ was hosted under the domain ``bugs.python.org`` + (sometimes called ``bpo`` for short). A read-only version is available on that domain for historical purposes. All ``bpo`` data has been migrated to the current `issue tracker`_ on GitHub. @@ -160,3 +161,4 @@ reason either as ``complete`` or ``not planned``. .. _checklists: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/about-task-lists .. _duplicates: https://docs.github.com/en/issues/tracking-your-work-with-issues/marking-issues-or-pull-requests-as-a-duplicate .. _Core Development Discourse category: https://discuss.python.org/c/core-dev/23 +.. _old bug tracker: https://bugs.python.org/ From 01cb2168a44c8ab5a86bea1706aca7322bc2dbcc Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 14 Nov 2023 17:19:20 +0200 Subject: [PATCH 230/538] Activate tabs based on browser's operating system (#1216) --- _static/activate_tab.js | 42 +++++++++++++++++++++++++++++++++++++ conf.py | 3 +++ index.rst | 8 +++++++ testing/run-write-tests.rst | 8 +++++++ 4 files changed, 61 insertions(+) create mode 100644 _static/activate_tab.js diff --git a/_static/activate_tab.js b/_static/activate_tab.js new file mode 100644 index 000000000..8b5fcbabd --- /dev/null +++ b/_static/activate_tab.js @@ -0,0 +1,42 @@ +// Based on https://stackoverflow.com/a/38241481/724176 +function getOS() { + const userAgent = window.navigator.userAgent, + platform = + window.navigator?.userAgentData?.platform || window.navigator.platform, + macosPlatforms = ["macOS", "Macintosh", "MacIntel", "MacPPC", "Mac68K"], + windowsPlatforms = ["Win32", "Win64", "Windows", "WinCE"], + iosPlatforms = ["iPhone", "iPad", "iPod"]; + + if (macosPlatforms.includes(platform)) { + return "macOS"; + } else if (iosPlatforms.includes(platform)) { + return "iOS"; + } else if (windowsPlatforms.includes(platform)) { + return "Windows"; + } else if (/Android/.test(userAgent)) { + return "Android"; + } else if (/Linux/.test(platform)) { + return "Unix"; + } + + return "unknown"; +} + +function activateTab(tabName) { + // Find all label elements containing the specified tab name + const labels = document.querySelectorAll(".tab-label"); + + labels.forEach((label) => { + if (label.textContent.includes(tabName)) { + // Find the associated input element using the 'for' attribute + const tabInputId = label.getAttribute("for"); + const tabInput = document.getElementById(tabInputId); + + // Check if the input element exists before attempting to set the "checked" attribute + if (tabInput) { + // Activate the tab by setting its "checked" attribute to true + tabInput.checked = true; + } + } + }); +} diff --git a/conf.py b/conf.py index c0997f017..31ce4f5fd 100644 --- a/conf.py +++ b/conf.py @@ -45,6 +45,9 @@ html_css_files = [ 'devguide_overrides.css', ] +html_js_files = [ + "activate_tab.js", +] html_logo = "_static/python-logo.svg" html_favicon = "_static/favicon.png" diff --git a/index.rst b/index.rst index 987f6b4bc..0621180e7 100644 --- a/index.rst +++ b/index.rst @@ -2,6 +2,14 @@ Python Developer's Guide ======================== +.. raw:: html + + + .. highlight:: bash This guide is a comprehensive resource for :ref:`contributing ` diff --git a/testing/run-write-tests.rst b/testing/run-write-tests.rst index 58e56297d..6fa9b04a5 100644 --- a/testing/run-write-tests.rst +++ b/testing/run-write-tests.rst @@ -5,6 +5,14 @@ Running and writing tests ========================= +.. raw:: html + + + .. note:: This document assumes you are working from an From 679d64ba47370f38182c8c2fe7ef6aac9a587383 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 14 Nov 2023 15:31:09 -0500 Subject: [PATCH 231/538] Add "how to" for the critical_section Argument Clinic directive. (#1217) See also https://github.com/python/cpython/issues/111903. --------- Co-authored-by: Alex Waygood Co-authored-by: Erlend E. Aasland --- development-tools/clinic.rst | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index 08ba17cbf..aa0efddd6 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -1955,6 +1955,52 @@ The generated docstring ends up looking like this: 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; + } + + +.. versionadded:: 3.13 + + .. _clinic-howto-deprecate-positional: .. _clinic-howto-deprecate-keyword: From 339cb89a32b2968224d4706336b2c10b62243a7c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 15 Nov 2023 20:19:42 +0200 Subject: [PATCH 232/538] Document 'make htmllive' (#1219) --- documentation/devguide.rst | 12 +++++++++--- documentation/start-documenting.rst | 7 +++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/documentation/devguide.rst b/documentation/devguide.rst index fb6998856..b8d1de28d 100644 --- a/documentation/devguide.rst +++ b/documentation/devguide.rst @@ -42,9 +42,15 @@ in the checkout directory. On Windows use: > .\make html -You will find the generated files in ``_build/html`` or, if you use -``make htmlview``, the docs will be opened in a browser once the build -completes. Note that ``make check`` runs automatically when you submit +You will find the generated files in ``_build/html``. + +.. tip:: * Replace ``html`` with ``htmlview`` to open the docs in a web browser + once the build completes. + * 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). + +Note that ``make check`` runs automatically when you submit a :ref:`pull request `. You may wish to run ``make check`` and ``make linkcheck`` to make sure that it runs without errors. diff --git a/documentation/start-documenting.rst b/documentation/start-documenting.rst index ea72704f1..817f0a1cf 100644 --- a/documentation/start-documenting.rst +++ b/documentation/start-documenting.rst @@ -122,8 +122,11 @@ To build the docs as HTML, run:: make html -.. tip:: Substitute ``htmlview`` for ``html`` to open the docs in a web browser - once the build completes. +.. tip:: * Replace ``html`` with ``htmlview`` to open the docs in a web browser + once the build completes. + * 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 check the docs for common errors with `Sphinx Lint`_ (which is run on all :ref:`pull requests `), use:: From 2fd6cd3c69f30c49179cde9e68ef7697dbada393 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 16 Nov 2023 10:36:26 -0800 Subject: [PATCH 233/538] Document `keepalive` for buildbot workers may be the reason for frequent disconnects (#1221) Co-authored-by: Ezio Melotti --- testing/new-buildbot-worker.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index cbe039064..39742669e 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -195,6 +195,13 @@ by tests that fail. Unfortunately we do not currently have a way to notify you only of failures on your builders, so doing periodic spot checks is also a good 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 (e.g. ``180`` for 3 minutes) + in the ``buildbot.tac`` file found in your build area. + Latent workers -------------- From cc50bace86f07f8d2eaaabd103dc3c5a0c74c58b Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Sun, 19 Nov 2023 09:29:20 -0300 Subject: [PATCH 234/538] Mention sphinx-lint in the translation tools (#1230) --- documentation/translating.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/translating.rst b/documentation/translating.rst index d71d4b65f..1a860da87 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -213,6 +213,8 @@ Here's what we're using: - `powrap `__ to rewrap the ``.po`` files before committing. This helps keep Git diffs short. - `potodo `__ to list what needs to be translated. +- `sphinx-lint `__ to validate reST syntax in + translation files. How is a coordinator elected? From 20979d92ae78439e9df5dfc59ed066ad8105c9e1 Mon Sep 17 00:00:00 2001 From: Lance Goyke Date: Sun, 19 Nov 2023 07:32:51 -0600 Subject: [PATCH 235/538] =?UTF-8?q?Add=20inline=20tabs=20on=20Helping=20wi?= =?UTF-8?q?th=20the=20Developer=E2=80=99s=20Guide=20page=20for=20commands?= =?UTF-8?q?=20on=20different=20systems=20(#1223)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- documentation/devguide.rst | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/documentation/devguide.rst b/documentation/devguide.rst index b8d1de28d..a17ed342a 100644 --- a/documentation/devguide.rst +++ b/documentation/devguide.rst @@ -4,6 +4,14 @@ Helping with the Developer's Guide ================================== +.. raw:: html + + + .. highlight:: console The Developer's Guide (what you're reading now) uses the same process as the @@ -32,15 +40,21 @@ To build the devguide, some additional dependencies are required (most importantly, `Sphinx`_), and the standard way to install dependencies in Python projects is to create a virtualenv, and then install dependencies from a ``requirements.txt`` file. For your convenience, this is all *automated for -you*. To build the devguide on a Unix-like system use:: +you*. + +To build the devguide from the checkout directory: + +.. tab:: Unix/macOS + + .. code-block:: shell - $ make html + make html -in the checkout directory. On Windows use: +.. tab:: Windows -.. code-block:: doscon + .. code-block:: dosbatch - > .\make html + .\make html You will find the generated files in ``_build/html``. From a1e39bf4fdf8fde4e87a1c630300942157f529a6 Mon Sep 17 00:00:00 2001 From: Lance Goyke Date: Sun, 19 Nov 2023 14:04:08 -0600 Subject: [PATCH 236/538] Add inline tabs on Git Bootcamp page for commands on different systems (#1225) * Add inline tabs on Git Bootcamp page for commands on different systems * add getOS() script * combine Unix/macOS tabs --- getting-started/git-boot-camp.rst | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 9b8981eb5..c38857e57 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -4,6 +4,14 @@ Git bootcamp and cheat sheet ============================ +.. raw:: html + + + .. highlight:: console .. note:: @@ -439,16 +447,19 @@ Both of these tools will configure a remote URL for the branch, so you can ``git push`` if the pull request author checked "Allow edits from maintainers" when creating the pull request. -If you don't have GitHub CLI or hub installed, you can set up a git alias. On -Unix and macOS:: +If you don't have GitHub CLI or hub installed, you can set up a git alias: - $ git config --global alias.pr '!sh -c "git fetch upstream pull/${1}/head:pr_${1} && git checkout pr_${1}" -' +.. tab:: Unix/macOS -On Windows, reverse the single (``'``) and double (``"``) quotes: + .. code-block:: shell -.. code-block:: bash + $ git config --global alias.pr '!sh -c "git fetch upstream pull/${1}/head:pr_${1} && git checkout pr_${1}" -' + +.. tab:: Windows + + .. code-block:: dosbatch - git config --global alias.pr "!sh -c 'git fetch upstream pull/${1}/head:pr_${1} && git checkout pr_${1}' -" + git config --global alias.pr "!sh -c 'git fetch upstream pull/${1}/head:pr_${1} && git checkout pr_${1}' -" The alias only needs to be done once. After the alias is set up, you can get a local copy of a pull request as follows:: From 1909f672d0416614dd739a041df0687ac54bc482 Mon Sep 17 00:00:00 2001 From: Lance Goyke Date: Wed, 22 Nov 2023 23:42:09 -0600 Subject: [PATCH 237/538] Add inline tabs on Documentation Getting Started page for commands on different systems (#1224) --- documentation/start-documenting.rst | 97 +++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 26 deletions(-) diff --git a/documentation/start-documenting.rst b/documentation/start-documenting.rst index 817f0a1cf..fec76fa97 100644 --- a/documentation/start-documenting.rst +++ b/documentation/start-documenting.rst @@ -5,6 +5,14 @@ Getting started =============== +.. raw:: html + + + .. highlight:: rest The Python language has a substantial body of documentation, much of it @@ -81,22 +89,24 @@ Create a virtual environment ---------------------------- .. _doc-create-venv-unix: +.. _doc-create-venv-windows: -**On Unix platforms** that support :program:`make` -(including Linux, macOS and BSD), -you can create a new :mod:`venv` with the required dependencies using:: +You can create a new :mod:`venv` with the required dependencies using: - make venv +.. tab:: Unix/macOS -Building the docs with :program:`make` will automatically use this environment -without you having to activate it. + .. code-block:: shell -.. _doc-create-venv-windows: + make venv + + Building the docs with :program:`make` will automatically use this environment + without you having to activate it. + +.. tab:: Windows -**On Windows**, or if not using :program:`make`, -`create a new virtual environment `__ manually. -Always be sure to `activate this environment `__ -before building the documentation. + `Create a new virtual environment `__ manually. + Always be sure to `activate this environment `__ + before building the documentation. .. _building-using-make: @@ -106,21 +116,36 @@ before building the documentation. Build using make / make.bat --------------------------- -A Unix ``Makefile`` is provided, :cpy-file:`Doc/Makefile`, -along with a :cpy-file:`Doc/make.bat` batch file for Windows -that attempts to emulate it as closely as practical. +.. tab:: Unix/macOS + + A Unix ``Makefile`` is provided, :cpy-file:`Doc/Makefile`. + +.. tab:: Windows + + A Windows ``make.bat`` is provided, :cpy-file:`Doc/make.bat`, which + attempts to emulate the Unix ``Makefile`` as closely as practical. + + .. important:: + + The Windows ``make.bat`` batch file lacks a ``make venv`` target. + Instead, it automatically installs any missing dependencies + into the currently activated environment (or the base Python, if none). + Make sure the environment you :ref:`created above ` + is `activated `__ before running ``make.bat``. + +To build the docs as HTML, run: -.. important:: +.. tab:: Unix/macOS - The Windows ``make.bat`` batch file lacks a ``make venv`` target. - Instead, it automatically installs any missing dependencies - into the currently activated environment (or the base Python, if none). - Make sure the environment you :ref:`created above ` - is `activated `__ before running ``make.bat``. + .. code-block:: shell -To build the docs as HTML, run:: + make html - make html +.. tab:: Windows + + .. code-block:: dosbatch + + .\make html .. tip:: * Replace ``html`` with ``htmlview`` to open the docs in a web browser once the build completes. @@ -129,13 +154,33 @@ To build the docs as HTML, run:: browser when you make changes to reST files (Unix only). To check the docs for common errors with `Sphinx Lint`_ -(which is run on all :ref:`pull requests `), use:: +(which is run on all :ref:`pull requests `), use: + +.. tab:: Unix/macOS + + .. code-block:: shell + + make check + +.. tab:: Windows + + .. code-block:: dosbatch + + .\make check + +To list other supported :program:`make` targets, run: + +.. tab:: Unix/macOS + + .. code-block:: shell + + make help - make check +.. tab:: Windows -To list other supported :program:`make` targets, run:: + .. code-block:: dosbatch - make help + .\make help See :cpy-file:`Doc/README.rst` for more information. From 6d96e576519ff26ad0e3f0d0fa432fd35a16eb65 Mon Sep 17 00:00:00 2001 From: Lance Goyke Date: Wed, 22 Nov 2023 23:42:54 -0600 Subject: [PATCH 238/538] Add inline tabs on Setup and Building page for commands on different systems (#1226) --- getting-started/setup-building.rst | 202 +++++++++++++++-------------- 1 file changed, 104 insertions(+), 98 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index e1a53a498..7a2cf702a 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -5,6 +5,14 @@ Setup and building ================== +.. raw:: html + + + .. highlight:: console These instructions cover how to get a working copy of the source code and a @@ -257,7 +265,6 @@ to learn more about these options. $ ./configure --enable-optimizations --with-lto - .. _windows-compiling: Windows @@ -339,156 +346,155 @@ and how to build. .. _build-dependencies: +.. _deps-on-linux: +.. _macOS and OS X: +.. _macOS: Install dependencies ==================== This section explains how to install additional extensions (e.g. ``zlib``) -on :ref:`Linux ` and :ref:`macOS`. On Windows, -extensions are already included and built automatically. +on :ref:`Linux ` and :ref:`macOS`. -.. _deps-on-linux: +.. tab:: Linux -Linux ------ + For Unix-based systems, we try to use system libraries whenever available. + This means optional components will only build if the relevant system headers + are available. The best way to obtain the appropriate headers will vary by + distribution, but the appropriate commands for some popular distributions + are below. -For Unix-based systems, we try to use system libraries whenever available. -This means optional components will only build if the relevant system headers -are available. The best way to obtain the appropriate headers will vary by -distribution, but the appropriate commands for some popular distributions -are below. + On **Fedora**, **Red Hat Enterprise Linux** and other ``yum`` based systems:: -On **Fedora**, **Red Hat Enterprise Linux** and other ``yum`` based systems:: + $ sudo yum install yum-utils + $ sudo yum-builddep python3 - $ sudo yum install yum-utils - $ sudo yum-builddep python3 + On **Fedora** and other ``DNF`` based systems:: -On **Fedora** and other ``DNF`` based systems:: + $ sudo dnf install dnf-plugins-core # install this to use 'dnf builddep' + $ sudo dnf builddep python3 - $ sudo dnf install dnf-plugins-core # install this to use 'dnf builddep' - $ sudo dnf builddep python3 + On **Debian**, **Ubuntu**, and other ``apt`` based systems, try to get the + dependencies for the Python you're working on by using the ``apt`` command. -On **Debian**, **Ubuntu**, and other ``apt`` based systems, try to get the -dependencies for the Python you're working on by using the ``apt`` command. + First, make sure you have enabled the source packages in the sources list. + You can do this by adding the location of the source packages, including + URL, distribution name and component name, to ``/etc/apt/sources.list``. + Take Ubuntu 22.04 LTS (Jammy Jellyfish) for example:: -First, make sure you have enabled the source packages in the sources list. -You can do this by adding the location of the source packages, including -URL, distribution name and component name, to ``/etc/apt/sources.list``. -Take Ubuntu 22.04 LTS (Jammy Jellyfish) for example:: + deb-src http://archive.ubuntu.com/ubuntu/ jammy main - deb-src http://archive.ubuntu.com/ubuntu/ jammy main + Alternatively, uncomment lines with ``deb-src`` using an editor, e.g.:: -Alternatively, uncomment lines with ``deb-src`` using an editor, e.g.:: + sudo nano /etc/apt/sources.list - sudo nano /etc/apt/sources.list + For other distributions, like Debian, change the URL and names to correspond + with the specific distribution. -For other distributions, like Debian, change the URL and names to correspond -with the specific distribution. + Then you should update the packages index:: -Then you should update the packages index:: + $ sudo apt-get update - $ sudo apt-get update + Now you can install the build dependencies via ``apt``:: -Now you can install the build dependencies via ``apt``:: + $ sudo apt-get build-dep python3 + $ sudo apt-get install pkg-config - $ sudo apt-get build-dep python3 - $ sudo apt-get install pkg-config + If you want to build all optional modules, install the following packages and + their dependencies:: -If you want to build all optional modules, install the following packages and -their dependencies:: + $ 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 - $ 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 +.. tab:: macOS -.. _macOS and OS X: -.. _macOS: + For **macOS systems** (versions 10.9+), + the Developer Tools can be downloaded and installed automatically; + you do not need to download the complete Xcode application. -macOS ------ + If necessary, run the following:: -For **macOS systems** (versions 10.9+), -the Developer Tools can be downloaded and installed automatically; -you do not need to download the complete Xcode application. + $ xcode-select --install -If necessary, run the following:: + This will also ensure that the system header files are installed into + ``/usr/include``. - $ xcode-select --install + .. _Homebrew: https://brew.sh -This will also ensure that the system header files are installed into -``/usr/include``. + .. _MacPorts: https://www.macports.org -.. _Homebrew: https://brew.sh + Also note that macOS does not include several libraries used by the Python + standard library, including ``libzma``, so expect to see some extension module + build failures unless you install local copies of them. As of OS X 10.11, + Apple no longer provides header files for the deprecated system version of + OpenSSL which means that you will not be able to build the ``_ssl`` extension. + One solution is to install these libraries from a third-party package + manager, like Homebrew_ or MacPorts_, and then add the appropriate paths + for the header and library files to your ``configure`` command. -.. _MacPorts: https://www.macports.org + For example, with **Homebrew**, install the dependencies:: -Also note that macOS does not include several libraries used by the Python -standard library, including ``libzma``, so expect to see some extension module -build failures unless you install local copies of them. As of OS X 10.11, -Apple no longer provides header files for the deprecated system version of -OpenSSL which means that you will not be able to build the ``_ssl`` extension. -One solution is to install these libraries from a third-party package -manager, like Homebrew_ or MacPorts_, and then add the appropriate paths -for the header and library files to your ``configure`` command. + $ brew install pkg-config openssl@3.0 xz gdbm tcl-tk -For example, with **Homebrew**, install the dependencies:: + Then, for Python 3.11 and newer, run ``configure``:: - $ brew install pkg-config openssl@3.0 xz gdbm tcl-tk + $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ + GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ + ./configure --with-pydebug \ + --with-openssl="$(brew --prefix openssl@3.0)" -Then, for Python 3.11 and newer, run ``configure``:: + Or, for Python 3.8 through 3.10:: - $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ - GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ - ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@3.0)" + $ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ + LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ + ./configure --with-pydebug \ + --with-openssl="$(brew --prefix openssl@3.0)" \ + --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ + --with-tcltk-includes="$(pkg-config --cflags tcl tk)" -Or, for Python 3.8 through 3.10:: + And finally, run ``make``:: - $ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ - LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ - ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@3.0)" \ - --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ - --with-tcltk-includes="$(pkg-config --cflags tcl tk)" + $ make -s -j2 -And finally, run ``make``:: + Alternatively, with **MacPorts**:: - $ make -s -j2 + $ sudo port install pkgconfig openssl xz gdbm tcl tk +quartz -Alternatively, with **MacPorts**:: + Then, for Python 3.11 and newer, run ``configure``:: - $ sudo port install pkgconfig openssl xz gdbm tcl tk +quartz + $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ + GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ + ./configure --with-pydebug -Then, for Python 3.11 and newer, run ``configure``:: + And finally, run ``make``:: - $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ - GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ - ./configure --with-pydebug + $ make -s -j2 -And finally, run ``make``:: + There will sometimes be optional modules added for a new release which + won't yet be identified in the OS-level build dependencies. In those cases, + just ask for assistance in the *Core Development* category on :ref:`help-discourse`. - $ make -s -j2 + Explaining how to build optional dependencies on a Unix-based system without + root access is beyond the scope of this guide. -There will sometimes be optional modules added for a new release which -won't yet be identified in the OS-level build dependencies. In those cases, -just ask for assistance in the *Core Development* category on :ref:`help-discourse`. + For more details on various options and considerations for building, refer + to the `macOS README + `_. -Explaining how to build optional dependencies on a Unix-based system without -root access is beyond the scope of this guide. + .. _clang: https://clang.llvm.org/ + .. _ccache: https://ccache.dev/ -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 + written completely in Python: as of this writing, CPython contains slightly + more Python code than C. -.. _clang: https://clang.llvm.org/ -.. _ccache: https://ccache.dev/ +.. tab:: Windows -.. 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 - written completely in Python: as of this writing, CPython contains slightly - more Python code than C. + On Windows, extensions are already included and built automatically. .. _regenerate_configure: From 40d64736a8e59449adaa021343e9a71bef7b2116 Mon Sep 17 00:00:00 2001 From: Lance Goyke Date: Wed, 22 Nov 2023 23:43:26 -0600 Subject: [PATCH 239/538] Add inline tabs on Increase Test Coverage page for commands on different systems (#1228) --- testing/coverage.rst | 86 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 18 deletions(-) diff --git a/testing/coverage.rst b/testing/coverage.rst index 0ebaf4b02..f0da94349 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -4,6 +4,14 @@ Increase test coverage ====================== +.. raw:: html + + + Python development follows a practice that all semantic changes and additions to the language and :abbr:`stdlib (standard library)` are accompanied by appropriate unit tests. Unfortunately Python was in existence for a long time @@ -87,23 +95,35 @@ just built, and this built version of Python will not see packages installed into your default version of Python. One option is to use a virtual environment to install coverage. -On Unix run:: +.. tab:: Unix + + Run: + + .. code-block:: shell + + ./python -m venv ../cpython-venv + source ../cpython-venv/bin/activate + pip install coverage + +.. tab:: macOS - ./python -m venv ../cpython-venv - source ../cpython-venv/bin/activate - pip install coverage + On :ref:`most ` macOS systems run: -On :ref:`most ` macOS systems run:: + .. code-block:: shell - ./python.exe -m venv ../cpython-venv - source ../cpython-venv/bin/activate - pip install coverage + ./python.exe -m venv ../cpython-venv + source ../cpython-venv/bin/activate + pip install coverage -On Windows run:: +.. tab:: Windows - python.bat -m venv ..\\cpython-venv - ..\\cpython-venv\\Scripts\\activate.bat - pip install coverage + Run: + + .. code-block:: dosbatch + + python.bat -m venv ..\\cpython-venv + ..\\cpython-venv\\Scripts\\activate.bat + pip 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 @@ -231,19 +251,49 @@ Measuring coverage of C code with gcov and lcov It's also possible to measure the function, line and branch coverage of Python's C code. Right now only GCC with `gcov`_ is supported. In order to -create an instrumented build of Python with gcov, run:: +create an instrumented build of Python with gcov, run: + +.. tab:: Unix/macOS + + .. code-block:: shell + + make coverage + +.. tab:: Windows - make coverage + .. code-block:: dosbatch + + .\make coverage Then run some code and gather coverage data with the ``gcov`` command. In -order to create a HTML report you can install `lcov`_. The command:: +order to create a HTML report you can install `lcov`_. The command: + +.. tab:: Unix/macOS + + .. code-block:: shell + + make coverage-lcov + +.. tab:: Windows + + .. code-block:: dosbatch - make coverage-lcov + .\make coverage-lcov assembles coverage data, removes 3rd party and system libraries and finally -creates a report. You can skip both steps and just run:: +creates a report. You can skip both steps and just run: + +.. tab:: Unix/macOS + + .. code-block:: shell + + make coverage-report + +.. tab:: Windows + + .. code-block:: dosbatch - make coverage-report + .\make coverage-report if you like to generate a coverage report for Python's stdlib tests. It takes about 20 to 30 minutes on a modern computer. From f73a918bc97a163a237a7fa86624f288ff427a93 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Fri, 24 Nov 2023 11:33:58 +0100 Subject: [PATCH 240/538] Bump sphinx-lint from 0.8.1 to 0.8.2 (#1218) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 036517fe0..f9f0b5073 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ furo>=2022.6.4 jinja2 sphinx-autobuild sphinx-inline-tabs>=2023.4.21 -sphinx-lint==0.8.1 +sphinx-lint==0.8.2 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 From a9aaedfafa03675ad4b4f0b41f42bc1258adbe37 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 26 Nov 2023 15:50:34 +0200 Subject: [PATCH 241/538] Add 'C API' to the style guide (#1222) --- documentation/style-guide.rst | 4 ++++ internals/parser.rst | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index d9f04526e..eb18feb9d 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -74,6 +74,10 @@ presentation in the Python documentation. Other terms and words deserve special mention as well; these conventions should be used to ensure consistency throughout the documentation: +C API + Python's `API `_ used by C programmers + to write extension modules. All caps and unhyphenated. + CPU For "central processing unit." Many style guides say this should be spelled out on the first use (and if you must use it, do so!). For diff --git a/internals/parser.rst b/internals/parser.rst index 9e2f21656..2b9a8df03 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -711,7 +711,7 @@ When a pegen-generated parser detects that an exception is raised, it will is and it will unwind the stack and report the exception. This means that if a :ref:`rule action ` raises an exception all parsing will stop at that exact point. This is done to allow to correctly propagate any -exception set by calling Python C-API functions. This also includes :exc:`SyntaxError` +exception set by calling Python's C API functions. This also includes :exc:`SyntaxError` exceptions and this is the main mechanism the parser uses to report custom syntax error messages. From 7e9a4153ec5884ff655348032086b3207a605702 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Wed, 29 Nov 2023 18:22:15 +0100 Subject: [PATCH 242/538] Add `-j auto` to the Makefile. (#1220) * Add `-j auto` to the Makefile. * One option per line. Co-authored-by: Hugo van Kemenade --------- Co-authored-by: Hugo van Kemenade --- Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index da382ea67..359ee297a 100644 --- a/Makefile +++ b/Makefile @@ -4,19 +4,22 @@ # You can set these variables from the command line. PYTHON = python3 VENVDIR = ./venv -BUILDDIR = _build -SPHINXOPTS = -W --keep-going SPHINXBUILD = $(VENVDIR)/bin/sphinx-build +SPHINXOPTS = -W --keep-going +BUILDDIR = _build BUILDER = html -SPHINXLINT = $(VENVDIR)/bin/sphinx-lint +JOBS = auto PAPER = +SPHINXLINT = $(VENVDIR)/bin/sphinx-lint # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -b $(BUILDER) \ -d $(BUILDDIR)/doctrees \ - $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) \ + -j $(JOBS) \ + $(PAPEROPT_$(PAPER)) \ + $(SPHINXOPTS) \ . $(BUILDDIR)/$(BUILDER) .PHONY: help From 01adb831d4d88f19ba2198dc82dddb94d192dc6f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 30 Nov 2023 11:01:18 +0200 Subject: [PATCH 243/538] `make htmllive`: open browser when ready (#1233) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 359ee297a..e394e0d4b 100644 --- a/Makefile +++ b/Makefile @@ -164,7 +164,7 @@ htmlview: html .PHONY: htmllive htmllive: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild -htmllive: SPHINXOPTS = --re-ignore="/\.idea/|/venv/" +htmllive: SPHINXOPTS = --re-ignore="/\.idea/|/venv/" --open-browser --delay 0 htmllive: html .PHONY: check From e8a65770008204dd48dfaca65064e15aeced8898 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 30 Nov 2023 13:06:59 +0000 Subject: [PATCH 244/538] Add "how to" for the getter Argument Clinic directive. (#1232) --------- Co-authored-by: Hugo van Kemenade Co-authored-by: Erlend E. Aasland Co-authored-by: Ezio Melotti Co-authored-by: Alex Waygood --- development-tools/clinic.rst | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index aa0efddd6..5bc4e03f1 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -2001,6 +2001,56 @@ The generated glue code looks like this: .. versionadded:: 3.13 +.. _clinic-howto-getter: + +How to generate a getter +------------------------ + +"Getters" are C functions that facilitate property-like access for a class. +See :c:type:`getter ` for details. +You can use the ``@getter`` directive to generate an "impl" function for a +getter using Argument Clinic. + +This example -- taken from :cpy-file:`Modules/_io/bufferedio.c` -- +shows the use of ``@getter`` in combination with +the :ref:`@critical_section ` directive +(which achieves thread safety without causing deadlocks between threads):: + + /*[clinic input] + @critical_section + @getter + _io._Buffered.closed + [clinic start generated code]*/ + +The generated glue code looks like this: + +.. code-block:: c + + static PyObject * + _io__Buffered_closed_get(buffered *self, void *context) + { + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_closed_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; + } + +And then the implementation will work the same as a Python method which is +decorated by :py:class:`property`. + +.. code-block:: pycon + + >>> import _io + >>> a = _io._BufferedIOBase() + >>> a.closed + False + +.. versionadded:: 3.13 + + .. _clinic-howto-deprecate-positional: .. _clinic-howto-deprecate-keyword: From 366b6151dad6b4d8fb047b9e63919644e7dc5900 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Dec 2023 02:57:53 +0100 Subject: [PATCH 245/538] Bump sphinx-lint from 0.8.2 to 0.9.0 (#1234) Bumps [sphinx-lint](https://github.com/sphinx-contrib/sphinx-lint) from 0.8.2 to 0.9.0. - [Release notes](https://github.com/sphinx-contrib/sphinx-lint/releases) - [Commits](https://github.com/sphinx-contrib/sphinx-lint/compare/v0.8.2...v0.9.0) --- updated-dependencies: - dependency-name: sphinx-lint dependency-type: direct:production update-type: version-update:semver-minor ... 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 f9f0b5073..5c91a1dac 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ furo>=2022.6.4 jinja2 sphinx-autobuild sphinx-inline-tabs>=2023.4.21 -sphinx-lint==0.8.2 +sphinx-lint==0.9.0 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 From 73842ead040573a93d6ed5deed36c89636688413 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 1 Dec 2023 16:22:27 +0200 Subject: [PATCH 246/538] Consistent console formatting for "Git bootcamp and cheat sheet" (#1231) --- getting-started/git-boot-camp.rst | 176 ++++++++++++++++-------------- 1 file changed, 92 insertions(+), 84 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index c38857e57..2bd4c8658 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -57,12 +57,12 @@ Cloning a forked CPython repository You will only need to do this once per machine. From your command line:: - git clone git@github.com:/cpython.git + $ git clone git@github.com:/cpython.git It is also recommended to configure an ``upstream`` remote repository:: - cd cpython - git remote add upstream https://github.com/python/cpython + $ cd cpython + $ git remote add upstream https://github.com/python/cpython You can also use SSH-based or HTTPS-based URLs. @@ -74,22 +74,24 @@ Configure the remotes Configure ``git`` to pull ``main`` from the ``upstream`` remote:: - git config --local branch.main.remote upstream + $ git config --local branch.main.remote upstream Since one should never attempt to push to ``upstream``, configure ``git`` to push always to ``origin``:: - git remote set-url --push upstream git@github.com:/cpython.git + $ git remote set-url --push upstream git@github.com:/cpython.git Listing the remote repositories ------------------------------- To list the remote repositories that are configured, along with their URLs:: - git remote -v + $ git remote -v You should have two remote repositories: ``origin`` pointing to your forked CPython repository, -and ``upstream`` pointing to the official CPython repository:: +and ``upstream`` pointing to the official CPython repository: + +.. code-block:: text origin git@github.com:/cpython.git (fetch) origin git@github.com:/cpython.git (push) @@ -98,7 +100,7 @@ and ``upstream`` pointing to the official CPython repository:: To verify the upstream for ``main``:: - git config branch.main.remote + $ git config branch.main.remote It should emit ``upstream``, indicating to track/pull changes for ``main`` from the ``upstream`` remote. @@ -109,10 +111,10 @@ It should emit ``upstream``, indicating to track/pull changes for ``main`` from Setting up your name and email address -------------------------------------- -.. code-block:: bash +:: - git config --global user.name "Your Name" - git config --global user.email your.email@example.com + $ git config --global user.name "Your Name" + $ git config --global user.email your.email@example.com The ``--global`` flag sets these parameters globally while the ``--local`` flag sets them only for the current project. @@ -126,7 +128,7 @@ The ``autocrlf`` option will fix automatically any Windows-specific line endings This should be enabled on Windows, since the public repository has a hook which will reject all changesets having the wrong line endings:: - git config --global core.autocrlf input + $ git config --global core.autocrlf input Creating and switching branches ------------------------------- @@ -136,34 +138,34 @@ Creating and switching branches Create a new branch from ``main`` and switch to it:: - git switch -c main + $ git switch -c main This is equivalent to:: - # create a new branch from main - git branch main - # switch to the new branch - git switch + $ # create a new branch from main + $ git branch main + $ # switch to the new branch + $ git switch To find the branch you are currently on:: - git branch + $ git branch The current branch will have an asterisk next to the branch name. Note, this will only list all of your local branches. To list all the branches, including the remote branches:: - git branch -a + $ git branch -a To switch to a different branch:: - git switch + $ git switch Other releases are just branches in the repository. For example, to work on the 2.7 release from the ``upstream`` remote:: - git switch -c 2.7 upstream/2.7 + $ git switch -c 2.7 upstream/2.7 .. _deleting_branches: @@ -172,12 +174,12 @@ Deleting branches To delete a **local** branch that you no longer need:: - git switch main - git branch -D + $ git switch main + $ git branch -D To delete a **remote** branch:: - git push origin -d + $ git push origin -d You may specify more than one branch for deletion. @@ -198,10 +200,10 @@ these GitHub instructions # to add new files + $ git add -p # to review and add changes to existing files + $ git add # to add new files 3. To commit the files that have been staged (done in step 2): @@ -240,23 +242,23 @@ Reverting changes To revert changes to a file that has not been committed yet:: - git checkout + $ git checkout If the change has been committed, and now you want to reset it to whatever the origin is at:: - git reset --hard HEAD + $ git reset --hard HEAD Stashing changes ---------------- To stash away changes that are not ready to be committed yet:: - git stash + $ git stash To re-apply the last stashed change:: - git stash pop + $ git stash pop .. _diff-changes: @@ -265,21 +267,21 @@ Comparing changes View all non-commited changes:: - git diff + $ git diff Compare to the ``main`` branch:: - git diff main + $ git diff main Exclude generated files from diff using an ``attr`` `pathspec `_ (note the single quotes):: - git diff main ':(attr:!generated)' + $ git diff main ':(attr:!generated)' Exclude generated files from diff by default:: - git config diff.generated.binary true + $ git config diff.generated.binary true The ``generated`` `attribute `_ is defined in :cpy-file:`.gitattributes`, found in the repository root. @@ -294,8 +296,8 @@ them to the remote repository. :: - git switch - git push origin + $ git switch + $ git push origin Creating a pull request ----------------------- @@ -353,9 +355,9 @@ get notified unnecessarily. Solution:: - git switch main - git pull upstream main - git push origin main + $ git switch main + $ git pull upstream main + $ git push origin main .. note:: For the above commands to work, please follow the instructions found in the :ref:`checkout` section. @@ -371,10 +373,10 @@ Another scenario: Solution:: - git switch some-branch - git fetch upstream - git merge upstream/main - git push origin some-branch + $ git switch some-branch + $ git fetch upstream + $ git merge upstream/main + $ git push origin some-branch You may see error messages like "CONFLICT" and "Automatic merge failed;" when you run ``git merge upstream/main``. @@ -402,12 +404,10 @@ Solution: git apply /path/to/patch.diff If there are errors, update to a revision from when the patch was - created and then try the ``git apply`` again: + created and then try the ``git apply`` again:: - .. code-block:: bash - - git checkout $(git rev-list -n 1 --before="yyyy-mm-dd hh:mm:ss" main) - git apply /path/to/patch.diff + $ git checkout $(git rev-list -n 1 --before="yyyy-mm-dd hh:mm:ss" main) + $ git apply /path/to/patch.diff If the patch still won't apply, then a patch tool will not be able to apply the patch and it will need to be re-implemented manually. @@ -419,8 +419,8 @@ Solution: 5. If the patch was applied to an old revision, it needs to be updated and merge conflicts need to be resolved:: - git rebase main - git mergetool + $ git rebase main + $ git mergetool For very old changes, ``git merge --no-ff`` may be easier than a rebase, with regards to resolving conflicts. @@ -464,7 +464,7 @@ If you don't have GitHub CLI or hub installed, you can set up a git alias: The alias only needs to be done once. After the alias is set up, you can get a local copy of a pull request as follows:: - git pr + $ git pr .. _accepting-and-merging-a-pr: @@ -489,14 +489,18 @@ in place of the gray ``Enable auto-merge`` button you will find a green In either case, adjust and clean up the commit message. -Here's an example of a **good** commit message:: +Here's an example of a **good** commit message: + +.. code-block:: text gh-12345: Improve the spam module (GH-777) * Add method A to the spam module * Update the documentation of the spam module -Here's an example of a **bad** commit message:: +Here's an example of a **bad** commit message: + +.. code-block:: text gh-12345: Improve the spam module (#777) @@ -549,19 +553,19 @@ repository to backport the commit. The commit hash for backporting is the squashed commit that was merged to the ``main`` branch. On the merged pull request, scroll to the bottom of the -page. Find the event that says something like:: +page. Find the event that says something like: + +.. code-block:: text merged commit into python:main ago. By following the link to ````, you will get the full commit hash. Alternatively, the commit hash can also be obtained by the following Git -commands: - -.. code-block:: bash +commands:: - git fetch upstream - git rev-parse ":/gh-12345" + $ git fetch upstream + $ git rev-parse ":/gh-12345" The above commands will print out the hash of the commit containing ``"gh-12345"`` as part of the commit message. @@ -569,7 +573,9 @@ The above commands will print out the hash of the commit containing When formatting the commit message for a backport commit: leave the original one as is and delete the number of the backport pull request. -Example of good backport commit message:: +Example of good backport commit message: + +.. code-block:: text gh-12345: Improve the spam module (GH-777) @@ -578,7 +584,9 @@ Example of good backport commit message:: (cherry picked from commit 62adc55) -Example of bad backport commit message:: +Example of bad backport commit message: + +.. code-block:: text gh-12345: Improve the spam module (GH-777) (#888) @@ -599,30 +607,30 @@ items like updating ``Misc/ACKS``. To edit an open pull request that targets ``main``: 1. In the pull request page, under the description, there is some information - about the contributor's forked CPython repository and branch name that will be useful later:: + about the contributor's forked CPython repository and branch name that will be useful later: + +.. code-block:: text wants to merge 1 commit into python:main from : 2. Fetch the pull request, using the :ref:`git pr ` alias:: - git pr + $ git pr This will checkout the contributor's branch at ````. 3. Make and commit your changes on the branch. For example, merge in changes made to ``main`` since the PR was submitted (any merge commits will be - removed by the later ``Squash and Merge`` when accepting the change): - - .. code-block:: bash + removed by the later ``Squash and Merge`` when accepting the change):: - git fetch upstream - git merge upstream/main - git add - git commit -m "" + $ git fetch upstream + $ git merge upstream/main + $ git add + $ git commit -m "" 4. Push the changes back to the contributor's PR branch:: - git push git@github.com:/cpython : + $ git push git@github.com:/cpython : 5. Optionally, :ref:`delete the PR branch `. @@ -638,22 +646,22 @@ You can install GitHub CLI `by following these instructions `_. After installing, you need to authenticate:: - gh auth login + $ gh auth login Examples of useful commands: * Create a PR:: - gh pr create + $ gh pr create * Check out another PR:: - gh co + $ gh co * Set ``ssh`` as the Git protocol:: - gh config set git_protocol ssh + $ gh config set git_protocol ssh * Set the browser:: - gh config set browser + $ gh config set browser From 9f2b215c3d67816b69aeb1c3d6ae56c2b59b9aec Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 1 Dec 2023 20:08:24 +0200 Subject: [PATCH 247/538] Use emoji to illustrate good and bad example commit messages (#1235) --- getting-started/git-boot-camp.rst | 10 +++++----- index.rst | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 2bd4c8658..fd080320e 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -401,7 +401,7 @@ Solution: 2. Apply the patch:: - git apply /path/to/patch.diff + $ git apply /path/to/patch.diff If there are errors, update to a revision from when the patch was created and then try the ``git apply`` again:: @@ -489,7 +489,7 @@ in place of the gray ``Enable auto-merge`` button you will find a green In either case, adjust and clean up the commit message. -Here's an example of a **good** commit message: +✅ Here's an example of a **good** commit message: .. code-block:: text @@ -498,7 +498,7 @@ Here's an example of a **good** commit message: * Add method A to the spam module * Update the documentation of the spam module -Here's an example of a **bad** commit message: +❌ Here's an example of a **bad** commit message: .. code-block:: text @@ -573,7 +573,7 @@ The above commands will print out the hash of the commit containing When formatting the commit message for a backport commit: leave the original one as is and delete the number of the backport pull request. -Example of good backport commit message: +✅ Example of good backport commit message: .. code-block:: text @@ -584,7 +584,7 @@ Example of good backport commit message: (cherry picked from commit 62adc55) -Example of bad backport commit message: +❌ Example of bad backport commit message: .. code-block:: text diff --git a/index.rst b/index.rst index 0621180e7..779977963 100644 --- a/index.rst +++ b/index.rst @@ -116,7 +116,9 @@ instructions please see the :ref:`setup guide `. 7. Push the branch on your fork on GitHub and :ref:`create a pull request `. Include the issue number using ``gh-NNNN`` in the - pull request description. For example:: + pull request description. For example: + + .. code-block:: text gh-12345: Fix some bug in spam module From 4d757d28dfdc1a70c9ba70365b1722d85692a6eb Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 5 Dec 2023 15:21:44 -0800 Subject: [PATCH 248/538] Remove references to quay.io/tiran/cpython_autoconf (#1236) The `make regen-configure` does the right thing via containers already. --- getting-started/setup-building.rst | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 7a2cf702a..8dffcd5cd 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -513,27 +513,19 @@ After editing :file:`configure.ac`, run ``make regen-configure`` to generate When submitting a pull request with changes made to :file:`configure.ac`, make sure you also commit the changes in the generated files. -The recommended and by far the easiest way to regenerate :file:`configure` is:: - - $ make regen-configure - -If you are regenerating :file:`configure` in a clean repo, -run one of the following containers instead:: - - $ podman run --rm --pull=always -v $(pwd):/src:Z quay.io/tiran/cpython_autoconf:271 - -:: - - $ docker run --rm --pull=always -v $(pwd):/src quay.io/tiran/cpython_autoconf:271 - -Notice that the images are tagged with ``271``. Python's :file:`configure.ac` script requires a specific version of GNU Autoconf. For Python 3.12 and newer, GNU Autoconf v2.71 is required. For Python 3.11 and earlier, GNU Autoconf v2.69 is required. -For GNU Autoconf v2.69, change the ``:271`` tag to ``:269``. -If you cannot (or don't want to) use the ``cpython_autoconf`` containers, +The recommended and by far the easiest way to regenerate :file:`configure` is:: + + $ make regen-configure + +This will use Podman or Docker to do the regeneration with the proper version +of GNU Autoconf. + +If you cannot (or don't want to) use ``make regen-configure``, install the :program:`autoconf-archive` and :program:`pkg-config` utilities, and make sure the :file:`pkg.m4` macro file located in the appropriate :program:`aclocal` location:: From 0b52e7b30c47c6a8000e66e1d529d184ac70d293 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 6 Dec 2023 19:31:47 +0000 Subject: [PATCH 249/538] Updates to the experts index (#1240) --- core-developers/experts.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 34edccfd0..6f1b39787 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -103,7 +103,7 @@ dis 1st1 doctest tim-one (inactive) email warsaw, bitdancer*, maxking encodings malemburg -ensurepip ncoghlan, dstufft, pradyunsg +ensurepip ncoghlan, dstufft, pradyunsg, pfmoore enum eliben*, warsaw, ethanfurman* errno Yhg1s faulthandler vstinner, gpshead @@ -276,7 +276,7 @@ Tools ================== =========== Tool Maintainers ================== =========== -Argument Clinic larryhastings +Argument Clinic larryhastings, AlexWaygood*, erlend-aasland Deepfreeze gvanrossum, kumaraditya303 PEG Generator gvanrossum, pablogsal, lysnikolaou ================== =========== @@ -310,7 +310,7 @@ Miscellaneous Interest Area Maintainers ================== ========================================================== algorithms rhettinger* -argument clinic larryhastings +argument clinic larryhastings, AlexWaygood*, erlend-aasland ast/compiler benjaminp, 1st1, pablogsal, markshannon, isidentical, brandtbucher, carljm, iritkatriel autoconf/makefiles Yhg1s* bsd @@ -326,7 +326,7 @@ database malemburg devguide merwok, ezio-melotti, willingc, Mariatta, hugovk, AA-Turner documentation ezio-melotti, merwok, JulienPalard, willingc, hugovk, - AA-Turner + AA-Turner, AlexWaygood* emoji Mariatta extension modules encukou, ncoghlan filesystem giampaolo @@ -345,7 +345,8 @@ object model benjaminp, Yhg1s packaging tarekziade, malemburg, alexis^, merwok, dstufft, pfmoore pattern matching brandtbucher* peg parser gvanrossum, pablogsal, lysnikolaou -performance vstinner, serhiy-storchaka, 1st1, rhettinger, markshannon, brandtbucher, carljm, Fidget-Spinner +performance vstinner, serhiy-storchaka, 1st1, rhettinger, markshannon, brandtbucher, carljm, Fidget-Spinner, + AlexWaygood* pip ncoghlan, dstufft, pfmoore, Marcus.Smith^, pradyunsg py3 transition benjaminp release management tarekziade, malemburg, benjaminp, warsaw, From 477be7df956967c51615a3a6041b220c9a8cef79 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 6 Dec 2023 20:33:56 +0100 Subject: [PATCH 250/538] Lint: Fix subsubsection markups (#1239) Replace ' markup with recommendations from the style guide. --- core-developers/committing.rst | 6 ++-- developer-workflow/communication-channels.rst | 6 ++-- developer-workflow/development-cycle.rst | 36 +++++++++---------- developer-workflow/stdlib.rst | 8 +++-- documentation/markup.rst | 4 +-- getting-started/setup-building.rst | 4 +-- internals/parser.rst | 22 ++++++------ testing/coverage.rst | 6 ++-- 8 files changed, 47 insertions(+), 45 deletions(-) diff --git a/core-developers/committing.rst b/core-developers/committing.rst index 8b3ee2b3c..1b701a6b6 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -186,7 +186,7 @@ clone. .. _committing-active-branches: Seeing active branches -'''''''''''''''''''''' +^^^^^^^^^^^^^^^^^^^^^^ If you use ``git branch``, then you will see a :ref:`list of branches `. The only branch that receives new features is @@ -198,7 +198,7 @@ originate on ``main`` and then be ported back to older branches. .. _branch-merge: Backporting changes to an older version -''''''''''''''''''''''''''''''''''''''' +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If it is determined that a pull request needs to be backported into one or more of the maintenance branches, then a core developer can apply the label @@ -236,7 +236,7 @@ can apply labels to GitHub pull requests). Reverting a merged pull request -''''''''''''''''''''''''''''''' +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To revert a merged pull request, press the ``Revert`` button at the bottom of the pull request. That will bring up the page to create a diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 66b88e784..12e14889e 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -138,7 +138,7 @@ Notifications ------------- Following categories (category notifications) -''''''''''''''''''''''''''''''''''''''''''''' +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Notifications can be set for individual categories and topics. To change any of these defaults, you can either go to your user preferences, or visit the category @@ -151,7 +151,7 @@ All categories are set by default in Normal mode where you will only be notified if someone mentions your @name or replies to you. Following individual threads (topic notifications) -'''''''''''''''''''''''''''''''''''''''''''''''''' +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To follow any individual topics or threads, you can adjust your notifications through the notification button 🔔 found on the right of the topic at the end @@ -160,7 +160,7 @@ Select "Watching" and you will be notified when there is any new updated reply from that particular thread. Customising notifications on user preference -'''''''''''''''''''''''''''''''''''''''''''' +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To get a bird's eye view of all your customised notifications, you can go to `Preferences of your account `_. diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 613af736b..704098cdd 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -34,7 +34,7 @@ and *null* for final releases), and ``N`` is the release serial number. Some examples of release tags: ``v3.7.0a1``, ``v3.6.3``, ``v2.7.14rc1``. Branches -'''''''' +-------- There is a branch for each *feature version*, whether released or not (e.g. 3.7, 3.8). @@ -43,7 +43,7 @@ There is a branch for each *feature version*, whether released or not (e.g. .. _indevbranch: In-development (main) branch ----------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ``main`` branch is the branch for the next feature release; it is under active development for all kinds of changes: new features, semantic @@ -65,7 +65,7 @@ for release 3.n. .. _maintbranch: Maintenance branches --------------------- +^^^^^^^^^^^^^^^^^^^^ A branch for a previous feature release, currently being maintained for bug fixes, or for the next feature release in its @@ -104,7 +104,7 @@ which followed the release of 3.5.1. .. _secbranch: Security branches ------------------ +^^^^^^^^^^^^^^^^^ A branch less than 5 years old but no longer in bugfix mode is a security branch. @@ -126,7 +126,7 @@ security patches have been applied to the branch. These releases have a .. _eolbranch: End-of-life branches --------------------- +^^^^^^^^^^^^^^^^^^^^ The code base for a release cycle which has reached end-of-life status is frozen and no longer has a branch in the repo. The final state of @@ -141,7 +141,7 @@ The latest release for each Python version can be found on the `download page .. _stages: Stages -'''''' +------ Based on what stage the :ref:`in-development ` version of Python is in, the responsibilities of a core developer change in regards to commits @@ -149,7 +149,7 @@ to the :abbr:`VCS (version control system)`. Pre-alpha ---------- +^^^^^^^^^ The branch is in this stage when no official release has been done since the latest final release. There are no special restrictions placed on @@ -159,7 +159,7 @@ breaking the buildbots). .. _alpha: Alpha ------ +^^^^^ Alpha releases typically serve as a reminder to core developers that they need to start getting in changes that change semantics or add something to @@ -169,7 +169,7 @@ restrictions are in place while in alpha. .. _beta: Beta ----- +^^^^ After a first beta release is published, no new features are accepted. Only bug fixes and improvements to documentation and tests can now be committed. @@ -187,7 +187,7 @@ new information about the creation of the 3.5 maintenance branch during beta. .. _rc: Release Candidate (RC) ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ A branch preparing for an RC release can only have bugfixes applied that have been reviewed by other core developers. Generally, these issues must be @@ -206,7 +206,7 @@ a core developer. .. _final: Final ------ +^^^^^ When a final release is being cut, only the release manager (RM) can make changes to the branch. After the final release is published, the full @@ -214,13 +214,13 @@ changes to the branch. After the final release is published, the full Repository administration -''''''''''''''''''''''''' +------------------------- The source code is currently hosted on `GitHub `_ in the `Python organization `_. Organization repository policy ------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Within the `GitHub Python organization `_, repositories are expected to relate to the Python language, the CPython @@ -261,7 +261,7 @@ specifically want to “bless” one implementation (as with e.g. Organization owner policy -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ The GitHub Organization Owner role allows for full management of all aspects of the Python organization. Allowing for visibility and management of all aspects @@ -288,7 +288,7 @@ Owner of the Python Organization. .. _current owners: Current owners --------------- +^^^^^^^^^^^^^^ +----------------------+--------------------------------+-----------------+ | Name | Role | GitHub Username | @@ -314,7 +314,7 @@ mentioned to request assistance from an organization owner. .. _be performed: https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles Repository administrator role policy ------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The Administrator role on the repository allows for managing all aspects including collaborators, access control, integrations, webhooks, and branch @@ -335,7 +335,7 @@ Multi-Factor Authentication must be enabled by the user in order to remain an Administrator of the repository. Current administrators ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ +-------------------+----------------------------------------------------------+-----------------+ | Name | Role | GitHub Username | @@ -360,7 +360,7 @@ Current administrators +-------------------+----------------------------------------------------------+-----------------+ Repository release manager role policy --------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Release Managers for :ref:`in-development `, :ref:`maintenance `, and :ref:`security mode ` Python releases are diff --git a/developer-workflow/stdlib.rst b/developer-workflow/stdlib.rst index 9ead7d706..c9e1ab429 100644 --- a/developer-workflow/stdlib.rst +++ b/developer-workflow/stdlib.rst @@ -62,7 +62,8 @@ are not taken lightly. Acceptable types of modules -''''''''''''''''''''''''''' +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Typically two types of modules get added to the stdlib. One type is a module which implements something that is difficult to get right. A good example of this is the :py:mod:`multiprocessing` package. Working out the various OS @@ -83,7 +84,8 @@ it. Requirements -'''''''''''' +^^^^^^^^^^^^ + In order for a module to even be considered for inclusion into the stdlib, a couple of requirements must be met. @@ -121,7 +123,7 @@ uniform. Proposal process -'''''''''''''''' +^^^^^^^^^^^^^^^^ If the module you want to propose adding to the stdlib meets the requirements, you may propose its inclusion diff --git a/documentation/markup.rst b/documentation/markup.rst index 0f31e345d..7e237462c 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -165,14 +165,14 @@ Hyperlinks ---------- External links -'''''''''''''' +^^^^^^^^^^^^^^ 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. Internal links -'''''''''''''' +^^^^^^^^^^^^^^ Internal linking is done via a special reST role, see the section on specific markup, :ref:`doc-ref-role`. diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 8dffcd5cd..b2dc2f1c2 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -227,7 +227,7 @@ the interpreter you just built. Clang -''''' +^^^^^ If you are using clang_ to build CPython, some flags you might want to set to quiet some standard warnings which are specifically superfluous to CPython are @@ -246,7 +246,7 @@ still build properly). Optimization -'''''''''''' +^^^^^^^^^^^^ If you are trying to improve CPython's performance, you will probably want to use an optimized build of CPython. It can take a lot longer to build CPython diff --git a/internals/parser.rst b/internals/parser.rst index 2b9a8df03..db9922a80 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -161,12 +161,12 @@ Grammar expressions ------------------- ``# comment`` -''''''''''''' +^^^^^^^^^^^^^ Python-style comments. ``e1 e2`` -''''''''' +^^^^^^^^^ Match ``e1``, then match ``e2``. @@ -175,7 +175,7 @@ Match ``e1``, then match ``e2``. rule_name: first_rule second_rule ``e1 | e2`` -''''''''''' +^^^^^^^^^^^ Match ``e1`` or ``e2``. @@ -190,7 +190,7 @@ first alternative, like so: | second_alt ``( e )`` -''''''''' +^^^^^^^^^ Match ``e``. @@ -206,7 +206,7 @@ operator together with the repeat operators: rule_name: (e1 e2)* ``[ e ] or e?`` -''''''''''''''' +^^^^^^^^^^^^^^^ Optionally match ``e``. @@ -222,7 +222,7 @@ optional: rule_name: e (',' e)* [','] ``e*`` -'''''' +^^^^^^ Match zero or more occurrences of ``e``. @@ -231,7 +231,7 @@ Match zero or more occurrences of ``e``. rule_name: (e1 e2)* ``e+`` -'''''' +^^^^^^ Match one or more occurrences of ``e``. @@ -240,7 +240,7 @@ Match one or more occurrences of ``e``. rule_name: (e1 e2)+ ``s.e+`` -'''''''' +^^^^^^^^ Match one or more occurrences of ``e``, separated by ``s``. The generated parse tree does not include the separator. This is otherwise identical to @@ -251,14 +251,14 @@ tree does not include the separator. This is otherwise identical to rule_name: ','.e+ ``&e`` -'''''' +^^^^^^ .. _peg-positive-lookahead: Succeed if ``e`` can be parsed, without consuming any input. ``!e`` -'''''' +^^^^^^ .. _peg-negative-lookahead: @@ -273,7 +273,7 @@ consists of an atom, which is not followed by a ``.`` or a ``(`` or a primary: atom !'.' !'(' !'[' ``~`` -'''''' +^^^^^ Commit to the current alternative, even if it fails to parse (this is called the "cut"). diff --git a/testing/coverage.rst b/testing/coverage.rst index f0da94349..62f075148 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -88,7 +88,7 @@ provided by the stdlib then you can :ref:`use test.regrtest .. _install_coverage: Install coverage -'''''''''''''''' +^^^^^^^^^^^^^^^^ By default, pip will not install into the in-development version of Python you just built, and this built version of Python will not see packages installed @@ -143,7 +143,7 @@ it. For this, you will again need to use the full path to that installation. .. _coverage_usage: Basic usage -''''''''''' +^^^^^^^^^^^ The following command will tell you if your copy of coverage works (substitute ``COVERAGEDIR`` with the directory where your clone exists, e.g. @@ -197,7 +197,7 @@ with pages that visibly show what lines of code were or were not executed. .. _branch_coverage: Branch coverage -''''''''''''''' +^^^^^^^^^^^^^^^ For the truly daring, you can use another powerful feature of coverage.py: branch coverage. Testing every possible branch path through code, while a great From 44e62d50719f96f3594a96ec5aec39e6b1e209e7 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 7 Dec 2023 15:03:29 +0100 Subject: [PATCH 251/538] Rework the docs for NEWS/What's New entries (#1238) - Add links to CPython repo where appropriate - Add some information about how to word NEWS entries - Break up in subsubsections instead of keeping all the text in a single large subsection - Mention that test, docs, and strictly internal changes seldom require NEWS entries - Use more appropriate markup iso. double backticks Co-authored-by: Hugo van Kemenade Co-authored-by: Alex Waygood Co-authored-by: Ezio Melotti --- core-developers/committing.rst | 57 ++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/core-developers/committing.rst b/core-developers/committing.rst index 1b701a6b6..3b2a10302 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -80,21 +80,20 @@ to enter the public source tree. Ask yourself the following questions: Updating NEWS and What's New in Python -------------------------------------- -Almost all changes made to the code base deserve an entry in ``Misc/NEWS.d``. -If the change is particularly interesting for end users (e.g. new features, -significant improvements, or backwards-incompatible changes), then an entry in -the ``What's New in Python`` document (in ``Doc/whatsnew/``) should be added -as well. Changes that affect documentation only generally do not require -a ``NEWS`` entry. +Changes that require NEWS entries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -There are two notable exceptions to this general principle, and they -both relate to changes that: +Most changes made to the codebase deserve an entry in :cpy-file:`Misc/NEWS.d`, +except for the following: -* Already have a ``NEWS`` entry -* Have not yet been included in any formal release (including alpha - and beta releases) +* documentation changes +* test changes +* strictly internal changes with no user-visible effects +* changes that already have a ``NEWS`` entry +* reverts that have not yet been included in any formal release + (including alpha and beta releases) -These are the two exceptions: +For the last two, note the following: #. **If a change is reverted prior to release**, then the corresponding entry is simply removed. Otherwise, a new entry must be added noting @@ -105,8 +104,24 @@ These are the two exceptions: change and the original** ``NEWS`` **entry remains valid**, then no additional entry is needed. -If a change needs an entry in ``What's New in Python``, then it is very -likely not suitable for including in a maintenance release. +Changes that require "What's New in Python" entries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If a change is particularly interesting for end users (e.g. new features, +significant improvements, or backwards-incompatible changes), add an entry in +the "What's New in Python" document (in :cpy-file:`Doc/whatsnew/`) +in addition to the ``NEWS`` entry. + +In most cases, it is sufficient to reuse the wording from the ``NEWS`` entry +in the "What's New in Python" entry. + +.. note:: + + A change that needs an entry in "What's New in Python", + is very likely not suitable for inclusion in a maintenance release. + +How to add a NEWS entry +^^^^^^^^^^^^^^^^^^^^^^^ ``NEWS`` entries go into the ``Misc/NEWS.d`` directory as individual files. The ``NEWS`` entry can be created by using `blurb-it `_, @@ -132,6 +147,17 @@ to the standard library). The file name itself should be in the format As a result, a file name can look something like ``Misc/NEWS.d/next/Library/2017-05-27-16-46-23.gh-issue-12345.Yl4gI2.rst``. +How to write a NEWS entry +^^^^^^^^^^^^^^^^^^^^^^^^^ + +All ``NEWS`` entries end up being part of the changelog. +The changelog contains *a lot* of entries, +and its intended audience is mainly users, not core devs and contributors. +Take this into consideration when wording your ``NEWS`` entry. +Describe the user-visible effects of your change succinctly and accurately; +avoid long technical elaborations, digressions, and do not expect or require +the reader to have read the actual diff for the change. + The contents of a ``NEWS`` file should be valid reStructuredText. An 80 character column width should be used. There is no indentation or leading marker in the file (e.g. ``-``). There is also no need to start the entry with the issue @@ -146,9 +172,6 @@ The inline Sphinx roles like ``:func:`` can be used help readers find more information. You can build HTML and verify that the link target is appropriate by using :ref:`make html `. -While Sphinx roles can be beneficial to readers, they are not required. -Inline ````code blocks```` can be used instead. - Working with Git_ ----------------- From 53452a778552bef34fb656c30b64e25b32ceeab6 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 7 Dec 2023 22:00:56 +0200 Subject: [PATCH 252/538] Add green and red side border for good and bad examples (#1237) --- _static/devguide_overrides.css | 7 +++++++ getting-started/git-boot-camp.rst | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css index a8e96a43c..e86b6c177 100644 --- a/_static/devguide_overrides.css +++ b/_static/devguide_overrides.css @@ -78,3 +78,10 @@ fill: #2222EE; stroke: #008888; } + +.good pre { + border-left: 3px solid rgba(74, 182, 93, 1); +} +.bad pre { + border-left: 3px solid rgb(244, 76, 78); +} diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index fd080320e..3783f9141 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -492,6 +492,7 @@ In either case, adjust and clean up the commit message. ✅ Here's an example of a **good** commit message: .. code-block:: text + :class: good gh-12345: Improve the spam module (GH-777) @@ -501,6 +502,7 @@ In either case, adjust and clean up the commit message. ❌ Here's an example of a **bad** commit message: .. code-block:: text + :class: bad gh-12345: Improve the spam module (#777) @@ -576,6 +578,7 @@ one as is and delete the number of the backport pull request. ✅ Example of good backport commit message: .. code-block:: text + :class: good gh-12345: Improve the spam module (GH-777) @@ -587,6 +590,7 @@ one as is and delete the number of the backport pull request. ❌ Example of bad backport commit message: .. code-block:: text + :class: bad gh-12345: Improve the spam module (GH-777) (#888) From bb691251cbba381467de61b177cbbaaba228e74d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 8 Dec 2023 12:04:32 +0200 Subject: [PATCH 253/538] Remove/update references to EOL Python versions (#1227) --- development-tools/clinic.rst | 3 +-- development-tools/gdb.rst | 2 -- getting-started/git-boot-camp.rst | 4 ++-- testing/run-write-tests.rst | 3 --- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index 5bc4e03f1..fe1361e88 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -834,8 +834,7 @@ 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. And to be clear, their use is acceptable when porting code for -Python 3.4. +easier. However, in the long term we probably want all our blocks to use Argument Clinic's real syntax for converters. Why? A couple diff --git a/development-tools/gdb.rst b/development-tools/gdb.rst index 81bdb5201..cff419514 100644 --- a/development-tools/gdb.rst +++ b/development-tools/gdb.rst @@ -297,8 +297,6 @@ thread is doing at the Python level:: #8 Frame 0x7fffd00024a0, for file /home/david/coding/python-svn/Lib/test/lock_tests.py, line 378, in _check_notify (self=, skipped=[], _mirrorOutput=False, testsRun=39, buffer=False, _original_stderr=, _stdout_buffer=, _stderr_buffer=, _moduleSetUpFailed=False, expectedFailures=[], errors=[], _previousTestClass=, unexpectedSuccesses=[], failures=[], shouldStop=False, failfast=False) at remote 0xc185a0>, _threads=(0,), _cleanups=[], _type_equality_funcs={: , : , : , : , Other releases are just branches in the repository. For example, to work -on the 2.7 release from the ``upstream`` remote:: +on the 3.12 release from the ``upstream`` remote:: - $ git switch -c 2.7 upstream/2.7 + $ git switch -c 3.12 upstream/3.12 .. _deleting_branches: diff --git a/testing/run-write-tests.rst b/testing/run-write-tests.rst index 6fa9b04a5..c902a99f5 100644 --- a/testing/run-write-tests.rst +++ b/testing/run-write-tests.rst @@ -166,9 +166,6 @@ using several Python processes so as to speed up things: .\python.bat -m test -j0 -If you are running a version of Python prior to 3.3 you must specify the number -of processes to run simultaneously (e.g. ``-j2``). - .. _strenuous_testing: Finally, if you want to run tests under a more strenuous set of settings, you From b875489527875ab8e40d1cdb8a84697b1b2f6065 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 12 Dec 2023 19:01:04 +0200 Subject: [PATCH 254/538] Update pre-commit to fix Sphinx Lint (#1247) Co-authored-by: Jelle Zijlstra --- .pre-commit-config.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e6b335c32..bd8154adf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,18 +1,18 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.10.1 + rev: v3.15.0 hooks: - id: pyupgrade args: [--py38-plus] - - repo: https://github.com/psf/black - rev: 23.7.0 + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 23.12.0 hooks: - id: black args: [--skip-string-normalization] - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.1 hooks: - id: isort args: [--profile=black] @@ -24,7 +24,7 @@ repos: additional_dependencies: [flake8-2020] - repo: https://github.com/sphinx-contrib/sphinx-lint - rev: v0.6.7 + rev: v0.9.1 hooks: - id: sphinx-lint args: ["--enable=default-role"] @@ -35,7 +35,7 @@ repos: - id: python-check-blanket-noqa - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-json - id: check-merge-conflict From 2be71b8627b18a096ebe921ee0eadbfa706e2c0c Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Tue, 12 Dec 2023 23:31:51 +0000 Subject: [PATCH 255/538] Add explanation about @critical_section target directive (#1246) * Add explanation about @critical_section target directive * nit * Update development-tools/clinic.rst Co-authored-by: Erlend E. Aasland * Update development-tools/clinic.rst Co-authored-by: Ezio Melotti --------- Co-authored-by: Erlend E. Aasland Co-authored-by: Ezio Melotti --- development-tools/clinic.rst | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index fe1361e88..859294894 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -1996,6 +1996,36 @@ The generated glue code looks like this: 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 From 47d44b3a632f2723f270677d571179875f425ac0 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Wed, 13 Dec 2023 14:03:25 +0000 Subject: [PATCH 256/538] Add "how to" for the setter Argument Clinic directive (#1245) --------- Co-authored-by: Hugo van Kemenade Co-authored-by: Ezio Melotti Co-authored-by: Erlend E. Aasland Co-authored-by: Alex Waygood --- development-tools/clinic.rst | 58 +++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index 859294894..c2b18f4a2 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -2030,25 +2030,31 @@ The generated glue code looks like this: .. versionadded:: 3.13 -.. _clinic-howto-getter: +.. _clinic-howto-pygetsetdef: -How to generate a getter ------------------------- +How to declare ``PyGetSetDef`` ("getter/setter") functions +---------------------------------------------------------- -"Getters" are C functions that facilitate property-like access for a class. -See :c:type:`getter ` for details. -You can use the ``@getter`` directive to generate an "impl" function for a -getter using Argument Clinic. +"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/bufferedio.c` -- -shows the use of ``@getter`` in combination with +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._Buffered.closed + _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: @@ -2056,26 +2062,44 @@ The generated glue code looks like this: .. code-block:: c static PyObject * - _io__Buffered_closed_get(buffered *self, void *context) + _io_TextIOWrapper__CHUNK_SIZE_get(textio *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; Py_BEGIN_CRITICAL_SECTION(self); - return_value = _io__Buffered_closed_get_impl(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. + And then the implementation will work the same as a Python method which is -decorated by :py:class:`property`. +decorated by :py:class:`property`: .. code-block:: pycon - >>> import _io - >>> a = _io._BufferedIOBase() - >>> a.closed - False + >>> import sys, _io + >>> a = _io.TextIOWrapper(sys.stdout) + >>> a._CHUNK_SIZE + 8192 + >>> a._CHUNK_SIZE = 30 + >>> a._CHUNK_SIZE + 30 .. versionadded:: 3.13 From 78fc0d7aa9fd0d6733d10c23b178b2a0e2799afc Mon Sep 17 00:00:00 2001 From: Muhammad Mahad Date: Tue, 19 Dec 2023 13:19:43 +0500 Subject: [PATCH 257/538] Fix dead links to the tokenizer's source code (#1250) --- developer-workflow/grammar.rst | 2 +- internals/compiler.rst | 2 +- internals/parser.rst | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/developer-workflow/grammar.rst b/developer-workflow/grammar.rst index dfb6a2f9d..ee6bdbaa4 100644 --- a/developer-workflow/grammar.rst +++ b/developer-workflow/grammar.rst @@ -42,7 +42,7 @@ Note: sometimes things mysteriously don't work. Before giving up, try ``make cl Then run ``make regen-ast`` to regenerate :cpy-file:`Include/internal/pycore_ast.h` and :cpy-file:`Python/Python-ast.c`. -* :cpy-file:`Parser/tokenizer.c` contains the tokenization code. +* :cpy-file:`Parser/lexer/` contains the tokenization code. This is where you would add a new type of comment or string literal, for example. * :cpy-file:`Python/ast.c` will need changes to validate AST objects diff --git a/internals/compiler.rst b/internals/compiler.rst index 5dd949d9d..a4e8457c3 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -11,7 +11,7 @@ Abstract In CPython, the compilation from source code to bytecode involves several steps: -1. Tokenize the source code (:cpy-file:`Parser/tokenizer.c`). +1. Tokenize the source code (:cpy-file:`Parser/lexer/` and :cpy-file:`Parser/tokenizer/`). 2. Parse the stream of tokens into an Abstract Syntax Tree (:cpy-file:`Parser/parser.c`). 3. Transform AST into an instruction sequence (:cpy-file:`Python/compile.c`). diff --git a/internals/parser.rst b/internals/parser.rst index db9922a80..ac5f9ba49 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -599,8 +599,9 @@ If you are on Windows you can use the Visual Studio project files to regenerate ./PCbuild/build.bat --regen -How tokens are generated and the rules governing this is completely up to the tokenizer (:cpy-file:`Parser/tokenizer.c`) -and the parser just receives tokens from it. +How tokens are generated and the rules governing this are completely up to the tokenizer +(:cpy-file:`Parser/lexer/` and :cpy-file:`Parser/tokenizer/`); +the parser just receives tokens from it. Memoization ----------- From 4cbaee53777efc4ba4ef833cb5953f7b8275d977 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Tue, 19 Dec 2023 12:31:59 -0600 Subject: [PATCH 258/538] Add initial guide for maintaining Software Bill-of-Materials (#1251) Co-authored-by: Hugo van Kemenade Co-authored-by: Ezio Melotti --- developer-workflow/index.rst | 1 + developer-workflow/sbom.rst | 109 +++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 developer-workflow/sbom.rst diff --git a/developer-workflow/index.rst b/developer-workflow/index.rst index 23f1909c9..7b069021b 100644 --- a/developer-workflow/index.rst +++ b/developer-workflow/index.rst @@ -13,3 +13,4 @@ Development workflow lang-changes grammar porting + sbom diff --git a/developer-workflow/sbom.rst b/developer-workflow/sbom.rst new file mode 100644 index 000000000..756c17570 --- /dev/null +++ b/developer-workflow/sbom.rst @@ -0,0 +1,109 @@ +Software Bill-of-Materials (SBOM) +================================= + +Software Bill-of-Materials (abbreviated as "SBOM") is a document for sharing +information about software and how it's been composed. This format is used +most often in the security space for checking software and its dependencies +for vulnerabilities using vulnerability databases like +`CVE `_ and `OSV `_. The SBOM format +that the CPython project uses is `SPDX `_ +which can be transformed into other formats if necessary by consumers. + +There are multiple sources of third-party dependencies for CPython. +Some are vendored into the source code of CPython itself (like ``mpdecimal`` +vendored at :cpy-file:`Modules/_decimal/libmpdec`) or they could be optionally pulled +in during builds like Windows using dependencies from the +`python/cpython-source-deps `_ +repository. + +Whenever adding or updating a third-party dependency, an update will likely +need to be done to the SBOM in order to track the version and software identifiers. + +Updating a dependency +--------------------- + +The SBOM for CPython's bundled dependencies is kept at +:cpy-file:`Misc/sbom.spdx.json`. When updating a dependency to a new version +you'll need to edit the version and other metadata about this dependency in +the SBOM. + +The recommended workflow is: + +1. Download the new dependency as an archive. Take note of the new version, download + URL, and checksum of the downloaded archive. +2. Update the vendored code in the CPython source tree. +3. Edit :cpy-file:`Misc/sbom.spdx.json` to add the new ``versionInfo``, + ``downloadLocation``, ``checksums``, and ``externalReferences`` for the + corresponding ``package``. For most of these updates all that's needed is to + update the embedded version within URLs and project identifiers. + Don't update any information in ``files`` and ``relationships`` as this will + be generated automatically by the SBOM tool. +4. Run ``make regen-sbom`` or ``python Tools/build/generate_sbom.py``. + Ensure that this doesn't fail with validation errors. +5. Run ``git diff Misc/sbom.spdx.json`` and check the diff matches the + expected changes. +6. Commit the changes to :cpy-file:`Misc/sbom.spdx.json` along with the + update to the dependency code. + +Adding a new dependency +----------------------- + +When adding a dependency it's important to have the following information: + +* Name, version, and download URL of the project +* License of the project as an `SPDX License Expression `_ +* Software identifiers that match values in vulnerability databases + (`CPE `_ and + `Package URLs `_ + or "PURLs") +* Paths to include and exclude in the CPython source tree corresponding to this dependency + +After gathering this information: + +1. Add the information into a new entry in ``packages`` in the file + :cpy-file:`Misc/sbom.spdx.json`. Don't worry about formatting, the tool will + auto-format your manually written JSON. The fields to fill out include: + + * ``name`` for the project name. + * ``SPDXID`` which will be ``"SPDXRef-PACKAGE-{name}"``. + * ``licenseConcluded`` for the SPDX license identifier of the project license. + * ``versionInfo`` for the version of the project. + * ``downloadLocation`` should be an HTTPS URL for the project download as an archive. + * ``checksums[0].checksumValue`` and ``.algorithm`` will be the SHA-256 + checksum of the downloaded archive. + * ``originator`` for the original author information, prefix with either an + ``Organization:`` or ``Person:`` depending on the author/maintenance situation. + * ``primaryPackagePurpose`` will likely be ``"SOURCE"``. + * ``externalReferences`` is a list of one or more project identifiers, + either CPE or Package URL. The value for ``referenceLocator`` must include + the value in ``versionInfo`` to ensure the identifier + corresponds to the correct release of the software. You can read more about + external references in the `SPDX SBOM specification`_. +2. If a new license ID is to be used, add the license expression to + ``ALLOWED_LICENSE_EXPRESSIONS`` in the :cpy-file:`Tools/build/generate_sbom.py`. +3. Add the paths to include and exclude into a ``PackageFiles`` instance + with a key corresponding to the SBOM ID for the package (``SPDXID`` without the + ``SPDXRef-PACKAGE-*`` prefix) in :cpy-file:`Tools/build/generate_sbom.py`. +4. Run the tool with ``make regen-sbom`` or ``python Tools/build/generate_sbom.py``. + Ensure that the tool doesn't fail with any validation errors. +5. Compare the changes to :cpy-file:`Misc/sbom.spdx.json` with ``git diff``, check + that all information appears correct. +6. Commit the changes to :cpy-file:`Misc/sbom.spdx.json` and + :cpy-file:`Tools/build/generate_sbom.py`. + +.. _SPDX SBOM specification: https://spdx.github.io/spdx-spec/v2-draft/external-repository-identifiers/ + +Removing a dependency +--------------------- + +When removing a dependency: + +1. Remove the entry from the :cpy-file:`Misc/sbom.spdx.json` + under the ``packages`` field. +2. Remove the corresponding ``PackageFiles`` entry in :cpy-file:`Tools/build/generate_sbom.py` +3. Run the tool with ``make regen-sbom`` or ``python Tools/build/generate_sbom.py``. + Ensure that the tool doesn't fail with any validation errors. +4. Compare the changes to :cpy-file:`Misc/sbom.spdx.json` with ``git diff``, check + that correct package is removed from the SBOM. +5. Commit the changes to :cpy-file:`Misc/sbom.spdx.json` and + :cpy-file:`Tools/build/generate_sbom.py`. From 008be35ea56c734851d8674eb48ef83d482ffdd7 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Wed, 20 Dec 2023 13:38:39 +0000 Subject: [PATCH 259/538] Add explanation about docstring for PyGetSetDef (gh-1248) Co-authored-by: Ezio Melotti --- development-tools/clinic.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index c2b18f4a2..910de404a 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -2087,6 +2087,8 @@ The generated glue code looks like this: 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`: From 42c223e8f8a458079db4521a347ba0e536e952ec Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sat, 30 Dec 2023 21:22:04 +0200 Subject: [PATCH 260/538] Fix linkcheck warnings (#1256) --- conf.py | 9 ++++++++- core-developers/motivations.rst | 8 ++++---- development-tools/gdb.rst | 4 ++-- documentation/translating.rst | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/conf.py b/conf.py index 31ce4f5fd..5896b065a 100644 --- a/conf.py +++ b/conf.py @@ -63,7 +63,10 @@ r"https://docs.python.org/[a-z-]+/": r"https://docs.python.org/[a-z-]+/3/", # Personal /my/ links redirect to login page r"https://discuss.python.org/my/.*": r"https://discuss.python.org/login-preferences", # noqa: E501 + # Category number URL to full slug + r"https://discuss.python.org/c/\d+": r"https://discuss.python.org/c/.*", # Login page + r"https://github.com/python/buildmaster-config/issues/new.*": r"https://github.com/login.*", # noqa: E501 r"https://github.com/python/core-workflow/issues/new.*": r"https://github.com/login.*", # noqa: E501 # Archive redirect r"https://github.com/python/cpython/archive/main.zip": r"https://codeload.github.com/python/cpython/zip/refs/heads/main", # noqa: E501 @@ -72,10 +75,11 @@ # HackMD shortcuts r"https://hackmd.io/s/.*": r"https://hackmd.io/@.*", # Read the Docs + r"https://python-docs-tr.readthedocs.io/": r"https://python-docs-tr.readthedocs.io/tr/.*", # noqa: E501 r"https://virtualenv.pypa.io/": r"https://virtualenv.pypa.io/en/latest/", r"https://www.sphinx-doc.org/": r"https://www.sphinx-doc.org/en/master/", # Cookie consent - r"https://www.youtube.com/playlist.*": r"https://consent.youtube.com/ml.*", + r"https://www.youtube.com/playlist.*": r"https://consent.youtube.com/.*", } # ignore linkcheck anchors for /#/$ANCHOR since it is used for @@ -99,6 +103,9 @@ r'https://github.com.+?#L\d+', r'https://github.com/cli/cli#installation', r'https://github.com/github/renaming#renaming-existing-branches', + r'https://github.com/python/bedevere/#pr-state-machine', + # "Anchor not found": + r'https://packaging.python.org/.*#', # Discord doesn't allow robot crawlers: "403 Client Error: Forbidden" r'https://support.discord.com/hc/en-us/articles/219070107-Server-Nicknames', ] diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index 164bdcb64..c32304962 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -145,7 +145,7 @@ participating in the CPython core development process: * Works as a `Software Engineer `_ in Vancouver, helps organize `Vancouver PyLadies `_ meetup on the side, and - sometimes `speaks `_ + sometimes `speaks `_ at conferences. * Email address: mariatta@python.org * `Sponsor Mariatta on GitHub `_ @@ -157,7 +157,7 @@ participating in the CPython core development process: .. 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 `_ @@ -238,7 +238,7 @@ participating in the CPython core development process: is both an Ubuntu and a `Debian `_ uploading developer. Barry has served as Python's postmaster, webmaster, release manager, Language Summit co-chair, `Jython `_ - project leader, `GNU Mailman `_ project leader, and + project leader, `GNU Mailman `_ project leader, and probably lots of other things he shouldn't admit to. .. topic:: Eric Snow (United States) @@ -327,7 +327,7 @@ on institutional sponsors allowing them to spend some or all of their work time contributing to CPython development. .. _issue metrics: https://bugs.python.org/issue?@template=stats -.. _OpenHub: https://www.openhub.net/p/python/contributors +.. _OpenHub: https://openhub.net/p/python/contributors .. _core mentorship program: https://www.python.org/dev/core-mentorship/ .. _internships: https://www.outreachy.org/ .. _Summer of Code: https://wiki.python.org/moin/SummerOfCode/2016 diff --git a/development-tools/gdb.rst b/development-tools/gdb.rst index cff419514..c6f781fbc 100644 --- a/development-tools/gdb.rst +++ b/development-tools/gdb.rst @@ -21,7 +21,7 @@ GDB 7 and later =============== In gdb 7, support for `extending gdb with Python -`_ was +`_ was added. When CPython is built you will notice a ``python-gdb.py`` file in the root directory of your checkout. Read the module docstring for details on how to use the file to enhance gdb for easier debugging of a CPython process. @@ -355,7 +355,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/translating.rst b/documentation/translating.rst index 1a860da87..3520569f5 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -111,7 +111,7 @@ in production; others are works in progress. .. _github_ar: https://github.com/Abdur-rahmaanJ/python-docs-ar .. _github_bn_in: https://github.com/python/python-docs-bn-in .. _github_es: https://github.com/python/python-docs-es -.. _github_fa: https://github.com/ftg-iran/python-docs-fa +.. _github_fa: https://github.com/mmdbalkhi/python-docs-fa .. _github_fr: https://github.com/python/python-docs-fr .. _github_hi_in: https://github.com/CuriousLearner/python-docs-hi-in .. _github_hu: https://github.com/python/python-docs-hu From 26f5ffce42b3dd84fd7cae34934925009a29387e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 02:32:11 +0100 Subject: [PATCH 261/538] Bump sphinx-lint from 0.9.0 to 0.9.1 (#1257) Bumps [sphinx-lint](https://github.com/sphinx-contrib/sphinx-lint) from 0.9.0 to 0.9.1. - [Release notes](https://github.com/sphinx-contrib/sphinx-lint/releases) - [Commits](https://github.com/sphinx-contrib/sphinx-lint/compare/v0.9.0...v0.9.1) --- updated-dependencies: - dependency-name: sphinx-lint 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 5c91a1dac..219122e4c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ furo>=2022.6.4 jinja2 sphinx-autobuild sphinx-inline-tabs>=2023.4.21 -sphinx-lint==0.9.0 +sphinx-lint==0.9.1 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 From bcd0c8a09877435f4f75f6200b5f355904d7507b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 3 Jan 2024 14:41:06 +0200 Subject: [PATCH 262/538] Document Git worktree (#1255) Co-authored-by: Ezio Melotti Co-authored-by: Itamar Oren --- .editorconfig | 15 +++++++ .pre-commit-config.yaml | 28 ++++++++----- getting-started/git-boot-camp.rst | 67 +++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..0169eed95 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*.{py,c,cpp,h,rst,md,yml}] +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space + +[*.{py,c,cpp,h}] +indent_size = 4 + +[*.rst] +indent_size = 3 + +[*.yml] +indent_size = 2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd8154adf..60ea4bc4b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,13 +6,13 @@ repos: args: [--py38-plus] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.12.0 + rev: 23.12.1 hooks: - id: black args: [--skip-string-normalization] - repo: https://github.com/PyCQA/isort - rev: 5.13.1 + rev: 5.13.2 hooks: - id: isort args: [--profile=black] @@ -21,13 +21,8 @@ repos: rev: 6.1.0 hooks: - id: flake8 - additional_dependencies: [flake8-2020] - - - repo: https://github.com/sphinx-contrib/sphinx-lint - rev: v0.9.1 - hooks: - - id: sphinx-lint - args: ["--enable=default-role"] + additional_dependencies: + [flake8-2020, flake8-implicit-str-concat] - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.10.0 @@ -37,11 +32,24 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - - id: check-json + - id: check-case-conflict - id: check-merge-conflict + - id: check-json - id: check-yaml + - id: debug-statements - id: end-of-file-fixer - id: trailing-whitespace + - repo: https://github.com/sphinx-contrib/sphinx-lint + rev: v0.9.1 + hooks: + - id: sphinx-lint + args: [--enable=default-role] + + - repo: meta + hooks: + - id: check-hooks-apply + - id: check-useless-excludes + ci: autoupdate_schedule: quarterly diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index d8d1a14fe..2bee5c29f 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -669,3 +669,70 @@ Examples of useful commands: * Set the browser:: $ gh config set browser + + +Git worktree +------------ + +With Git worktrees, you can have multiple isolated working trees +associated with a single repository (the ``.git`` directory). +This allows you to work simultaneously on different version +branches, eliminating the need for multiple independent clones +that need to be maintained and updated separately. +In addition, it reduces cloning overhead and saves disk space. + +Setting up Git worktree +^^^^^^^^^^^^^^^^^^^^^^^ + +With an existing CPython clone (see :ref:`clone-your-fork`), rename the +``cpython`` directory to ``main`` and move it into a new ``cpython`` +directory, so we have a structure like: + +.. Generated with: tree -L 1 -d cpython + +.. code-block:: text + + cpython + └── main (.git is here) + +Next, create worktrees for the other branches:: + + $ cd cpython/main + $ git worktree add -b 3.11 ../3.11 upstream/3.11 + $ git worktree add -b 3.12 ../3.12 upstream/3.12 + +This gives a structure like this, with the code for each branch checked out in +its own directory: + +.. code-block:: text + + cpython + ├── 3.11 + ├── 3.12 + └── main + +Using Git worktree +^^^^^^^^^^^^^^^^^^ + +List your worktrees, for example:: + + $ git worktree list + /Users/my-name/cpython/main b3d24c40df [main] + /Users/my-name/cpython/3.11 da1736b06a [3.11] + /Users/my-name/cpython/3.12 cf29a2f25e [3.12] + +Change into a directory to work from that branch. For example:: + + $ cd ../3.12 + $ git switch -c my-3.12-bugfix-branch # create new branch + $ # make changes, test them, commit + $ git push origin my-3.12-bugfix-branch + $ # create PR + $ git switch 3.12 # switch back to the 3.12 branch + ... + +.. seealso:: + + * `Git Reference Manual `_ + * `"Experiment on your code freely with Git worktree" + `_ From 26bf7569c8d703c7436cf59053a49700ac9ff88d Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 7 Jan 2024 01:40:03 +0100 Subject: [PATCH 263/538] Document that type-feature labels do not need to be paired with version labels (#1259) --- triage/labels.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triage/labels.rst b/triage/labels.rst index 7cee20af8..6cc54360c 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -26,6 +26,8 @@ These labels are used to specify the type of issue: * :gh-label:`type-crash`: for hard crashes of the interpreter, possibly with a core dump. * :gh-label:`type-feature`: for feature requests or enhancements. + Feature requests do not need :ref:`version labels `; + 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-security`: for security issues. @@ -81,6 +83,8 @@ You can see the `full list of topic labels on GitHub `_. +.. _Version labels: + Version labels ============== From 4da3b3a21172aa284ee4bdd3413b475f4a91fbb9 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Fri, 29 Dec 2023 20:37:02 +0100 Subject: [PATCH 264/538] Hello python-docs-ru --- documentation/translating.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 3520569f5..1d0da91e4 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -65,7 +65,8 @@ in production; others are works in progress. | in Brasil | | `Telegram `_ | | (pt-br) | | `article `_| +-----------------+-------------------------------+----------------------------+ -| Russian (ru) | | `mail `_ | +| Russian (ru) | | `GitHub `_ | +| | | `mail `_ | +-----------------+-------------------------------+----------------------------+ | Simplified | `Shengjing Zhu `_, | `Transifex `_ | | Chinese | `Du, Meng `_ | `GitHub `_ | @@ -125,6 +126,7 @@ in production; others are works in progress. .. _github_uk: https://github.com/python/python-docs-uk .. _github_zh_cn: https://github.com/python/python-docs-zh-cn .. _github_zh_tw: https://github.com/python/python-docs-zh-tw +.. _github_ru: https://github.com/MLGRussianXP/python-docs-ru .. _list_hu: https://mail.python.org/pipermail/python-hu .. _mail_it: https://mail.python.org/pipermail/doc-sig/2019-April/004114.html .. _mail_lt: https://mail.python.org/pipermail/doc-sig/2019-July/004138.html From f398a500a28de6e4571c1bf38d6aa30e0e8b472f Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Fri, 29 Dec 2023 22:30:33 +0100 Subject: [PATCH 265/538] RST syntax... --- documentation/translating.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 1d0da91e4..2f5b498e4 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -65,7 +65,7 @@ in production; others are works in progress. | in Brasil | | `Telegram `_ | | (pt-br) | | `article `_| +-----------------+-------------------------------+----------------------------+ -| Russian (ru) | | `GitHub `_ | +| Russian (ru) | | `GitHub `_ | | | | `mail `_ | +-----------------+-------------------------------+----------------------------+ | Simplified | `Shengjing Zhu `_, | `Transifex `_ | From d4552d0942d57501f4fbbb4564749aae356e0df3 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 14 Jan 2024 19:21:49 +0200 Subject: [PATCH 266/538] Add big O notation to the style guide (#1261) Co-authored-by: Hugo van Kemenade --- documentation/style-guide.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index eb18feb9d..53c6f36e3 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -225,3 +225,20 @@ errors ("I made a mistake, therefore the docs must be wrong ..."). Typically, the documentation wasn't consulted until after the error was made. It is unfortunate, but typically no documentation edit would have saved the user from making false assumptions about the language ("I was surprised by ..."). + +Big *O* notation +================ + +Big *O* notation is used to describe the performance of algorithms. + +Use italics for the big *O* and variables. For example: + +======================== ==================== +reStructuredText Rendered +======================== ==================== +``*O*\ (1)`` *O*\ (1) +``*O*\ (log *n*)`` *O*\ (log *n*) +``*O*\ (*n*)`` *O*\ (*n*) +``*O*\ (*n* log *n*)`` *O*\ (*n* log *n*) +``*O*\ (*n*\ :sup:`2`)`` *O*\ (*n*\ :sup:`2`) +======================== ==================== From a92330ce89c4b25eb826bce4c65b485deeb768c0 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 26 Jan 2024 20:48:16 +0100 Subject: [PATCH 267/538] Clarify when to use versionadded and versionchanged (#1264) Clarify when to use the versionadded vs versionchanged directives in doc markup Co-authored-by: Jelle Zijlstra Co-authored-by: C.A.M. Gerlach --- documentation/markup.rst | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index 7e237462c..e457a525f 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -373,6 +373,8 @@ As you can see, the module-specific markup consists of two directives, the in overview files. +.. _information-units: + Information units ----------------- @@ -1019,13 +1021,20 @@ units as well as normal text: feature, or a part of it, to the library or C API. When this applies to an entire module, it should be placed at the top of the module section before any prose. + When adding a new API :ref:`with a directive ` + (``class``, ``attribute``, ``function``, ``method``, ``c:type``, etc), + a ``versionadded`` should be included at the end of its description block. The first argument must be given and is the version in question. The second argument is optional and can be used to describe the details of the feature. Example:: - .. versionadded:: 3.5 + .. function:: func() + + Return foo and bar. + + .. versionadded:: 3.5 .. describe:: versionchanged @@ -1035,8 +1044,12 @@ units as well as normal text: Example:: - .. versionchanged:: 3.1 - The *spam* parameter was added. + .. function:: func(spam=False) + + Return foo and bar, optionally with *spam* applied. + + .. versionchanged:: 3.6 + Added the *spam* parameter. Note that there should be no blank line between the directive head and the explanation; this is to make these blocks visually continuous in the markup. From cb7c54c078702d7d14d46555ccc39168564df71a Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Mon, 29 Jan 2024 15:42:44 -0800 Subject: [PATCH 268/538] Add myself as a JIT expert (#1266) --- core-developers/experts.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 6f1b39787..f2f9bfb75 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -336,6 +336,7 @@ GUI i18n malemburg, merwok import machinery brettcannon, ncoghlan, ericsnowcurrently io benjaminp, stutzbach^, gpshead +JIT brandtbucher* locale malemburg mathematics mdickinson, malemburg, stutzbach^, rhettinger memory management tim-one, malemburg, Yhg1s From 90595bcedae935015b195d2db1b9c56d1f273ef0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 30 Jan 2024 17:12:56 +0200 Subject: [PATCH 269/538] Add governance contact (#1260) --- conf.py | 9 +++++++ developer-workflow/development-cycle.rst | 32 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/conf.py b/conf.py index 5896b065a..ec801aef3 100644 --- a/conf.py +++ b/conf.py @@ -8,6 +8,7 @@ extensions = [ 'custom_roles', 'notfound.extension', + 'sphinx.ext.extlinks', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx_copybutton', @@ -170,6 +171,14 @@ # sphinx-notfound-page notfound_urls_prefix = "/" +# sphinx.ext.extlinks +# This config is a dictionary of external sites, +# mapping unique short aliases to a base URL and a prefix. +# https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html +extlinks = { + "github": ("https://github.com/%s/", "%s"), +} + # sphinxext-opengraph config ogp_site_url = "https://devguide.python.org/" ogp_site_name = "Python Developer's Guide" diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 704098cdd..79a9dced4 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -371,3 +371,35 @@ administrators) to merge changes to that branch. Multi-Factor Authentication must be enabled by the user in order to retain access as a Release Manager of the branch. + +Governance +---------- + +The Python Steering Council has overall authority over Python and has delegated +some of its responsibilities to other groups. + +This table lists the PEPs defining each group's responsibilities, +and the repository where you can open an issue to ask for a decision. + +.. list-table:: + :header-rows: 1 + + * - Name + - PEP + - Contact repo + * - Steering Council + - :pep:`13` + - :github:`python/steering-council` + * - C API Working Group + - :pep:`731` + - :github:`capi-workgroup/decisions` + * - Documentation Editorial Board + - :pep:`732` + - :github:`python/editorial-board` + * - Typing Council + - :pep:`729` + - :github:`python/typing-council` + +.. seealso:: + + All governance PEPs: https://peps.python.org/topic/governance/ From 32d31f364cd702cbaba70dcac1d2d5097ff6d711 Mon Sep 17 00:00:00 2001 From: "Paul m. p. Peny" Date: Thu, 1 Feb 2024 09:25:38 +0100 Subject: [PATCH 270/538] List community platform (emscripten) supporters (GH-1267) --- core-developers/experts.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index f2f9bfb75..628831d37 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -291,6 +291,7 @@ Platform Maintainers AIX David.Edelsohn^ Android Cygwin jlt63^, stutzbach^ +Emscripten hoodmane, pmp-p, rdb, rth, ryanking13 FreeBSD HP-UX Linux From bdec818697a7fac251f6d40cb20ebc882e720280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 6 Feb 2024 21:01:22 +0100 Subject: [PATCH 271/538] Add Sam Gross & Nikita Sobolev, clarify how to announce (#1271) --- core-developers/become-core-developer.rst | 6 ++++-- core-developers/developers.csv | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index a0b2a1053..4c0251933 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -54,8 +54,10 @@ are granted through these steps: - Add their details to `🔒 python/voters `_. - Update the devguide to publicly list their team membership at :ref:`developers`. - - Send an announcement email to the `Committers Discourse category - `_. + - Post an announcement in the `Committers Discourse category + `_. The past few announcements + were in the form of a separate post on the already open topic with + the poll. .. _Code of Conduct: https://www.python.org/psf/conduct/ .. _Committers category: https://discuss.python.org/c/committers/5 diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 2510af384..d05354b4a 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,5 @@ +Sam Gross,colesbury,2024-02-06,, +Nikita Sobolev,sobolevn,2024-02-06,, Adam Turner,AA-Turner,2023-10-10,, C.A.M. Gerlach,CAM-Gerlach,2023-04-19,, Barney Gale,barneygale,2023-03-21,, From fe3722df7ed42d02e75544ec79b658d50e7232f2 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 6 Feb 2024 15:02:13 -0500 Subject: [PATCH 272/538] Describe GC for free-threaded build in the GC design doc (#1263) Co-authored-by: Ezio Melotti --- internals/garbage-collector.rst | 167 +++++++++++++++++++++++++------- 1 file changed, 134 insertions(+), 33 deletions(-) diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index d25cfc23e..7459b23e8 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -53,9 +53,29 @@ is needed to clean these reference cycles between objects once they become unreachable. This is the cyclic garbage collector, usually called just Garbage Collector (GC), even though reference counting is also a form of garbage collection. +Starting in version 3.13, CPython contains two GC implementations: + +* The default build implementation relies on the :term:`global interpreter + lock` for thread safety. +* The free-threaded build implementation pauses other executing threads when + performing a collection for thread safety. + +Both implementations use the same basic algorithms, but operate on different +data structures. The :ref:`gc-differences` section summarizes the +differences between the two GC implementations. + + Memory layout and object structure ================================== +The garbage collector requires additional fields in Python objects to support +garbage collection. These extra fields are different in the default and the +free-threaded builds. + + +GC for the default build +------------------------ + Normally the C structure supporting a regular Python object looks as follows: .. code-block:: none @@ -107,6 +127,44 @@ isn't running at all!), and merging partitions, all with a small constant number With care, they also support iterating over a partition while objects are being added to - and removed from - it, which is frequently required while GC is running. +GC for the free-threaded build +------------------------------ + +In the free-threaded build, Python objects contain a 1-byte field +``ob_gc_bits`` that is used to track garbage collection related state. The +field exists in all objects, including ones that do not support cyclic +garbage collection. The field is used to identify objects that are tracked +by the collector, ensure that finalizers are called only once per object, +and, during garbage collection, differentiate reachable vs. unreachable objects. + +.. code-block:: none + + object -----> +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ \ + | ob_tid | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | + | pad | ob_mutex | ob_gc_bits | ob_ref_local | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PyObject_HEAD + | ob_ref_shared | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | + | *ob_type | | + +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / + | ... | + + +Note that not all fields are to scale. ``pad`` is two bytes, ``ob_mutex`` and +``ob_gc_bits`` are each one byte, and ``ob_ref_local`` is four bytes. The +other fields, ``ob_tid``, ``ob_ref_shared``, and ``ob_type``, are all +pointer-sized (i.e., eight bytes on a 64-bit platform). + + +The garbage collector also temporarily repurposes the ``ob_tid`` (thread ID) +and ``ob_ref_local`` (local reference count) fields for other purposes during +collections. + + +C APIs +------ + Specific APIs are offered to allocate, deallocate, initialize, track, and untrack objects with GC support. These APIs can be found in the `Garbage Collector C API documentation `_. @@ -139,14 +197,11 @@ the interpreter create cycles everywhere. Some notable examples: * When representing data structures like graphs, it is very typical for them to have internal links to themselves. -To correctly dispose of these objects once they become unreachable, they need to be -identified first. Inside the function that identifies cycles, two doubly linked -lists are maintained: one list contains all objects to be scanned, and the other will -contain all objects "tentatively" unreachable. - -To understand how the algorithm works, let’s take the case of a circular linked list -which has one link referenced by a variable ``A``, and one self-referencing object which -is completely unreachable: +To correctly dispose of these objects once they become unreachable, they need +to be identified first. To understand how the algorithm works, let’s take +the case of a circular linked list which has one link referenced by a +variable ``A``, and one self-referencing object which is completely +unreachable: .. code-block:: python @@ -171,10 +226,17 @@ is completely unreachable: >>> gc.collect() 2 -When the GC starts, it has all the container objects it wants to scan -on the first linked list. The objective is to move all the unreachable -objects. Since most objects turn out to be reachable, it is much more -efficient to move the unreachable as this involves fewer pointer updates. +The GC starts with a set of candidate objects it wants to scan. In the +default build, these "objects to scan" might be all container objects or a +smaller subset (or "generation"). In the free-threaded build, the collector +always operates scans all container objects. + +The objective is to identify all the unreachable objects. The collector does +this by identifying reachable objects; the remaining objects must be +unreachable. The first step is to identify all of the "to scan" objects that +are **directly** reachable from outside the set of candidate objects. These +objects have a refcount larger than the number of incoming references from +within the candidate set. Every object that supports garbage collection will have an extra reference count field initialized to the reference count (``gc_ref`` in the figures) @@ -273,23 +335,20 @@ Once the GC knows the list of unreachable objects, a very delicate process start with the objective of completely destroying these objects. Roughly, the process follows these steps in order: -1. Handle and clean weak references (if any). If an object that is in the unreachable - set is going to be destroyed and has weak references with callbacks, these - callbacks need to be honored. This process is **very** delicate as any error can - cause objects that will be in an inconsistent state to be resurrected or reached - by some Python functions invoked from the callbacks. In addition, weak references - that also are part of the unreachable set (the object and its weak reference - are in cycles that are unreachable) need to be cleaned - immediately, without executing the callback. Otherwise it will be triggered later, - when the ``tp_clear`` slot is called, causing havoc. Ignoring the weak reference's - callback is fine because both the object and the weakref are going away, so it's - legitimate to say the weak reference is going away first. - -2. If an object has legacy finalizers (``tp_del`` slot) move them to the +1. Handle and clear weak references (if any). Weak references to unreachable objects + are set to ``None``. If the weak reference has an associated callback, the callback + is enqueued to be called once the clearing of weak references is finished. We only + invoke callbacks for weak references that are themselves reachable. If both the weak + reference and the pointed-to object are unreachable we do not execute the callback. + This is partly for historical reasons: the callback could resurrect an unreachable + object and support for weak references predates support for object resurrection. + Ignoring the weak reference's callback is fine because both the object and the weakref + are going away, so it's legitimate to say the weak reference is going away first. +2. If an object has legacy finalizers (``tp_del`` slot) move it to the ``gc.garbage`` list. 3. Call the finalizers (``tp_finalize`` slot) and mark the objects as already - finalized to avoid calling them twice if they resurrect or if other finalizers - have removed the object first. + finalized to avoid calling finalizers twice if the objects are resurrected or + if other finalizers have removed the object first. 4. Deal with resurrected objects. If some objects have been resurrected, the GC finds the new subset of objects that are still unreachable by running the cycle detection algorithm again and continues with them. @@ -300,12 +359,12 @@ follows these steps in order: Optimization: generations ========================= -In order to limit the time each garbage collection takes, the GC uses a popular -optimization: generations. The main idea behind this concept is the assumption that -most objects have a very short lifespan and can thus be collected shortly after their -creation. This has proven to be very close to the reality of many Python programs as -many temporary objects are created and destroyed very fast. The older an object is -the less likely it is that it will become unreachable. +In order to limit the time each garbage collection takes, the GC +implementation for the default build uses a popular optimization: +generations. The main idea behind this concept is the assumption that most +objects have a very short lifespan and can thus be collected soon after their +creation. This has proven to be very close to the reality of many Python +programs as many temporary objects are created and destroyed very quickly. To take advantage of this fact, all container objects are segregated into three spaces/generations. Every new @@ -317,6 +376,9 @@ the same object survives another GC round in this new generation (generation 1) it will be moved to the last generation (generation 2) where it will be surveyed the least often. +The GC implementation for the free-threaded build does not use multiple +generations. Every collection operates on the entire heap. + In order to decide when to run, the collector keeps track of the number of object allocations and deallocations since the last collection. When the number of allocations minus the number of deallocations exceeds ``threshold_0``, @@ -497,6 +559,45 @@ tracking status of the object. True +.. _gc-differences: + +Differences between GC implementations +====================================== + +This section summarizes the differences between the GC implementation in the +default build and the implementation in the free-threaded build. + +The default build implementation makes extensive use of the ``PyGC_Head`` data +structure, while the free-threaded build implementation does not use that +data structure. + +* The default build implementation stores all tracked objects in a doubly + linked list using ``PyGC_Head``. The free-threaded build implementation + instead relies on the embedded mimalloc memory allocator to scan the heap + for tracked objects. +* The default build implementation uses ``PyGC_Head`` for the unreachable + object list. The free-threaded build implementation repurposes the + ``ob_tid`` field to store a unreachable objects linked list. +* The default build implementation stores flags in the ``_gc_prev`` field of + ``PyGC_Head``. The free-threaded build implementation stores these flags + in ``ob_gc_bits``. + + +The default build implementation relies on the :term:`global interpreter lock` +for thread safety. The free-threaded build implementation has two "stop the +world" pauses, in which all other executing threads are temporarily paused so +that the GC can safely access reference counts and object attributes. + +The default build implementation is a generational collector. The +free-threaded build is non-generational; each collection scans the entire +heap. + +* Keeping track of object generations is simple and inexpensive in the default + build. The free-threaded build relies on mimalloc for finding tracked + objects; identifying "young" objects without scanning the entire heap would + be more difficult. + + .. admonition:: Document History :class: note From ce77c74c93d2c82142ea64964c7f783de3145d30 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:02:30 +0200 Subject: [PATCH 273/538] Document the python/proofreaders team (#1229) Co-authored-by: Hugo van Kemenade --- documentation/help-documenting.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/documentation/help-documenting.rst b/documentation/help-documenting.rst index 137827b3e..06e44549c 100644 --- a/documentation/help-documenting.rst +++ b/documentation/help-documenting.rst @@ -84,4 +84,12 @@ a pull request directly. It's best to avoid filing a single issue for an entire section containing multiple problems; instead, file several issues so that it is easier to break the work up for multiple people and more efficient review. +For help with the finer points of English technical writing, mention the +`@python/proofreaders `__ +team in your issue or pull request in any `@python `__ +repo. If you'd like to join the team, +`open a core-workflow issue `__ +similar to +`python/core-workflow#461 `__. + .. _issue tracker: https://github.com/python/cpython/issues From 1a5666774fee6b7e42a1f23b918fff913a5a2372 Mon Sep 17 00:00:00 2001 From: James Gough <68547555+Jamesgo1@users.noreply.github.com> Date: Tue, 6 Feb 2024 20:05:07 +0000 Subject: [PATCH 274/538] =?UTF-8?q?gh-1145:=20Add=20an=20overview=20of=20D?= =?UTF-8?q?i=C3=A1taxis=20to=20the=20=20style=20guide=20(#1177)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf.py | 1 + documentation/style-guide.rst | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/conf.py b/conf.py index ec801aef3..825cfb5b5 100644 --- a/conf.py +++ b/conf.py @@ -164,6 +164,7 @@ intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), + 'diataxis': ('https://diataxis.fr/', None), } todo_include_todos = True diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index 53c6f36e3..2fba1e1fc 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -106,6 +106,48 @@ Unix The name of the operating system developed at AT&T Bell Labs in the early 1970s. +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 +explanation. + +* :ref:`python:tutorial-index` should + be explicit and avoid making assumptions about the + reader's knowledge. The goal of a tutorial is to get the user writing + Python code as quickly as possible with clear logical steps. Explanations + and abstract concepts should be avoided. Please consult the Diátaxis guide on + :ref:`diataxis:tutorials` for more detail. + +* `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, + how-to guides make more assumptions about the user's knoweldge and + focus on the user finding the best way to solve their own + particular problem. + +* :ref:`python:reference-index` should + be factual and succinct. The purpose of reference documentation is + to describe rather than to explain. Accuracy and consistency are key as + this type of documentation should be seen as an authoritative source. + :ref:`Code-examples` can be a useful way of achieving these + objectives. + +* Python explanations provide + a deeper level of understanding and are naturally more discursive. They aim + to deepen the reader's understanding and answer 'why' questions. They should + provide context, make connections between topics, and discuss alternative + opinions. There is no section dedicated to explanations but these can be + found throughout Python's documentation, for example the + :ref:`python:unicode-howto` + +Please consult the `Diátaxis `_ guide for more +detail. + Affirmative tone ================ @@ -163,6 +205,8 @@ module (e.g. OS level pipe buffers filling up and stalling child processes), these can be documented in a "Common Errors" section and cross-referenced rather than repeated for every affected interface. +.. _code-examples: + Code examples ============= From b5f49de1f237b20cb00f52b6954402fa4c82cda5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 6 Feb 2024 21:07:24 +0100 Subject: [PATCH 275/538] Add section on keeping CI green (#1215) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Jelle Zijlstra Co-authored-by: Ezio Melotti --- getting-started/git-boot-camp.rst | 8 ++-- getting-started/pull-request-lifecycle.rst | 50 ++++++++++++++++++++-- triage/triaging.rst | 1 + 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 2bee5c29f..2fb5e2f72 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -476,9 +476,11 @@ You can read more about what to look for before accepting a change :ref:`here `. All pull requests have required checks that need to pass before a change -can be merged. At any point, a core developer can schedule an automatic merge -of the change by -clicking the gray ``Enable auto-merge (squash)`` button. You will find +can be merged. See :ref:`"Keeping CI green" ` for some +simple things you can do to help the checks turn green. + +At any point, a core developer can schedule an automatic merge of the change +by clicking the gray ``Enable auto-merge (squash)`` button. You will find it at the bottom of the pull request page. The auto-merge will only happen if all the required checks pass, but the PR does not need to have been approved for a successful auto-merge to take place. diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index e2dde81f6..1c16f1592 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -41,8 +41,8 @@ Here is a quick overview of how you can contribute to CPython: #. `Create Pull Request`_ on GitHub to merge a branch from your fork -#. Make sure the continuous integration checks on your Pull Request - are green (i.e. successful) +#. Make sure the :ref:`continuous integration checks on your Pull Request + are green ` (i.e. successful) #. Review and address `comments on your Pull Request`_ @@ -472,7 +472,7 @@ code and leave comments in the pull request or issue tracker. 'merge-ready', you should always make sure the entire test suite passes. Leaving a pull request review on GitHub -======================================= +--------------------------------------- When you review a pull request, you should provide additional details and context of your review process. @@ -487,14 +487,55 @@ Instead of simply "approving" the pull request, leave comments. For example: #. Comment on what is "good" about the pull request, not just the "bad". Doing so will make it easier for the PR author to find the good in your comments. +#. 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 -============================================= +--------------------------------------------- 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 the PR to themselves, then it is a sign that they are actively looking after the PR, and their review should not be dismissed. +.. _keeping-ci-green: + +Keeping continuous integration green +==================================== + +Our change management workflows generally won't allow merging PRs with +failures. Therefore, if you see a CI failure on a PR, have a look +what it is about. + +Usually the failure will be directly related to the changes in the current +PR. If you happen to have any insight into the failure, let the author know +in a review comment. CI runs sometimes generate thousands of lines of output. +Even something as simple as finding the traceback and putting it in the +comment will be helpful to the PR author. + +If the failure doesn't look related to the change you're looking at, check +if it's not present on the `Release Status`_ Buildbot dashboard as well. +If so, that means the failure was introduced in a prior change. Using Buildbot's +UI you can find which PR introduced the issue and comment that it +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 +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 +to re-run that particular failed check. Go to the red GitHub Action job, +click on the "Re-run jobs" button on the top right, and select +"Re-run failed jobs". The button will only be present when all other jobs +finished running. + +Re-running failed jobs shouldn't be your first instinct but it is occasionally +helpful because distributed systems can have intermittent failures, and +some of our unit tests are sensitive to overloaded virtual machines. +If you identify such flaky behavior, look for an issue in the `issue tracker`_ +that describes this particular flakiness. Create a new issue if you can't +find one. Committing/rejecting ==================== @@ -522,3 +563,4 @@ accepts your pull request. .. _issue tracker: https://github.com/python/cpython/issues .. _Core Development Discourse category: https://discuss.python.org/c/core-dev/23 +.. _Release Status: https://buildbot.python.org/all/#/release_status diff --git a/triage/triaging.rst b/triage/triaging.rst index 89919450d..1d9e8809f 100644 --- a/triage/triaging.rst +++ b/triage/triaging.rst @@ -94,6 +94,7 @@ you can help by making sure the pull request: * includes a :ref:`NEWS entry ` (if needed) * includes the author in ``Misc/ACKS``, either already or the patch adds them * doesn't have conflicts with the ``main`` branch +* :ref:`doesn't have failing CI checks ` Doing all of this allows core developers and :ref:`triagers ` to more quickly look for subtle issues that only people with extensive From 653a6108613f27ca17deea175fe6ca5c50bff97d Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Thu, 8 Feb 2024 12:30:02 -0800 Subject: [PATCH 276/538] Document how to do a WASI build (#1273) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- getting-started/setup-building.rst | 101 +++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index b2dc2f1c2..0da5ba557 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -345,6 +345,107 @@ and how to build. .. _Git for Windows download from the official Git website: https://git-scm.com/download/win +.. _wasi-compiling: + +WASI +---- + +WASI_ is a system interface standard for WebAssembly_. Through a combination of +C compilers that can target WebAssembly and `wasi-libc`_ providing +POSIX-compatible shims for WASI, it's possible for CPython to run on a WASI +host/runtime as a *guest*. + +.. note:: + + The instructions below assume a Unix-based OS due to cross-compilation for + CPython being designed for ``./configure`` / ``make``. + +To build for WASI, you will need to cross-compile CPython. This requires a C +compiler just like building for :ref:`Unix ` as well as: + +1. A C compiler that can target WebAssembly (e.g. `WASI SDK`_) +2. A WASI host/runtime (e.g. 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. + +.. 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 + and their versions specified in the container 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 (i.e. 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 +Python you have installed on your machine): + +.. 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``, +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.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. + +Once everything is complete, there will be a +``cross-build/wasm32-wasi/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 + +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 +used in ``python.sh``: + +.. code-block:: shell + + $ make -C cross-build/wasm32-wasi test + +.. note:: + + WASI uses a *capability-based* security model. This means that the WASI host + does not give full access to your machine unless you tell it to. This + also means things like files can end up being mapped to a different path + inside the WASI host. So, if you try passing a file path to + ``python.wasm``/ ``python.sh``, it needs to match the path **inside** the + WASI host, not the path on your machine (much like using a container). + +.. _WASI: https://wasi.dev +.. _wasi-libc: https://github.com/WebAssembly/wasi-libc +.. _WASI SDK: https://github.com/WebAssembly/wasi-sdk +.. _wasmtime: https://wasmtime.dev +.. _WebAssembly: https://webassembly.org + .. _build-dependencies: .. _deps-on-linux: .. _macOS and OS X: From 833f102b0d68d90e121170b70ef5ebf5c34fe99c Mon Sep 17 00:00:00 2001 From: Eugene Toder Date: Mon, 12 Feb 2024 09:31:10 -0500 Subject: [PATCH 277/538] Remove reference to core-workflow (#1274) cherry_picker is in its own repo now. --- getting-started/git-boot-camp.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 2fb5e2f72..9b60f0e1c 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -552,8 +552,7 @@ by the label ``needs backport to X.Y`` on the pull request itself. Use the utility script `cherry_picker.py `_ -from the `core-workflow `_ -repository to backport the commit. +to backport the commit. The commit hash for backporting is the squashed commit that was merged to the ``main`` branch. On the merged pull request, scroll to the bottom of the From 5fde84570b70127d5246df2ad5cbbfba6158c4b6 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 18 Feb 2024 20:34:02 +0200 Subject: [PATCH 278/538] Replace BPO with GitHub links (#1276) --- testing/coverage.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/coverage.rst b/testing/coverage.rst index 62f075148..93273793a 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -232,7 +232,8 @@ you want the coverage data to end up it will go somewhere you don't expect. If you are running coverage over the entire test suite, make sure to add ``-x test_importlib test_runpy test_trace`` to exclude those tests as they trigger exceptions during coverage; see - https://bugs.python.org/issue10541 and https://bugs.python.org/issue10991. + `python/cpython#54750 `__ and + `python/cpython#55200 `__. Once the tests are done you will find the directory you specified contains files for each executed module along with which lines were executed how many From ecccd9b660b0685ca4de9d0f879f7b460ca98e48 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 26 Feb 2024 22:15:28 +0100 Subject: [PATCH 279/538] Replace most of "GDB Support" by a link to the main CPython docs (#1279) --- development-tools/gdb.rst | 360 +++----------------------------------- 1 file changed, 25 insertions(+), 335 deletions(-) diff --git a/development-tools/gdb.rst b/development-tools/gdb.rst index c6f781fbc..e85e826a0 100644 --- a/development-tools/gdb.rst +++ b/development-tools/gdb.rst @@ -6,345 +6,19 @@ GDB support .. highlight:: none -If you experience low-level problems such as crashes or deadlocks -(e.g. when tinkering with parts of CPython which are written in C), -it can be convenient to use a low-level debugger such as gdb in -order to diagnose and fix the issue. By default, however, gdb (or any -of its front-ends) doesn't know about high-level information specific to the -CPython interpreter, such as which Python function is currently executing, -or what type or value has a given Python object represented by a standard -``PyObject *`` pointer. We hereafter present two ways to overcome this -limitation. +Page moved +========== +Information on debugging CPython using GDB is now in the main Python +documentation, since it is relevant for C extension modules as well. +Please read it first: :ref:`python:gdb` -GDB 7 and later -=============== -In gdb 7, support for `extending gdb with Python -`_ was -added. When CPython is built you will notice a ``python-gdb.py`` file in the -root directory of your checkout. Read the module docstring for details on how -to use the file to enhance gdb for easier debugging of a CPython process. +CPython tips +============ -To activate support, you must add the directory containing ``python-gdb.py`` -to GDB's "auto-load-safe-path". Put this in your ``~/.gdbinit`` file:: - - add-auto-load-safe-path /path/to/checkout - -You can also add multiple paths, separated by ``:``. - -This is what a backtrace looks like (truncated) when this extension is -enabled:: - - #0 0x000000000041a6b1 in PyObject_Malloc (nbytes=Cannot access memory at address 0x7fffff7fefe8 - ) at Objects/obmalloc.c:748 - #1 0x000000000041b7c0 in _PyObject_DebugMallocApi (id=111 'o', nbytes=24) at Objects/obmalloc.c:1445 - #2 0x000000000041b717 in _PyObject_DebugMalloc (nbytes=24) at Objects/obmalloc.c:1412 - #3 0x000000000044060a in _PyUnicode_New (length=11) at Objects/unicodeobject.c:346 - #4 0x00000000004466aa in PyUnicodeUCS2_DecodeUTF8Stateful (s=0x5c2b8d "__lltrace__", size=11, errors=0x0, consumed= - 0x0) at Objects/unicodeobject.c:2531 - #5 0x0000000000446647 in PyUnicodeUCS2_DecodeUTF8 (s=0x5c2b8d "__lltrace__", size=11, errors=0x0) - at Objects/unicodeobject.c:2495 - #6 0x0000000000440d1b in PyUnicodeUCS2_FromStringAndSize (u=0x5c2b8d "__lltrace__", size=11) - at Objects/unicodeobject.c:551 - #7 0x0000000000440d94 in PyUnicodeUCS2_FromString (u=0x5c2b8d "__lltrace__") at Objects/unicodeobject.c:569 - #8 0x0000000000584abd in PyDict_GetItemString (v= - {'Yuck': , '__builtins__': , '__file__': 'Lib/test/crashers/nasty_eq_vs_dict.py', '__package__': None, 'y': , 'dict': {0: 0, 1: 1, 2: 2, 3: 3}, '__cached__': None, '__name__': '__main__', 'z': , '__doc__': None}, key= - 0x5c2b8d "__lltrace__") at Objects/dictobject.c:2171 - -(Notice how the dictionary argument to ``PyDict_GetItemString`` is displayed -as its ``repr()``, rather than an opaque ``PyObject *`` pointer.) - -The extension works by supplying a custom printing routine for values of type -``PyObject *``. If you need to access lower-level details of an object, then -cast the value to a pointer of the appropriate type. For example:: - - (gdb) p globals - $1 = {'__builtins__': , '__name__': - '__main__', 'ctypes': , '__doc__': None, - '__package__': None} - - (gdb) p *(PyDictObject*)globals - $2 = {ob_refcnt = 3, ob_type = 0x3dbdf85820, ma_fill = 5, ma_used = 5, - ma_mask = 7, ma_table = 0x63d0f8, ma_lookup = 0x3dbdc7ea70 - , ma_smalltable = {{me_hash = 7065186196740147912, - me_key = '__builtins__', me_value = }, - {me_hash = -368181376027291943, me_key = '__name__', - me_value ='__main__'}, {me_hash = 0, me_key = 0x0, me_value = 0x0}, - {me_hash = 0, me_key = 0x0, me_value = 0x0}, - {me_hash = -9177857982131165996, me_key = 'ctypes', - me_value = }, - {me_hash = -8518757509529533123, me_key = '__doc__', me_value = None}, - {me_hash = 0, me_key = 0x0, me_value = 0x0}, { - me_hash = 6614918939584953775, me_key = '__package__', me_value = None}}} - -The pretty-printers try to closely match the ``repr()`` implementation of the -underlying implementation of Python, and thus vary somewhat between Python 2 -and Python 3. - -An area that can be confusing is that the custom printer for some types look a -lot like gdb's built-in printer for standard types. For example, the -pretty-printer for a Python 3 ``int`` gives a ``repr()`` that is not -distinguishable from a printing of a regular machine-level integer:: - - (gdb) p some_machine_integer - $3 = 42 - - (gdb) p some_python_integer - $4 = 42 - - (gdb) p *(PyLongObject*)some_python_integer - $5 = {ob_base = {ob_base = {ob_refcnt = 8, ob_type = 0x3dad39f5e0}, ob_size = 1}, - ob_digit = {42}} - -A similar confusion can arise with the ``str`` type, where the output looks a -lot like gdb's built-in printer for ``char *``:: - - (gdb) p ptr_to_python_str - $6 = '__builtins__' - -The pretty-printer for ``str`` instances defaults to using single-quotes (as -does Python's ``repr`` for strings) whereas the standard printer for ``char *`` -values uses double-quotes and contains a hexadecimal address:: - - (gdb) p ptr_to_char_star - $7 = 0x6d72c0 "hello world" - -Here's how to see the implementation details of a ``str`` instance (for Python -3, where a ``str`` is a ``PyUnicodeObject *``):: - - (gdb) p *(PyUnicodeObject*)$6 - $8 = {ob_base = {ob_refcnt = 33, ob_type = 0x3dad3a95a0}, length = 12, - str = 0x7ffff2128500, hash = 7065186196740147912, state = 1, defenc = 0x0} - -As well as adding pretty-printing support for ``PyObject *``, -the extension adds a number of commands to gdb: - -``py-list`` - List the Python source code (if any) for the current frame in the selected - thread. The current line is marked with a ">":: - - (gdb) py-list - 901 if options.profile: - 902 options.profile = False - 903 profile_me() - 904 return - 905 - >906 u = UI() - 907 if not u.quit: - 908 try: - 909 gtk.main() - 910 except KeyboardInterrupt: - 911 # properly quit on a keyboard interrupt... - - Use ``py-list START`` to list at a different line number within the python - source, and ``py-list START,END`` to list a specific range of lines within - the python source. - -``py-up`` and ``py-down`` - The ``py-up`` and ``py-down`` commands are analogous to gdb's regular ``up`` - and ``down`` commands, but try to move at the level of CPython frames, rather - than C frames. - - gdb is not always able to read the relevant frame information, depending on - the optimization level with which CPython was compiled. Internally, the - commands look for C frames that are executing ``PyEval_EvalFrameEx`` (which - implements the core bytecode interpreter loop within CPython) and look up - the value of the related ``PyFrameObject *``. - - They emit the frame number (at the C level) within the thread. - - For example:: - - (gdb) py-up - #37 Frame 0x9420b04, for file /usr/lib/python2.6/site-packages/ - gnome_sudoku/main.py, line 906, in start_game () - u = UI() - (gdb) py-up - #40 Frame 0x948e82c, for file /usr/lib/python2.6/site-packages/ - gnome_sudoku/gnome_sudoku.py, line 22, in start_game(main=) - main.start_game() - (gdb) py-up - Unable to find an older python frame - - so we're at the top of the python stack. Going back down:: - - (gdb) py-down - #37 Frame 0x9420b04, for file /usr/lib/python2.6/site-packages/gnome_sudoku/main.py, line 906, in start_game () - u = UI() - (gdb) py-down - #34 (unable to read python frame information) - (gdb) py-down - #23 (unable to read python frame information) - (gdb) py-down - #19 (unable to read python frame information) - (gdb) py-down - #14 Frame 0x99262ac, for file /usr/lib/python2.6/site-packages/gnome_sudoku/game_selector.py, line 201, in run_swallowed_dialog (self=, puzzle=None, saved_games=[{'gsd.auto_fills': 0, 'tracking': {}, 'trackers': {}, 'notes': [], 'saved_at': 1270084485, 'game': '7 8 0 0 0 0 0 5 6 0 0 9 0 8 0 1 0 0 0 4 6 0 0 0 0 7 0 6 5 0 0 0 4 7 9 2 0 0 0 9 0 1 0 0 0 3 9 7 6 0 0 0 1 8 0 6 0 0 0 0 2 8 0 0 0 5 0 4 0 6 0 0 2 1 0 0 0 0 0 4 5\n7 8 0 0 0 0 0 5 6 0 0 9 0 8 0 1 0 0 0 4 6 0 0 0 0 7 0 6 5 1 8 3 4 7 9 2 0 0 0 9 0 1 0 0 0 3 9 7 6 0 0 0 1 8 0 6 0 0 0 0 2 8 0 0 0 5 0 4 0 6 0 0 2 1 0 0 0 0 0 4 5', 'gsd.impossible_hints': 0, 'timer.__absolute_start_time__': , 'gsd.hints': 0, 'timer.active_time': , 'timer.total_time': }], dialog=, saved_game_model=, sudoku_maker=, main_page=0) at remote 0x98fa6e4>, d=) - gtk.main() - (gdb) py-down - #8 (unable to read python frame information) - (gdb) py-down - Unable to find a newer python frame - - and we're at the bottom of the python stack. - -``py-bt`` - The ``py-bt`` command attempts to display a Python-level backtrace of the - current thread. - - For example:: - - (gdb) py-bt - #8 (unable to read python frame information) - #11 Frame 0x9aead74, for file /usr/lib/python2.6/site-packages/gnome_sudoku/dialog_swallower.py, line 48, in run_dialog (self=, main_page=0) at remote 0x98fa6e4>, d=) - gtk.main() - #14 Frame 0x99262ac, for file /usr/lib/python2.6/site-packages/gnome_sudoku/game_selector.py, line 201, in run_swallowed_dialog (self=, puzzle=None, saved_games=[{'gsd.auto_fills': 0, 'tracking': {}, 'trackers': {}, 'notes': [], 'saved_at': 1270084485, 'game': '7 8 0 0 0 0 0 5 6 0 0 9 0 8 0 1 0 0 0 4 6 0 0 0 0 7 0 6 5 0 0 0 4 7 9 2 0 0 0 9 0 1 0 0 0 3 9 7 6 0 0 0 1 8 0 6 0 0 0 0 2 8 0 0 0 5 0 4 0 6 0 0 2 1 0 0 0 0 0 4 5\n7 8 0 0 0 0 0 5 6 0 0 9 0 8 0 1 0 0 0 4 6 0 0 0 0 7 0 6 5 1 8 3 4 7 9 2 0 0 0 9 0 1 0 0 0 3 9 7 6 0 0 0 1 8 0 6 0 0 0 0 2 8 0 0 0 5 0 4 0 6 0 0 2 1 0 0 0 0 0 4 5', 'gsd.impossible_hints': 0, 'timer.__absolute_start_time__': , 'gsd.hints': 0, 'timer.active_time': , 'timer.total_time': }], dialog=, saved_game_model=, sudoku_maker=) - main.start_game() - - The frame numbers correspond to those displayed by gdb's standard - ``backtrace`` command. - -``py-print`` - The ``py-print`` command looks up a Python name and tries to print it. - It looks in locals within the current thread, then globals, then finally - builtins:: - - (gdb) py-print self - local 'self' = , - main_page=0) at remote 0x98fa6e4> - (gdb) py-print __name__ - global '__name__' = 'gnome_sudoku.dialog_swallower' - (gdb) py-print len - builtin 'len' = - (gdb) py-print scarlet_pimpernel - 'scarlet_pimpernel' not found - -``py-locals`` - The ``py-locals`` command looks up all Python locals within the current - Python frame in the selected thread, and prints their representations:: - - (gdb) py-locals - self = , - main_page=0) at remote 0x98fa6e4> - d = - -You can of course use other gdb commands. For example, the ``frame`` command -takes you directly to a particular frame within the selected thread. -We can use it to go a specific frame shown by ``py-bt`` like this:: - - (gdb) py-bt - (output snipped) - #68 Frame 0xaa4560, for file Lib/test/regrtest.py, line 1548, in () - main() - (gdb) frame 68 - #68 0x00000000004cd1e6 in PyEval_EvalFrameEx (f=Frame 0xaa4560, for file Lib/test/regrtest.py, line 1548, in (), throwflag=0) at Python/ceval.c:2665 - 2665 x = call_function(&sp, oparg); - (gdb) py-list - 1543 # Run the tests in a context manager that temporary changes the CWD to a - 1544 # temporary and writable directory. If it's not possible to create or - 1545 # change the CWD, the original CWD will be used. The original CWD is - 1546 # available from test_support.SAVEDCWD. - 1547 with test_support.temp_cwd(TESTCWD, quiet=True): - >1548 main() - -The ``info threads`` command will give you a list of the threads within the -process, and you can use the ``thread`` command to select a different one:: - - (gdb) info threads - 105 Thread 0x7fffefa18710 (LWP 10260) sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86 - 104 Thread 0x7fffdf5fe710 (LWP 10259) sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86 - * 1 Thread 0x7ffff7fe2700 (LWP 10145) 0x00000038e46d73e3 in select () at ../sysdeps/unix/syscall-template.S:82 - -You can use ``thread apply all COMMAND`` or (``t a a COMMAND`` for short) to run -a command on all threads. You can use this with ``py-bt`` to see what every -thread is doing at the Python level:: - - (gdb) t a a py-bt - - Thread 105 (Thread 0x7fffefa18710 (LWP 10260)): - #5 Frame 0x7fffd00019d0, for file /home/david/coding/python-svn/Lib/threading.py, line 155, in _acquire_restore (self=<_RLock(_Verbose__verbose=False, _RLock__owner=140737354016512, _RLock__block=, _RLock__count=1) at remote 0xd7ff40>, count_owner=(1, 140737213728528), count=1, owner=140737213728528) - self.__block.acquire() - #8 Frame 0x7fffac001640, for file /home/david/coding/python-svn/Lib/threading.py, line 269, in wait (self=<_Condition(_Condition__lock=<_RLock(_Verbose__verbose=False, _RLock__owner=140737354016512, _RLock__block=, _RLock__count=1) at remote 0xd7ff40>, acquire=, _is_owned=, _release_save=, release=, _acquire_restore=, _Verbose__verbose=False, _Condition__waiters=[]) at remote 0xd7fd10>, timeout=None, waiter=, saved_state=(1, 140737213728528)) - self._acquire_restore(saved_state) - #12 Frame 0x7fffb8001a10, for file /home/david/coding/python-svn/Lib/test/lock_tests.py, line 348, in f () - cond.wait() - #16 Frame 0x7fffb8001c40, for file /home/david/coding/python-svn/Lib/test/lock_tests.py, line 37, in task (tid=140737213728528) - f() - - Thread 104 (Thread 0x7fffdf5fe710 (LWP 10259)): - #5 Frame 0x7fffe4001580, for file /home/david/coding/python-svn/Lib/threading.py, line 155, in _acquire_restore (self=<_RLock(_Verbose__verbose=False, _RLock__owner=140737354016512, _RLock__block=, _RLock__count=1) at remote 0xd7ff40>, count_owner=(1, 140736940992272), count=1, owner=140736940992272) - self.__block.acquire() - #8 Frame 0x7fffc8002090, for file /home/david/coding/python-svn/Lib/threading.py, line 269, in wait (self=<_Condition(_Condition__lock=<_RLock(_Verbose__verbose=False, _RLock__owner=140737354016512, _RLock__block=, _RLock__count=1) at remote 0xd7ff40>, acquire=, _is_owned=, _release_save=, release=, _acquire_restore=, _Verbose__verbose=False, _Condition__waiters=[]) at remote 0xd7fd10>, timeout=None, waiter=, saved_state=(1, 140736940992272)) - self._acquire_restore(saved_state) - #12 Frame 0x7fffac001c90, for file /home/david/coding/python-svn/Lib/test/lock_tests.py, line 348, in f () - cond.wait() - #16 Frame 0x7fffac0011c0, for file /home/david/coding/python-svn/Lib/test/lock_tests.py, line 37, in task (tid=140736940992272) - f() - - Thread 1 (Thread 0x7ffff7fe2700 (LWP 10145)): - #5 Frame 0xcb5380, for file /home/david/coding/python-svn/Lib/test/lock_tests.py, line 16, in _wait () - time.sleep(0.01) - #8 Frame 0x7fffd00024a0, for file /home/david/coding/python-svn/Lib/test/lock_tests.py, line 378, in _check_notify (self=, skipped=[], _mirrorOutput=False, testsRun=39, buffer=False, _original_stderr=, _stdout_buffer=, _stderr_buffer=, _moduleSetUpFailed=False, expectedFailures=[], errors=[], _previousTestClass=, unexpectedSuccesses=[], failures=[], shouldStop=False, failfast=False) at remote 0xc185a0>, _threads=(0,), _cleanups=[], _type_equality_funcs={: , : , : , : , Date: Thu, 29 Feb 2024 15:06:54 +0100 Subject: [PATCH 280/538] Document the OS-Unsupported label and Platforms experts list (GH-1281) Co-Authored-By: Erlend E. Aasland --- core-developers/experts.rst | 9 ++++++++- triage/labels.rst | 11 ++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 628831d37..5ab3d9083 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -282,14 +282,21 @@ PEG Generator gvanrossum, pablogsal, lysnikolaou ================== =========== +.. _platform-experts: + Platforms ========= +For official contacts for supported platforms, see :pep:`11`. + +Platforms listed here are not necessarily supported by CPython. +Some of the experts listed here maintain and distribute Python +for “their” platform as a third-party project. + =================== =========== Platform Maintainers =================== =========== AIX David.Edelsohn^ -Android Cygwin jlt63^, stutzbach^ Emscripten hoodmane, pmp-p, rdb, rth, ryanking13 FreeBSD diff --git a/triage/labels.rst b/triage/labels.rst index 6cc54360c..95719615b 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -61,9 +61,14 @@ OS labels These labels are used to specify which operating systems are affected. Since most issues either affect all systems or are specific to Unix, -the only available labels are :gh-label:`OS-windows`, :gh-label:`OS-mac`, -and :gh-label:`OS-freebsd`. - +we don't have a dedicated Unix label. +Use :gh-label:`OS-windows`, :gh-label:`OS-mac`, and :gh-label:`OS-freebsd`. + +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 +it can be categorized further. +See also the :ref:`Platform experts list `. .. _Expert labels: .. _Topic labels: From 49d823f0ec47402d61321fe4cd2948f260cd8aee Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 3 Mar 2024 23:26:04 +0200 Subject: [PATCH 281/538] Fix 'Install dependencies' links (#1282) --- getting-started/setup-building.rst | 2 +- index.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 0da5ba557..fd1bce86d 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -455,7 +455,7 @@ Install dependencies ==================== This section explains how to install additional extensions (e.g. ``zlib``) -on :ref:`Linux ` and :ref:`macOS`. +on Linux and macOS. .. tab:: Linux diff --git a/index.rst b/index.rst index 779977963..5dddafd0f 100644 --- a/index.rst +++ b/index.rst @@ -58,7 +58,7 @@ instructions please see the :ref:`setup guide `. See also :ref:`more detailed instructions `, :ref:`how to install and build dependencies `, and the platform-specific pages for :ref:`Unix `, - :ref:`macOS`, and :ref:`Windows `. + :ref:`macOS `, and :ref:`Windows `. 4. :ref:`Run the tests `: From a78e332346f9e7dc416f30d5e7ef3cc00e85a3aa Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Fri, 8 Mar 2024 17:19:01 +0300 Subject: [PATCH 282/538] Add myself to `typing` experts (#1288) I cannot say that I know all about `typing` in Python, but I can still be helpful. I don't want to be a codeowner on GitHub, because I will get too many notifications, but I can add myself here for better visibility for others: I am open to help, answer questions, and review PRs. If @JelleZijlstra and @AlexWaygood agree :) --- 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 5ab3d9083..d79d5cf8d 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -237,7 +237,7 @@ tracemalloc vstinner tty Yhg1s* turtle gregorlingl^, willingc types 1st1 -typing gvanrossum, JelleZijlstra*, AlexWaygood*, carljm +typing gvanrossum, JelleZijlstra*, AlexWaygood*, carljm, sobolevn* unicodedata malemburg, ezio-melotti unittest voidspace*, ezio-melotti, rbtcollins, gpshead unittest.mock voidspace* From 3732839b29ed48ffc0503df6937129b590bdb95b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:34:45 +0200 Subject: [PATCH 283/538] Revise specific guidance about avoiding 'CPU' (#1289) * Remove specific guidance about avoiding 'CPU' * Retain CPU entry: no need to spell out This reverts commit 92f54024c880f497379b49ed0fc5c83032114a6e. --- documentation/style-guide.rst | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index 2fba1e1fc..2e5a1c953 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -79,12 +79,7 @@ C API to write extension modules. All caps and unhyphenated. CPU - For "central processing unit." Many style guides say this should be - spelled out on the first use (and if you must use it, do so!). For - the Python documentation, this abbreviation should be avoided since - there's no reasonable way to predict which occurrence will be the - first seen by the reader. It is better to use the word "processor" - instead. + Central processing unit. No need to spell out. POSIX The name assigned to a particular group of standards. This is always From 235cc7faa650e3bb01f8d17907963e159c957453 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 19 Mar 2024 15:10:37 -0400 Subject: [PATCH 284/538] Explain that a venv is being created (#1291) --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index e394e0d4b..76f5b9df5 100644 --- a/Makefile +++ b/Makefile @@ -69,6 +69,7 @@ venv: .PHONY: ensure-venv ensure-venv: @if [ ! -d $(VENVDIR) ] ; then \ + echo "Creating venv in $(VENVDIR)"; \ $(PYTHON) -m venv $(VENVDIR); \ $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \ $(VENVDIR)/bin/python3 -m pip install -r requirements.txt; \ From 0140f3cebdac237c1bd9ede4b1a4724ff903441a Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 19 Mar 2024 22:45:47 -0400 Subject: [PATCH 285/538] Move markup concerns from style to markup (#1292) --- documentation/markup.rst | 38 +++++++++++++++++++++++++++++++++++ documentation/style-guide.rst | 37 +++------------------------------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index e457a525f..c7a5a5ac4 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -52,6 +52,22 @@ language, this will not take too long. Documentation `_. +Use of whitespace +----------------- + +All reST files use an indentation of 3 spaces; no tabs are allowed. The +maximum line length is 80 characters for normal text, but tables, deeply +indented code samples and long links may extend beyond that. Code example +bodies should use normal Python 4-space indentation. + +Make use of multiple blank lines where applicable to clarify the structure of +the reST file. Extra blank lines help group sections together to make the +organization of the file clearer. + +A sentence-ending period may be followed by one or two spaces. While reST +ignores the second space, it is customarily put in by some users, for example +to aid Emacs' auto-fill mode. + Paragraphs ---------- @@ -289,6 +305,28 @@ There are some problems one commonly runs into while authoring reST documents: separated from the surrounding text by non-word characters, you have to use an escaped space to get around that. + +Typographic conventions +======================= + +Big *O* notation +---------------- + +Big *O* notation is used to describe the performance of algorithms. + +Use italics for the big *O* and variables. For example: + +======================== ==================== +reStructuredText Rendered +======================== ==================== +``*O*\ (1)`` *O*\ (1) +``*O*\ (log *n*)`` *O*\ (log *n*) +``*O*\ (*n*)`` *O*\ (*n*) +``*O*\ (*n* log *n*)`` *O*\ (*n* log *n*) +``*O*\ (*n*\ :sup:`2`)`` *O*\ (*n*\ :sup:`2`) +======================== ==================== + + .. _additional-markup-constructs: Additional markup constructs diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index 2e5a1c953..0078d670e 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -4,26 +4,12 @@ Style guide =========== -.. highlight:: rest +.. highlight:: rest -This document describes the style guide for our documentation. +This page describes the linguistic style guide for our documentation. +For markup details in reST files, see :ref:`markup`. -Use of whitespace -================= - -All reST files use an indentation of 3 spaces; no tabs are allowed. The -maximum line length is 80 characters for normal text, but tables, deeply -indented code samples and long links may extend beyond that. Code example -bodies should use normal Python 4-space indentation. - -Make generous use of blank lines where applicable; they help group things -together. - -A sentence-ending period may be followed by one or two spaces; while reST -ignores the second space, it is customarily put in by some users, for example -to aid Emacs' auto-fill mode. - Footnotes ========= @@ -264,20 +250,3 @@ errors ("I made a mistake, therefore the docs must be wrong ..."). Typically, the documentation wasn't consulted until after the error was made. It is unfortunate, but typically no documentation edit would have saved the user from making false assumptions about the language ("I was surprised by ..."). - -Big *O* notation -================ - -Big *O* notation is used to describe the performance of algorithms. - -Use italics for the big *O* and variables. For example: - -======================== ==================== -reStructuredText Rendered -======================== ==================== -``*O*\ (1)`` *O*\ (1) -``*O*\ (log *n*)`` *O*\ (log *n*) -``*O*\ (*n*)`` *O*\ (*n*) -``*O*\ (*n* log *n*)`` *O*\ (*n* log *n*) -``*O*\ (*n*\ :sup:`2`)`` *O*\ (*n*\ :sup:`2`) -======================== ==================== From 1eae014f30babae14afb41bd9b17bb9a40051b3c Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 19 Mar 2024 22:46:09 -0400 Subject: [PATCH 286/538] Footnotes are discouraged (#1290) --- documentation/markup.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index c7a5a5ac4..dfabcd666 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -699,7 +699,7 @@ Syntax highlighting is handled in a smart way: Longer displays of verbatim text may be included by storing the example text in an external file containing only plain text. The file may be included using the -``literalinclude`` directive. [1]_ For example, to include the Python source +``literalinclude`` directive. For example, to include the Python source file :file:`example.py`, use:: .. literalinclude:: example.py @@ -707,6 +707,13 @@ file :file:`example.py`, use:: The file name is relative to the current file's path. Documentation-specific include files should be placed in the ``Doc/includes`` subdirectory. +.. note:: + + There is a standard ``include`` directive, but it raises errors if the + file is not found. ``literalinclude`` is preferred because it only emits a + warning instead of raising an error. + + .. _rest-inline-markup: .. _roles: @@ -1326,9 +1333,3 @@ default. They are set in the build configuration file :file:`conf.py`. Replaced by either today's date, or the date set in the build configuration file. Normally has the format ``April 14, 2007``. - - -.. rubric:: Footnotes - -.. [1] There is a standard ``include`` directive, but it raises errors if the - file is not found. This one only emits a warning. From c53c0541e23deb3a1ed40ecfd0f2d552b251ae19 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 20 Mar 2024 17:41:36 -0400 Subject: [PATCH 287/538] No need for old redirect sections (#1295) --- documentation/start-documenting.rst | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/documentation/start-documenting.rst b/documentation/start-documenting.rst index fec76fa97..184cf54bf 100644 --- a/documentation/start-documenting.rst +++ b/documentation/start-documenting.rst @@ -215,15 +215,3 @@ replace ``html`` above with the desired builder ``name``. .. _Sphinx Lint: https://github.com/sphinx-contrib/sphinx-lint .. _venv-activate: https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#activating-a-virtual-environment .. _venv-create: https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment - - -Style guide -=========== - -Moved to :doc:`style-guide`. - - -Translating -=========== - -Moved to :doc:`translating`. From 520b6b0064a2fe252b97b2f34b62a86d383368e8 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Fri, 22 Mar 2024 20:49:24 +0100 Subject: [PATCH 288/538] Add GR translation link and contacts (#1297) Co-authored-by: Ezio Melotti --- documentation/translating.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/documentation/translating.rst b/documentation/translating.rst index 2f5b498e4..2d8cb86d4 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -25,6 +25,12 @@ in production; others are works in progress. | French (fr) | `Julien Palard (@JulienPalard)| `GitHub `_ | | | `_ | | +-----------------+-------------------------------+----------------------------+ +| Greek (gr) | `Lysandros Nikolaou | `GitHub `_ | +| | (@lysnikolaou) | | +| | `_, | | +| | `Fanis Petkos (@thepetk) | | +| | `_ | | ++-----------------+-------------------------------+----------------------------+ | Hindi as spoken | | `GitHub `_ | | in India (hi_IN)| | | +-----------------+-------------------------------+----------------------------+ @@ -100,6 +106,8 @@ in production; others are works in progress. .. _gh_dumeng: https://github.com/dumeng .. _gh_mattwang44: https://github.com/mattwang44 .. _gh_egeakman: https://github.com/egeakman +.. _gh_lysnikolaou: https://github.com/lysnikolaou +.. _gh_thepetk: https://github.com/thepetk .. _email_garade: mailto:garade@pm.me .. _email_kazanzhy: mailto:dkazanzhy@gmail.com .. _chat_pt_br: https://t.me/pybr_i18n @@ -127,6 +135,7 @@ in production; others are works in progress. .. _github_zh_cn: https://github.com/python/python-docs-zh-cn .. _github_zh_tw: https://github.com/python/python-docs-zh-tw .. _github_ru: https://github.com/MLGRussianXP/python-docs-ru +.. _github_gr: https://github.com/pygreece/python-docs-gr .. _list_hu: https://mail.python.org/pipermail/python-hu .. _mail_it: https://mail.python.org/pipermail/doc-sig/2019-April/004114.html .. _mail_lt: https://mail.python.org/pipermail/doc-sig/2019-July/004138.html From d92fda3beb5506eb42d53fee1c52d31180e9d77a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 25 Mar 2024 23:17:06 +0200 Subject: [PATCH 289/538] Add diataxis index for searching (#1301) --- documentation/style-guide.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index 0078d670e..8e043895b 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -87,6 +87,9 @@ Unix The name of the operating system developed at AT&T Bell Labs in the early 1970s. + +.. index:: diataxis + Diátaxis ======== From 45f7b020ef6fb446873b55d6a38b3b59cda980fa Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Wed, 27 Mar 2024 16:42:36 +0800 Subject: [PATCH 290/538] Add iOS instructions to the devguide (#1296) Co-authored-by: Ezio Melotti Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- README.rst | 8 ++ getting-started/setup-building.rst | 162 ++++++++++++++++++++++++++++- 2 files changed, 169 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f8f7ff251..fde4a6c27 100644 --- a/README.rst +++ b/README.rst @@ -27,3 +27,11 @@ Render HTML To render the devguide to HTML under ``_build/html``, run:: make html + +To render the devguide to HTML, and open the result in a browser, run:: + + make htmlview + +To maintain a live view of edits as they are saved, run:: + + make htmllive diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index fd1bce86d..30b756708 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -446,6 +446,148 @@ used in ``python.sh``: .. _wasmtime: https://wasmtime.dev .. _WebAssembly: https://webassembly.org +iOS +--- + +Compiling Python for iOS requires a macOS machine, on a recent version of macOS, +running a recent version of Xcode. Apple expects developers to keep their +operating systems and tools up-to-date; if your macOS version is more than one +major release out of date, or your Xcode version is more than a couple of minor +versions out of date, you'll likely encounter difficulties. It is not possible +to compile for iOS using Windows or Linux as a build machine. + +A complete build for Python on iOS requires compiling CPython four times: once for +macOS; then once for each of the three underlying platforms used by iOS: + +* An ARM64 device (an iPhone or iPad); +* An ARM64 simulator running on a recent macOS machine; and +* An x86_64 simulator running on older macOS machine. + +The macOS build is required because building Python involves running some Python +code. On a normal desktop build of Python, you can compile a Python interpreter +and then use that interpreter to run Python code. However, the binaries produced +for iOS won't run on macOS, so you need to provide an external Python +interpreter. From the root of a CPython code checkout, run the following:: + + $ ./configure --prefix=$(pwd)/cross-build/macOS + $ make -j4 all + $ make install + +This will build and install Python for macOS into the ``cross-build/macOS`` +directory. + +The CPython build system can compile a single platform at a time. It is possible +to *test* a single platform at a time; however, for distribution purposes, you +must compile all three, and merge the results. See the `iOS README +`__ +for details on this merging process. + +The following instructions will build CPython for iOS with all extensions +enabled, provided you have installed the build dependencies XZ, BZip2, OpenSSL +and libFFI in subfolders of the ``cross-build`` folder. See :ref:`the iOS +section on installing build dependencies ` for details on +how to obtain these dependencies. These dependencies are all strictly optional, +however, including libFFI is *highly* recommended, as it is required by the +:py:mod:`ctypes` module which is used on iOS to support accessing native system APIs. + +.. tab:: ARM64 device + + .. code-block:: console + + $ export PATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin" + $ ./configure \ + LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/xz/include" \ + LIBLZMA_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/xz/lib -llzma" \ + BZIP2_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/bzip2/include" \ + BZIP2_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/bzip2/lib -lbz2" \ + LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/libffi/include" \ + LIBFFI_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/libffi/lib -lffi" \ + --with-openssl="$(pwd)/cross-build/iphoneos.arm64/openssl" \ + --host=arm64-apple-ios12.0 \ + --build=arm64-apple-darwin \ + --with-build-python=$(pwd)/cross-build/macOS/bin/python3.13 \ + --enable-framework + $ make -j4 all + $ make install + +.. tab:: ARM64 simulator + + .. code-block:: console + + $ export PATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin" + $ ./configure \ + LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/xz/include" \ + LIBLZMA_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/xz/lib -llzma" \ + BZIP2_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/bzip2/include" \ + BZIP2_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/bzip2/lib -lbz2" \ + LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/libffi/include" \ + LIBFFI_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/libffi/lib -lffi" \ + --with-openssl="$(pwd)/cross-build/iphonesimulator.arm64/openssl" \ + --host=arm64-apple-ios12.0-simulator \ + --build=arm64-apple-darwin \ + --with-build-python=$(pwd)/cross-build/macOS/bin/python3.13 \ + --enable-framework + $ make -j4 all + $ make install + +.. tab:: x86-64 simulator + + .. code-block:: console + + $ export PATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin" + $ ./configure \ + LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/xz/include" \ + LIBLZMA_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/xz/lib -llzma" \ + BZIP2_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/bzip2/include" \ + BZIP2_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/bzip2/lib -lbz2" \ + LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/libffi/include" \ + LIBFFI_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/libffi/lib -lffi" \ + --with-openssl="$(pwd)/cross-build/iphonesimulator.x86_64/openssl" \ + --host=x86_64-apple-ios12.0-simulator \ + --build=arm64-apple-darwin \ + --with-build-python=$(pwd)/cross-build/macOS/bin/python3.13 \ + --enable-framework + $ make -j4 all + $ make install + +These instructions modify your ``PATH`` before the build. As iOS and macOS share +a hardware architecture (ARM64), it is easy for a macOS ARM64 binary to be +accidentally linked into your iOS build. This is especially common when Homebrew +is present on the build system. The most reliable way to avoid this problem is +to remove any potential source of other libraries from your ``PATH``. + +However, the ``PATH`` is not completely bare --- it includes the +``iOS/Resources/bin`` folder. This folder contains a collection of scripts that +wrap the invocation of the Xcode :program:`xcrun` tool, removing user- and +version-specific paths from the values encoded in the :py:mod:`sysconfig` +module. Copies of these scripts are included in the final build products. + +Once this build completes, the ``iOS/Frameworks`` folder will contain a +``Python.framework`` that can be used for testing. + +To run the test suite on iOS, complete a build for a *simulator* platform, +ensure the path modifications from the build are still in effect, and run:: + + $ make testios + +The full test suite takes approximately 12 minutes to run on a 2022 M1 MacBook +Pro, plus a couple of extra minutes to build the testbed application and boot +the simulator. There will be an initial burst of console output while the Xcode +test project is compiled; however, while the test suite is running, there is no +console output or progress. This is a side effect of how Xcode operates when +executed at the command line. You should see an iOS simulator appear during the +testing process; the simulator will booth to an iOS landing screen, the testbed +app will be installed, and then started. The screen of the simulator will be +black while the test suite is running. When the test suite completes, success or +failure will be reported at the command line. In the case of failure, you will +see the full log of CPython test suite output. + +You can also run the test suite in Xcode itself. This is required if you want to +run on a physical device; it is also the easiest approach if you need to run a +single test, or a subset of tests. See the `iOS README +`__ +for details. + .. _build-dependencies: .. _deps-on-linux: .. _macOS and OS X: @@ -455,7 +597,7 @@ Install dependencies ==================== This section explains how to install additional extensions (e.g. ``zlib``) -on Linux and macOS. +on Linux, macOS and iOS. .. tab:: Linux @@ -597,6 +739,24 @@ on Linux and macOS. On Windows, extensions are already included and built automatically. +.. tab:: iOS + + As with CPython itself, the dependencies for CPython must be compiled for + each of the hardware architectures that iOS supports. Consult the + documentation for `XZ `__, `bzip2 + `__, `OpenSSL `__ and + `libffi `__ for details on how to configure + the project for cross-platform iOS builds. + + Alternatively, the `BeeWare Project `__ maintains a + `project for building iOS dependencies + `__, and distributes + `pre-compiled binaries + `__ for each + of the dependencies. If you use this project to build the dependencies + yourself, the subfolders of the ``install`` folder can be used to configure + CPython. If you use the pre-compiled binaries, you should unpack each tarball + into a separate folder, and use that folder as the configuration target. .. _regenerate_configure: From ea7063ae38b1b72de5c6be3282bcda02b4ef833e Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 27 Mar 2024 09:03:07 -0400 Subject: [PATCH 291/538] Avoid over-linking #1293 (#1294) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Avoid over-linking * Update documentation/markup.rst Co-authored-by: Éric * two updates from comments * update per ezio-melotti's comment https://github.com/python/devguide/pull/1294#discussion_r1535088844 * fix a sphinx lint failure * Update documentation/markup.rst Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --------- Co-authored-by: Éric Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- documentation/markup.rst | 4 ++++ documentation/style-guide.rst | 30 +++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index dfabcd666..830493a31 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -753,6 +753,10 @@ versatile: In HTML output, the link's ``title`` attribute (that is e.g. shown as a tool-tip on mouse-hover) will always be the full target name. +* Combining ``~`` and ``!`` (for example, ``:meth:`~!Queue.Queue.get```) is not + supported. You can obtain the same result by using ``!`` and the last + component of the target (for example, ``:meth:`!get```). + The following roles refer to objects in modules and are possibly hyperlinked if a matching identifier is found: diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index 8e043895b..1e94e518d 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -127,11 +127,39 @@ explanation. provide context, make connections between topics, and discuss alternative opinions. There is no section dedicated to explanations but these can be found throughout Python's documentation, for example the - :ref:`python:unicode-howto` + :ref:`python:unicode-howto`. Please consult the `Diátaxis `_ guide for more detail. +Links +===== + +Links are a powerful tool for helping people navigate documentation and find +more information, but links can be over-used. Links should be used only if +they help the reader. + +Generally, a link should be provided for the first use of a term in a unit, +such as a section or paragraph. This is not a hard and fast rule. Sometimes +the second mention is more appropriate for a link. Some units are long enough +to have a few repeated links. Use judgement to decide when a link will help +the reader. + +Do not use a link when the link would point to the current unit. It's natural +to use the name of a function in the documentation for the function, but a link +on that function name that simply reloads the section the user is already +reading is useless and distracting. + +Do not use links in section headers. They distract from the title of the +section. The term will be mentioned in the paragraph text and can be linked +from there. + +Sphinx provides ways to automatically add links to references, and a way to +suppress the link. Using roles like ``:func:`map``` will link to the +documentation for ``map``. You can suppress the link while keeping the +semantic presentation of the function name by adding an exclamation point +prefix: ``:func:`!map```. See :ref:`roles` for more details. + Affirmative tone ================ From 2308db4e59938df76b2b0657386e86d22e1c3174 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 28 Mar 2024 08:25:34 +0200 Subject: [PATCH 292/538] Update link to new home at python/blurb (#1302) --- index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.rst b/index.rst index 5dddafd0f..fb901ddbd 100644 --- a/index.rst +++ b/index.rst @@ -126,7 +126,7 @@ instructions please see the :ref:`setup guide `. news entry can be created by using `blurb-it `_, or the `blurb `_ tool and its ``blurb add`` command. Please read more about ``blurb`` in its - `repository `_. + `repository `_. .. note:: From 9f77765838066dfecadd1c9f58a3464c4957d7dd Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 2 Apr 2024 09:15:41 +0300 Subject: [PATCH 293/538] Document style on naming env vars (#1300) Co-authored-by: Ezio Melotti --- developer-workflow/stdlib.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/developer-workflow/stdlib.rst b/developer-workflow/stdlib.rst index c9e1ab429..ae0f7208e 100644 --- a/developer-workflow/stdlib.rst +++ b/developer-workflow/stdlib.rst @@ -52,6 +52,7 @@ useful. 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 @@ -137,3 +138,17 @@ once the authors of the module sign :ref:`contributor agreements `. .. _issue tracker: https://github.com/python/cpython/issues + +Adding a new environment variable +--------------------------------- + +Names of environment variables should be uppercase and, from Python 3.13 +onwards, use underscores for readability and accessibility. + +For example, use ``PYTHON_CPU_COUNT`` instead of ``PYTHONCPUCOUNT``. + +See also: + +* :ref:`python:using-on-envvars` +* `"Change environment variable style" Discourse discussion + `__ From 590c9db2f8444dd11406825d4396f649b4dc2c8b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:28:41 +0300 Subject: [PATCH 294/538] Python 3.11 is now security-only (GH-1303) --- 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 8acf9b4c1..27644ef14 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -18,7 +18,7 @@ "3.11": { "branch": "3.11", "pep": 664, - "status": "bugfix", + "status": "security", "first_release": "2022-10-24", "end_of_life": "2027-10", "release_manager": "Pablo Galindo Salgado" From 8c95d16654ab66f92008c4b6e1b2841bc8bd9a49 Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Thu, 11 Apr 2024 13:37:15 +0200 Subject: [PATCH 295/538] Add pre-commit setup to the Setup and Building chapter (#1306) Co-authored-by: Ezio Melotti Co-authored-by: Erlend E. Aasland Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- getting-started/pull-request-lifecycle.rst | 7 ++++++- getting-started/setup-building.rst | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 1c16f1592..225b352be 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -108,7 +108,12 @@ You should have already :ref:`set up your system `, (Learn more about :ref:`good-commits`) -* Then push your work to your GitHub fork:: +* If your code isn't linted correctly, :ref:`pre-commit ` + will block the commit with an error message, for example:: + + Doc/library/stdtypes.rst:5718: No newline at end of file. (missing-final-newline) + +* Once all linting errors have been fixed, you can push your work to your GitHub fork:: git push origin diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 30b756708..0ffdb02b8 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -130,6 +130,18 @@ affected files as described below.) Patches for the documentation can be made from the same repository; see :ref:`documenting`. +.. _install-pre-commit: + +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 install --allow-missing-config + pre-commit installed at .git/hooks/pre-commit + +Now pre-commit will run automatically on ``git commit``. .. _compiling: From a8e1743d3f05fe21f627914f4247100a406379fe Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 15 Apr 2024 23:47:16 +0300 Subject: [PATCH 296/538] Document custom CVE, CWE and PyPI roles (#1307) --- conf.py | 1 + core-developers/committing.rst | 3 +-- developer-workflow/communication-channels.rst | 6 ++---- documentation/markup.rst | 9 ++++++--- documentation/translating.rst | 15 ++++++--------- getting-started/pull-request-lifecycle.rst | 2 +- index.rst | 2 +- 7 files changed, 18 insertions(+), 20 deletions(-) diff --git a/conf.py b/conf.py index 825cfb5b5..df5805f84 100644 --- a/conf.py +++ b/conf.py @@ -178,6 +178,7 @@ # https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html extlinks = { "github": ("https://github.com/%s/", "%s"), + "pypi": ("https://pypi.org/project/%s/", "%s"), } # sphinxext-opengraph config diff --git a/core-developers/committing.rst b/core-developers/committing.rst index 3b2a10302..3206d991a 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -125,8 +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 `_, -or the `blurb `_ tool and its ``blurb add`` -command. +or the :pypi:`blurb` tool and its ``blurb add`` command. If you are unable to use the tool, then you can create the ``NEWS`` entry file manually. The ``Misc/NEWS.d`` directory contains a sub-directory named diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 12e14889e..0f7970fad 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -249,11 +249,11 @@ order to make open source pleasant for everyone involved. Additional repositories ======================= -`Python Core Workflow`_ hosts the codebase for tools such as `blurb`_. +`Python Core Workflow`_ hosts the codebase for tools such as :pypi:`blurb`. Other core workflow tools are: -* `cherry_picker`_ (`PyPI`_) +* `cherry_picker`_ (:pypi:`PyPI `) * `bedevere`_ * `blurb_it`_ * `miss-islington`_ @@ -264,9 +264,7 @@ Python `Performance Benchmark`_ project is intended to be an authoritative source of benchmarks for all Python implementations. .. _Python Core Workflow: https://github.com/python/core-workflow -.. _blurb: https://pypi.org/project/blurb .. _cherry_picker: https://github.com/python/cherry-picker -.. _PyPI: https://pypi.org/project/cherry_picker/ .. _bedevere: https://github.com/python/bedevere .. _blurb_it: https://github.com/python/blurb_it .. _miss-islington: https://github.com/python/miss-islington diff --git a/documentation/markup.rst b/documentation/markup.rst index 830493a31..2dec9d06b 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -732,9 +732,12 @@ where simpler markup should be used: In addition, the CPython documentation defines a few custom roles: -* ``:gh:`ID```: creates a link to a GitHub issue. -* ``:issue:`ID```: creates a link to a bugs.python.com issue. -* ``:source:`PATH```: creates a link to a source file on GitHub. +* ``:cve:`YYYY-NNNNN```: link to a Common Vulnerabilities and Exposures entry. +* ``:cwe:`NNN```: link to a Common Weakness Enumeration entry. +* ``:gh:`ID```: link to a GitHub issue. +* ``:issue:`ID```: link to a bugs.python.com issue. +* ``:pypi:`NAME```: link to a project on PyPI. +* ``:source:`PATH```: link to a source file on GitHub. There are some additional facilities that make cross-referencing roles more versatile: diff --git a/documentation/translating.rst b/documentation/translating.rst index 2d8cb86d4..8abb69fbb 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -209,8 +209,7 @@ Which version of the Python documentation should be translated? --------------------------------------------------------------- Consensus is to work on current stable. You can then propagate your -translation from one branch to another using `pomerge -`__. +translation from one branch to another using :pypi:`pomerge`. Are there some tools to help in managing the repo? @@ -218,14 +217,12 @@ Are there some tools to help in managing the repo? Here's what we're using: -- `pomerge `__ to propagate translations - from one file to others. -- `pospell `__ to check for typos in ``.po`` files. -- `powrap `__ to rewrap the ``.po`` files +- :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. -- `potodo `__ to list what needs to be translated. -- `sphinx-lint `__ to validate reST syntax in - translation files. +- :pypi:`potodo` to list what needs to be translated. +- :pypi:`sphinx-lint` to validate reST syntax in translation files. How is a coordinator elected? diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 225b352be..2381211ab 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -266,7 +266,7 @@ The automated patch checklist runs through: * Has the test suite been updated? * Has an entry under ``Misc/NEWS.d/next`` been added? (using `blurb-it `_, - or the `blurb `_ tool) + or the :pypi:`blurb` tool) * Has ``Misc/ACKS`` been updated? * Has ``configure`` been regenerated, if necessary? * Has ``pyconfig.h.in`` been regenerated, if necessary? diff --git a/index.rst b/index.rst index fb901ddbd..8b060fb87 100644 --- a/index.rst +++ b/index.rst @@ -124,7 +124,7 @@ instructions please see the :ref:`setup guide `. 8. Add a News entry into the ``Misc/NEWS.d`` directory as individual file. The news entry can be created by using `blurb-it `_, - or the `blurb `_ tool and its ``blurb add`` + or the :pypi:`blurb` tool and its ``blurb add`` command. Please read more about ``blurb`` in its `repository `_. From 84cb6f01d67fcaedf383c715bc05a665bd3c1a27 Mon Sep 17 00:00:00 2001 From: Paul Bae <165033012+kokoavailable@users.noreply.github.com> Date: Tue, 23 Apr 2024 06:13:02 +0900 Subject: [PATCH 297/538] Document attr and attribute (#1311) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- documentation/markup.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/documentation/markup.rst b/documentation/markup.rst index 2dec9d06b..b72e1a952 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -24,6 +24,8 @@ variables/literals/code ````foo````, ````42````, ````len(s) - 1```` :ref:`inline True/False/None ````True````, ````False````, ````None```` :ref:`inline-markup` functions definitions ``.. function:: print(*args)`` :ref:`directives` functions references ``:func:`print``` :ref:`roles` +attribute definitions ``.. attribute: `attr-name``` :ref:`information-units` +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` @@ -565,6 +567,10 @@ The directives are: Description of the attribute. + Refer to an attribute using the ``:attr:`` role:: + + Use the :attr:`ham` attribute to spam the eggs. + If is also possible to document an attribute outside of a class directive, for example if the documentation for different attributes and methods is split in multiple sections. The class name should then be included From 884f89d61dff1d1648558723be3ac425c8fa2ded Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 00:59:51 -0600 Subject: [PATCH 298/538] Update sphinx requirement from ~=7.2.6 to ~=7.3.7 (#1314) 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 219122e4c..7b98f183d 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~=7.2.6 +Sphinx~=7.3.7 From b9eda580425de52d43cdba1fc52a7553af3cc0e2 Mon Sep 17 00:00:00 2001 From: Safwan Samsudeen <62411302+safwansamsudeen@users.noreply.github.com> Date: Thu, 2 May 2024 19:46:08 +0530 Subject: [PATCH 299/538] Clean up translations list (#1119) Co-authored-by: Ezio Melotti Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- conf.py | 3 +- documentation/translating.rst | 222 ++++++++++++++-------------------- 2 files changed, 90 insertions(+), 135 deletions(-) diff --git a/conf.py b/conf.py index df5805f84..6de594b23 100644 --- a/conf.py +++ b/conf.py @@ -177,7 +177,8 @@ # mapping unique short aliases to a base URL and a prefix. # https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html extlinks = { - "github": ("https://github.com/%s/", "%s"), + "github": ("https://github.com/%s", "%s"), + "github-user": ("https://github.com/%s", "@%s"), "pypi": ("https://pypi.org/project/%s/", "%s"), } diff --git a/documentation/translating.rst b/documentation/translating.rst index 8abb69fbb..9d21bca0e 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -12,140 +12,94 @@ They are built by `docsbuild-scripts docs.python.org. There are several documentation translations already in production; others are works in progress. -+-----------------+-------------------------------+----------------------------+ -| Language | Contact | Links | -+=================+===============================+============================+ -| Arabic (ar) | `Abdur-Rahmaan Janhangeer | `GitHub `_ | -| | `_ | | -+-----------------+-------------------------------+----------------------------+ -| Bengali as | `Kushal Das `_ | `GitHub `_ | -| spoken in | | | -| India (bn_IN) | | | -+-----------------+-------------------------------+----------------------------+ -| French (fr) | `Julien Palard (@JulienPalard)| `GitHub `_ | -| | `_ | | -+-----------------+-------------------------------+----------------------------+ -| Greek (gr) | `Lysandros Nikolaou | `GitHub `_ | -| | (@lysnikolaou) | | -| | `_, | | -| | `Fanis Petkos (@thepetk) | | -| | `_ | | -+-----------------+-------------------------------+----------------------------+ -| Hindi as spoken | | `GitHub `_ | -| in India (hi_IN)| | | -+-----------------+-------------------------------+----------------------------+ -| Hungarian (hu) | `Tamás Bajusz (@gbtami) | `GitHub `_ | -| | `_ | `Mailing List `_ | -+-----------------+-------------------------------+----------------------------+ -| Indonesian (id) | `Oon Arfiandwi `_ | `GitHub `_ | -+-----------------+-------------------------------+----------------------------+ -| Italian (it) | | `mail `_ | -+-----------------+-------------------------------+----------------------------+ -| Japanese (ja) | `Kinebuchi Tomohiko | `GitHub `_ | -| | (@cocoatomo) | `Doc `_ | -| | `_, | | -| | `Atsuo Ishimoto | | -| | (@atsuoishimoto) | | -| | `_ | | -+-----------------+-------------------------------+----------------------------+ -| Korean (ko) | | `GitHub `_ | -| | | `Doc `_ | -+-----------------+-------------------------------+----------------------------+ -| Marathi (mr) | `Sanket Garade | `GitHub `_ | -| | `_ | | -+-----------------+-------------------------------+----------------------------+ -| Lithuanian (lt) | | `mail `_ | -+-----------------+-------------------------------+----------------------------+ -| Persian (fa) | `Komeil Parseh (@mmdbalkhi) | `GitHub `_ | -| | `_ | | -+-----------------+-------------------------------+----------------------------+ -| Polish (pl) | `Maciej Olko (@m-aciek) | `GitHub `_ | -| | `_ | `Translations `_ | -| | | `Doc `_ | -| | | `mail `_ | -+-----------------+-------------------------------+----------------------------+ -| Portuguese (pt) | Gustavo Toffo | | -+-----------------+-------------------------------+----------------------------+ -| Portuguese | Marco Rougeth | `GitHub `_ | -| as spoken | | `Wiki `_ | -| in Brasil | | `Telegram `_ | -| (pt-br) | | `article `_| -+-----------------+-------------------------------+----------------------------+ -| Russian (ru) | | `GitHub `_ | -| | | `mail `_ | -+-----------------+-------------------------------+----------------------------+ -| Simplified | `Shengjing Zhu `_, | `Transifex `_ | -| Chinese | `Du, Meng `_ | `GitHub `_ | -| (zh-cn) | | `Doc `_ | -+-----------------+-------------------------------+----------------------------+ -| Spanish (es) | Raúl Cumplido | `GitHub `_ | -+-----------------+-------------------------------+----------------------------+ -| Traditional | `王威翔 Matt Wang | `GitHub `_ | -| Chinese | `_, | `Doc `_ | -| (zh-tw) | Josix Wang | | -+-----------------+-------------------------------+----------------------------+ -| Turkish (tr) | `Ege Akman (@egeakman) | `GitHub `_ | -| | `_ | `RTD `_ | -| | | `Doc `_ | -+-----------------+-------------------------------+----------------------------+ -| Ukrainian (uk) | `Dmytro Kazanzhy (@kazanzhy) | `GitHub `_ | -| | `_ | `Translations `_ | -+-----------------+-------------------------------+----------------------------+ - -.. _article_pt_br: https://rgth.co/blog/python-ptbr-cenario-atual/ -.. _gh_cocoatomo: https://github.com/cocoatomo -.. _gh_atsuoishimoto: https://github.com/atsuoishimoto -.. _gh_gbtami: https://github.com/gbtami -.. _gh_kushal: https://github.com/Kushal997-das -.. _gh_maciek: https://github.com/m-aciek -.. _gh_mdk: https://github.com/JulienPalard -.. _gh_mmdbalkhi: https://github.com/mmdbalkhi -.. _gh_oonid: https://github.com/oonid -.. _gh_osdotsystem: https://github.com/Abdur-rahmaanJ -.. _gh_zhsj: https://github.com/zhsj -.. _gh_dumeng: https://github.com/dumeng -.. _gh_mattwang44: https://github.com/mattwang44 -.. _gh_egeakman: https://github.com/egeakman -.. _gh_lysnikolaou: https://github.com/lysnikolaou -.. _gh_thepetk: https://github.com/thepetk -.. _email_garade: mailto:garade@pm.me -.. _email_kazanzhy: mailto:dkazanzhy@gmail.com -.. _chat_pt_br: https://t.me/pybr_i18n -.. _doc_ja: https://docs.python.org/ja/ -.. _doc_ko: https://docs.python.org/ko/ -.. _doc_pl: https://docs.python.org/pl/ -.. _doc_tr: https://docs.python.org/tr/ -.. _doc_zh_cn: https://docs.python.org/zh-cn/ -.. _doc_zh_tw: https://docs.python.org/zh-tw/ -.. _github_ar: https://github.com/Abdur-rahmaanJ/python-docs-ar -.. _github_bn_in: https://github.com/python/python-docs-bn-in -.. _github_es: https://github.com/python/python-docs-es -.. _github_fa: https://github.com/mmdbalkhi/python-docs-fa -.. _github_fr: https://github.com/python/python-docs-fr -.. _github_hi_in: https://github.com/CuriousLearner/python-docs-hi-in -.. _github_hu: https://github.com/python/python-docs-hu -.. _github_id: https://github.com/python/python-docs-id -.. _github_ja: https://github.com/python/python-docs-ja -.. _github_ko: https://github.com/python/python-docs-ko -.. _github_mr: https://github.com/sanketgarade/python-doc-mr -.. _github_pl: https://github.com/python/python-docs-pl -.. _github_pt_br: https://github.com/python/python-docs-pt-br -.. _github_tr: https://github.com/python/python-docs-tr -.. _github_uk: https://github.com/python/python-docs-uk -.. _github_zh_cn: https://github.com/python/python-docs-zh-cn -.. _github_zh_tw: https://github.com/python/python-docs-zh-tw -.. _github_ru: https://github.com/MLGRussianXP/python-docs-ru -.. _github_gr: https://github.com/pygreece/python-docs-gr -.. _list_hu: https://mail.python.org/pipermail/python-hu -.. _mail_it: https://mail.python.org/pipermail/doc-sig/2019-April/004114.html -.. _mail_lt: https://mail.python.org/pipermail/doc-sig/2019-July/004138.html -.. _mail_pl: https://mail.python.org/pipermail/doc-sig/2019-April/004106.html -.. _mail_ru: https://mail.python.org/pipermail/doc-sig/2019-May/004131.html -.. _rtd_tr: https://python-docs-tr.readthedocs.io/ -.. _tx_pl: https://explore.transifex.com/python-doc/python-newest/ -.. _tx_uk: https://explore.transifex.com/python-doc/python-newest/ -.. _tx_zh_cn: https://explore.transifex.com/python-doc/python-newest/ -.. _wiki_pt_br: https://python.org.br/traducao/ +.. list-table:: + :header-rows: 1 + + * - Language + - Contact + - Links + * - Arabic (ar) + - Abdur-Rahmaan Janhangeer (:github-user:`Abdur-rahmaanJ`) + - :github:`GitHub ` + * - Bengali as spoken in India (bn_IN) + - Kushal Das (:github-user:`Kushal997-das`) + - :github:`GitHub ` + * - `French (fr) `__ + - Julien Palard (:github-user:`JulienPalard`) + - :github:`GitHub ` + * - Greek (gr) + - Lysandros Nikolaou (:github-user:`lysnikolaou`), + Fanis Petkos (:github-user:`thepetk`) + - :github:`GitHub ` + * - Hindi as spoken in India (hi_IN) + - Sanyam Khurana (:github-user:`CuriousLearner`) + - :github:`GitHub ` + * - Hungarian (hu) + - Tamás Bajusz (:github-user:`gbtami`) + - :github:`GitHub `, + `mailing list `__ + * - `Indonesian (id) `__ + - Oon Arfiandwi (:github-user:`oonid`) + - :github:`GitHub ` + * - Italian (it) + - Alessandro Cucci (`email `__) + - `Original mail `__ + * - `Japanese (ja) `__ + - Kinebuchi Tomohiko (:github-user:`cocoatomo`), + Atsuo Ishimoto (:github-user:`atsuoishimoto`) + - :github:`GitHub ` + * - `Korean (ko) `__ + - 오동권 (:github-user:`flowdas`) + - :github:`GitHub ` + * - Marathi (mr) + - Sanket Garade (:github-user:`sanketgarade`, `email `__) + - :github:`GitHub ` + * - Lithuanian (lt) + - Albertas Gimbutas (:github-user:`albertas`, `email `__) + - `Original mail `__ + * - Persian (fa) + - Komeil Parseh (:github-user:`mmdbalkhi`) + - :github:`GitHub ` + * - `Polish (pl) `__ + - Maciej Olko (:github-user:`m-aciek`) + - :github:`GitHub `, + `Transifex `_, + `original mail `__ + * - Portuguese (pt) + - Gustavo Toffo + - + * - `Portuguese as spoken in Brasil (pt-br) `__ + - Marco Rougeth + - :github:`GitHub `, + `wiki `__, + `Telegram `__, + `article `__ + * - Russian (ru) + - Daniil Kolesnikov (:github-user:`MLGRussianXP`, `email `__) + - :github:`GitHub `, + `mail `__ + * - `Simplified Chinese (zh-cn) `__ + - 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 + - :github:`GitHub ` + * - `Turkish (tr) `__ + - Ege Akman (:github-user:`egeakman`) + - :github:`GitHub `, + `RTD `__ + * - `Ukrainian (uk) `__ + - Dmytro Kazanzhy (:github-user:`kazanzhy`, `email `__) + - :github:`GitHub `, + `Transifex `_ + +.. _tx: https://explore.transifex.com/python-doc/python-newest/ Starting a new translation ========================== From 5c6a0c1c878af5b58bf95a2f6786a1c510b19c31 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 3 May 2024 08:33:30 +0200 Subject: [PATCH 300/538] Update deps and build instructions wrt. libmpdecimal (#1313) --- getting-started/setup-building.rst | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 0ffdb02b8..b0961813e 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -661,7 +661,7 @@ on Linux, macOS and iOS. $ 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 + lzma lzma-dev tk-dev uuid-dev zlib1g-dev libmpdec-dev .. tab:: macOS @@ -692,9 +692,17 @@ on Linux, macOS and iOS. For example, with **Homebrew**, install the dependencies:: - $ brew install pkg-config openssl@3.0 xz gdbm tcl-tk + $ brew install pkg-config openssl@3.0 xz gdbm tcl-tk mpdecimal - Then, for Python 3.11 and newer, run ``configure``:: + Then, for Python 3.13 and newer, run ``configure``:: + + $ 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.0)" + + For Python 3.11 and 3.12:: $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ @@ -716,9 +724,16 @@ on Linux, macOS and iOS. Alternatively, with **MacPorts**:: - $ sudo port install pkgconfig openssl xz gdbm tcl tk +quartz + $ sudo port install pkgconfig openssl xz gdbm tcl tk +quartz mpdecimal + + Then, for Python 3.13 and newer, run ``configure``:: + + $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ + GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ + ./configure --with-pydebug \ + --with-system-libmpdec - Then, for Python 3.11 and newer, run ``configure``:: + Or, for Python 3.11 and 3.12, run ``configure``:: $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ From 0c56002c0b40358c25a397d8a3dce2a814824859 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 8 May 2024 21:28:15 +0300 Subject: [PATCH 301/538] Python 3.14 is now `main` (#1319) --- include/release-cycle.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/release-cycle.json b/include/release-cycle.json index 27644ef14..fdb574b11 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -1,8 +1,16 @@ { - "3.13": { + "3.14": { "branch": "main", - "pep": 719, + "pep": 745, "status": "feature", + "first_release": "2025-10-01", + "end_of_life": "2030-10", + "release_manager": "Hugo van Kemenade" + }, + "3.13": { + "branch": "3.13", + "pep": 719, + "status": "prerelease", "first_release": "2024-10-01", "end_of_life": "2029-10", "release_manager": "Thomas Wouters" From 84b881329155e1bcf94be50d90a7dc3c60462215 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 9 May 2024 16:59:10 +0300 Subject: [PATCH 302/538] macOS: Add tabs for Homebrew/MacPorts and for 3.13+/3.11-3.12/3.8-3.10 (#1317) Co-authored-by: Erlend E. Aasland Co-authored-by: Ezio Melotti --- getting-started/setup-building.rst | 76 +++++++++++++++++------------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index b0961813e..e8d7c73ea 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -690,54 +690,64 @@ on Linux, macOS and iOS. manager, like Homebrew_ or MacPorts_, and then add the appropriate paths for the header and library files to your ``configure`` command. - For example, with **Homebrew**, install the dependencies:: + .. tab:: Homebrew - $ brew install pkg-config openssl@3.0 xz gdbm tcl-tk mpdecimal + For **Homebrew**, install dependencies using ``brew``:: - Then, for Python 3.13 and newer, run ``configure``:: + $ brew install pkg-config openssl@3.0 xz gdbm tcl-tk mpdecimal - $ 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.0)" + .. tab:: Python 3.13+ - For Python 3.11 and 3.12:: + For Python 3.13 and newer:: - $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ - GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ - ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@3.0)" + $ 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.0)" - Or, for Python 3.8 through 3.10:: + .. tab:: Python 3.11-3.12 - $ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ - LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ - ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@3.0)" \ - --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ - --with-tcltk-includes="$(pkg-config --cflags tcl tk)" + For Python 3.11 and 3.12:: - And finally, run ``make``:: + $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ + GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ + ./configure --with-pydebug \ + --with-openssl="$(brew --prefix openssl@3.0)" - $ make -s -j2 + .. tab:: Python 3.8-3.10 + + For Python 3.8, 3.9, and 3.10:: + + $ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ + LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ + ./configure --with-pydebug \ + --with-openssl="$(brew --prefix openssl@3.0)" \ + --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ + --with-tcltk-includes="$(pkg-config --cflags tcl tk)" + + .. tab:: MacPorts + + For **MacPorts**, install dependencies using ``port``:: + + $ sudo port install pkgconfig openssl xz gdbm tcl tk +quartz mpdecimal - Alternatively, with **MacPorts**:: + .. tab:: Python 3.13+ - $ sudo port install pkgconfig openssl xz gdbm tcl tk +quartz mpdecimal + For Python 3.13 and newer:: - Then, for Python 3.13 and newer, run ``configure``:: + $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ + GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ + ./configure --with-pydebug \ + --with-system-libmpdec - $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ - GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ - ./configure --with-pydebug \ - --with-system-libmpdec + .. tab:: Python 3.11-3.12 - Or, for Python 3.11 and 3.12, run ``configure``:: + For Python 3.11 and 3.12:: - $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ - GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ - ./configure --with-pydebug + $ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \ + GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \ + ./configure --with-pydebug And finally, run ``make``:: From f7dd3b08ab766fe71a69003f917f7110b56698cb Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 10 May 2024 13:24:53 +0300 Subject: [PATCH 303/538] Linux: Remove outdated `yum` instructions (#1318) Co-authored-by: Erlend E. Aasland Co-authored-by: Ezio Melotti Co-authored-by: Petr Viktorin --- getting-started/setup-building.rst | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index e8d7c73ea..f653164d3 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -619,17 +619,13 @@ on Linux, macOS and iOS. distribution, but the appropriate commands for some popular distributions are below. - On **Fedora**, **Red Hat Enterprise Linux** and other ``yum`` based systems:: - - $ sudo yum install yum-utils - $ sudo yum-builddep python3 - - On **Fedora** and other ``DNF`` based systems:: + On **Fedora**, **RHEL**, **CentOS** and other ``dnf``-based systems:: $ sudo dnf install dnf-plugins-core # install this to use 'dnf builddep' $ sudo dnf builddep python3 - On **Debian**, **Ubuntu**, and other ``apt`` based systems, try to get the + + On **Debian**, **Ubuntu**, and other ``apt``-based systems, try to get the dependencies for the Python you're working on by using the ``apt`` command. First, make sure you have enabled the source packages in the sources list. @@ -637,11 +633,11 @@ on Linux, macOS and iOS. URL, distribution name and component name, to ``/etc/apt/sources.list``. Take Ubuntu 22.04 LTS (Jammy Jellyfish) for example:: - deb-src http://archive.ubuntu.com/ubuntu/ jammy main + $ deb-src http://archive.ubuntu.com/ubuntu/ jammy main Alternatively, uncomment lines with ``deb-src`` using an editor, e.g.:: - sudo nano /etc/apt/sources.list + $ sudo nano /etc/apt/sources.list For other distributions, like Debian, change the URL and names to correspond with the specific distribution. From 78154694dc5ed109dd8acb605f04bcede8a0c150 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Tue, 14 May 2024 10:59:22 -0500 Subject: [PATCH 304/538] Remove office hours section (#1324) --- getting-started/getting-help.rst | 19 ------------------- index.rst | 4 ++-- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/getting-started/getting-help.rst b/getting-started/getting-help.rst index 4e5a02c39..4e993a1e9 100644 --- a/getting-started/getting-help.rst +++ b/getting-started/getting-help.rst @@ -86,25 +86,6 @@ welcomed and encouraged to contribute. .. _Python Mentors: https://www.python.org/dev/core-mentorship/ -.. _office hour: - -Core developers office hours ----------------------------- - -Several core developers have set aside time to host mentorship office hours. -During the office hour, core developers are available to help contributors with -our process, answer questions, and help lower the barrier of contributing and -becoming Python core developers. - -The PSF's code of conduct applies for interactions with core developers -during office hours. - -+------------------+-------------------------------+------------------------------------------------+ -| Core Developer | Schedule | Details | -+==================+===============================+================================================+ -| Zachary Ware | See details link | Schedule at https://calendly.com/zware | -+------------------+-------------------------------+------------------------------------------------+ - File a bug ---------- diff --git a/index.rst b/index.rst index 8b060fb87..8f60b8f9f 100644 --- a/index.rst +++ b/index.rst @@ -174,8 +174,8 @@ Contributors Documentarians Triagers Core Develo :ref:`pullrequest` :ref:`style-guide` :ref:`helptriage` :ref:`committing` :ref:`runtests` :ref:`rst-primer` :ref:`experts` :ref:`devcycle` :ref:`fixingissues` :ref:`translating` :ref:`labels` :ref:`motivations` -:ref:`communication` :ref:`devguide` :ref:`gh-faq` :ref:`office hour` -:ref:`gitbootcamp` :ref:`triage-team` :ref:`experts` +:ref:`communication` :ref:`devguide` :ref:`gh-faq` :ref:`experts` +:ref:`gitbootcamp` :ref:`triage-team` :ref:`devcycle` ======================== =================== ======================= ======================= From 538c4e8f6922da8df3e132c907db9b453658cf22 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 25 May 2024 17:17:56 +0300 Subject: [PATCH 305/538] makefile/RTD: Use uv if installed (#1320) --- .readthedocs.yml | 3 +++ Makefile | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 5d8884584..26e5be967 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -14,5 +14,8 @@ build: python: "3" commands: + - asdf plugin add uv + - asdf install uv latest + - asdf global uv latest - make dirhtml BUILDDIR=_readthedocs - mv _readthedocs/dirhtml _readthedocs/html diff --git a/Makefile b/Makefile index 76f5b9df5..985e46e82 100644 --- a/Makefile +++ b/Makefile @@ -70,9 +70,14 @@ venv: ensure-venv: @if [ ! -d $(VENVDIR) ] ; then \ echo "Creating venv in $(VENVDIR)"; \ - $(PYTHON) -m venv $(VENVDIR); \ - $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \ - $(VENVDIR)/bin/python3 -m pip install -r requirements.txt; \ + if uv --version > /dev/null; then \ + uv venv $(VENVDIR); \ + VIRTUAL_ENV=$(VENVDIR) uv pip install -r requirements.txt; \ + else \ + $(PYTHON) -m venv $(VENVDIR); \ + $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \ + $(VENVDIR)/bin/python3 -m pip install -r requirements.txt; \ + fi; \ echo "The venv has been created in the $(VENVDIR) directory"; \ fi @@ -175,7 +180,11 @@ check: ensure-venv .PHONY: lint lint: venv - $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit + if uv --version > /dev/null; then \ + $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || VIRTUAL_ENV=$(VENVDIR) uv pip install pre-commit; \ + else \ + $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit; \ + fi; $(VENVDIR)/bin/python3 -m pre_commit run --all-files .PHONY: serve From e880e36aa40f8266eb325b8f13298ce853e088e9 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 27 May 2024 17:55:05 +0300 Subject: [PATCH 306/538] Define port for htmllive to avoid collisions (#1327) Co-authored-by: Ezio Melotti --- Makefile | 16 +++++++++------- make.bat | 34 +++++++++++++++++----------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 985e46e82..d005d01bb 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ PYTHON = python3 VENVDIR = ./venv SPHINXBUILD = $(VENVDIR)/bin/sphinx-build -SPHINXOPTS = -W --keep-going +SPHINXOPTS = --fail-on-warning --keep-going BUILDDIR = _build BUILDER = html JOBS = auto @@ -13,11 +13,11 @@ PAPER = SPHINXLINT = $(VENVDIR)/bin/sphinx-lint # Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -b $(BUILDER) \ - -d $(BUILDDIR)/doctrees \ - -j $(JOBS) \ +PAPEROPT_a4 = --define latex_paper_size=a4 +PAPEROPT_letter = --define latex_paper_size=letter +ALLSPHINXOPTS = --builder $(BUILDER) \ + --doctree-dir $(BUILDDIR)/doctrees \ + --jobs $(JOBS) \ $(PAPEROPT_$(PAPER)) \ $(SPHINXOPTS) \ . $(BUILDDIR)/$(BUILDER) @@ -170,7 +170,9 @@ htmlview: html .PHONY: htmllive htmllive: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild -htmllive: SPHINXOPTS = --re-ignore="/\.idea/|/venv/" --open-browser --delay 0 +# Arbitrarily selected ephemeral port between 49152–65535 +# to avoid conflicts with other processes: +htmllive: SPHINXOPTS = --re-ignore="/\.idea/|/venv/" --open-browser --delay 0 --port 55301 htmllive: html .PHONY: check diff --git a/make.bat b/make.bat index 432b7f361..64661e8d2 100644 --- a/make.bat +++ b/make.bat @@ -22,8 +22,8 @@ if not defined SPHINXLINT ( ) set BUILDDIR=_build -set SPHINXOPTS=-W --keep-going -n -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set SPHINXOPTS=-W --keep-going --nitpicky +set ALLSPHINXOPTS=--doctree-dir %BUILDDIR%/doctrees %SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% ) @@ -76,7 +76,7 @@ if not defined SPHINXBUILD ( ) if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + %SPHINXBUILD% --builder html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. @@ -95,7 +95,7 @@ if "%1" == "htmlview" ( ) if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + %SPHINXBUILD% --builder dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. @@ -103,7 +103,7 @@ if "%1" == "dirhtml" ( ) if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + %SPHINXBUILD% --builder singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. @@ -111,7 +111,7 @@ if "%1" == "singlehtml" ( ) if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + %SPHINXBUILD% --builder pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. @@ -119,7 +119,7 @@ if "%1" == "pickle" ( ) if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + %SPHINXBUILD% --builder json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. @@ -127,7 +127,7 @@ if "%1" == "json" ( ) if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + %SPHINXBUILD% --builder htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ @@ -136,7 +136,7 @@ if "%1" == "htmlhelp" ( ) if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + %SPHINXBUILD% --builder qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ @@ -148,7 +148,7 @@ if "%1" == "qthelp" ( ) if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + %SPHINXBUILD% --builder devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. @@ -156,7 +156,7 @@ if "%1" == "devhelp" ( ) if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + %SPHINXBUILD% --builder epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. @@ -164,7 +164,7 @@ if "%1" == "epub" ( ) if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + %SPHINXBUILD% --builder latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. @@ -172,7 +172,7 @@ if "%1" == "latex" ( ) if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + %SPHINXBUILD% --builder text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. @@ -180,7 +180,7 @@ if "%1" == "text" ( ) if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + %SPHINXBUILD% --builder man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. @@ -188,7 +188,7 @@ if "%1" == "man" ( ) if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + %SPHINXBUILD% --builder changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. @@ -196,7 +196,7 @@ if "%1" == "changes" ( ) if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + %SPHINXBUILD% --builder linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ @@ -205,7 +205,7 @@ or in %BUILDDIR%/linkcheck/output.txt. ) if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + %SPHINXBUILD% --builder doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ From c60c672e7a30bbd05c476f4db2ef5b20b7ffc621 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 29 May 2024 12:23:17 +0300 Subject: [PATCH 307/538] Prefer "feature release" (#1328) --- developer-workflow/c-api.rst | 6 +++--- getting-started/pull-request-lifecycle.rst | 2 +- triage/labels.rst | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index 8097354c3..f0620aca5 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -174,7 +174,7 @@ Unstable C API The unstable C API tier is meant for extensions that need tight integration with the interpreter, like debuggers and JIT compilers. -Users of this tier may need to change their code with every minor release. +Users of this tier may need to change their code with every feature release. In many ways, this tier is like the general C API: @@ -189,7 +189,7 @@ The differences are: - Names of functions structs, macros, etc. start with the ``PyUnstable_`` prefix. This defines what's in the unstable tier. -- The unstable API can change in minor versions, without any deprecation +- The unstable API can change in feature releases, without any deprecation period. - A stability note appears in the docs. This happens automatically, based on the name @@ -198,7 +198,7 @@ The differences are: Despite being “unstable”, there are rules to make sure third-party code can use this API reliably: -* Changes and removals can be done in minor releases +* Changes and removals can be done in feature releases (:samp:`3.{x}.0`, including Alphas and Betas for :samp:`3.{x}.0`). * Adding a new unstable API *for an existing feature* is allowed even after Beta feature freeze, up until the first Release Candidate. diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 2381211ab..0cf34766e 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -553,7 +553,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 major release of Python. It may also be backported to older +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 it is warranted. diff --git a/triage/labels.rst b/triage/labels.rst index 95719615b..783bb555d 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -95,7 +95,7 @@ Version labels These labels are used to indicate which versions of Python are affected. The available version labels (with the form :samp:`3.{N}`) are updated -whenever new major releases are created or retired. +whenever new feature releases are created or retired. See also :ref:`the branch status page ` for a list of active branches. From fbf3141a110aa2af666ea643b8946166a3568bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 30 May 2024 07:51:56 -0400 Subject: [PATCH 308/538] Add Russell Keith-Magee (#1329) --- core-developers/developers.csv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index d05354b4a..60b611480 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Russell Keith-Magee,freakboy3742,2024-05-30,, Sam Gross,colesbury,2024-02-06,, Nikita Sobolev,sobolevn,2024-02-06,, Adam Turner,AA-Turner,2023-10-10,, @@ -145,7 +146,7 @@ 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 From 22727e32e941719603699389127d5be2395e9fec Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Fri, 31 May 2024 08:38:52 +0800 Subject: [PATCH 309/538] Add experts for mobile platforms. (#1330) --- core-developers/experts.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index d79d5cf8d..10c7ec152 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -297,12 +297,14 @@ for “their” platform as a third-party project. Platform Maintainers =================== =========== AIX David.Edelsohn^ +Android mhsmith, encukou Cygwin jlt63^, stutzbach^ Emscripten hoodmane, pmp-p, rdb, rth, ryanking13 FreeBSD HP-UX +iOS freakboy3742, ned-deily Linux -macOS ronaldoussoren, ned-deily +macOS ronaldoussoren, ned-deily, freakboy3742 NetBSD1 OS2/EMX aimacintyre^ Solaris/OpenIndiana jcea From 7810baf64c7087f9c571c4ed34670121c672ef2e Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 31 May 2024 11:49:26 +0200 Subject: [PATCH 310/538] Remove myself as an Android expert (GH-1331) I'm not an expert; the first time I've installed the Android SDK was to review Android/README.md when support was being finalzed. (FWIW, I like to think that a beginner's point of view helped there.) As a PEP sponsor, I helped with the *process* side of getting the changes in. I'm happy to help with Android support, as with any other part of Python; it's not special to me, nor I to it. --- 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 10c7ec152..3964f29d3 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -297,7 +297,7 @@ for “their” platform as a third-party project. Platform Maintainers =================== =========== AIX David.Edelsohn^ -Android mhsmith, encukou +Android mhsmith Cygwin jlt63^, stutzbach^ Emscripten hoodmane, pmp-p, rdb, rth, ryanking13 FreeBSD From e9d25c788fa5c146126e62db7cf0cacf908b6d8a Mon Sep 17 00:00:00 2001 From: Alessandro Cucci Date: Sun, 2 Jun 2024 17:09:04 +0200 Subject: [PATCH 311/538] documentation/translating: Added github to Italian entry (#1333) * documentation/translating: Added github to Italian entry * Fix table markup in documentation/translating.rst * Fix indentation in documentation/translating.rst --------- Co-authored-by: Alessandro Cucci Co-authored-by: Ezio Melotti --- documentation/translating.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 9d21bca0e..12aea204e 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -43,7 +43,8 @@ in production; others are works in progress. - :github:`GitHub ` * - Italian (it) - Alessandro Cucci (`email `__) - - `Original mail `__ + - :github:`GitHub `, + `original mail `__ * - `Japanese (ja) `__ - Kinebuchi Tomohiko (:github-user:`cocoatomo`), Atsuo Ishimoto (:github-user:`atsuoishimoto`) From f1ad3191655da63f9b998ce87ce7f6f73b4aab20 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 4 Jun 2024 12:01:20 -0700 Subject: [PATCH 312/538] Updates to experts (#1332) Co-authored-by: Carl Meyer --- core-developers/experts.rst | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 3964f29d3..f61f1439c 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -55,15 +55,12 @@ Module Maintainers __future__ __main__ gvanrossum, ncoghlan _thread -_testbuffer abc -aifc bitdancer argparse array -ast benjaminp, pablogsal, isidentical +ast benjaminp, pablogsal, isidentical, JelleZijlstra asyncio 1st1, asvetlov, gvanrossum, graingert, kumaraditya303, willingc atexit -audioop serhiy-storchaka base64 bdb binascii @@ -71,9 +68,6 @@ bisect rhettinger* builtins bz2 calendar -cgi ethanfurman* -cgitb ethanfurman* -chunk cmath mdickinson cmd code @@ -90,7 +84,6 @@ contextvars copy avassalotti copyreg avassalotti cProfile -crypt jafo^* csv smontanaro (inactive) ctypes theller (inactive), abalkin, amauryfa, meadori curses Yhg1s @@ -137,14 +130,12 @@ ipaddress pmoody^ itertools rhettinger* json etrepum (inactive), ezio-melotti, rhettinger keyword -lib2to3 benjaminp libmpdec linecache locale malemburg logging vsajip lzma mailbox -mailcap marshal math mdickinson, rhettinger, stutzbach^ mimetypes @@ -164,7 +155,7 @@ os.path serhiy-storchaka ossaudiodev parser pablogsal pathlib barneygale* -pdb +pdb gaogaotiantian pickle avassalotti pickletools avassalotti pipes @@ -212,14 +203,12 @@ string stringprep struct mdickinson, meadori subprocess astrand^ (inactive), giampaolo, gpshead* -sunau symtable benjaminp sys sysconfig FFY00 syslog jafo^* tabnanny tim-one (inactive) tarfile gustaebel -telnetlib tempfile termios Yhg1s test ezio-melotti @@ -366,6 +355,7 @@ release management tarekziade, malemburg, benjaminp, warsaw, runtime lifecycle ericsnowcurrently, kumaraditya303, zooba str.format ericvsmith* subinterpreters ericsnowcurrently, kumaraditya303 +symbol table JelleZijlstra, carljm testing voidspace, ezio-melotti test coverage threads gpshead From 79987a6ac759df16394e54f283d04c444b1bde0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 6 Jun 2024 08:22:49 -0400 Subject: [PATCH 313/538] Add Michael Droetboom and Tian Gao (#1335) --- core-developers/developers.csv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 60b611480..a87f58df2 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,5 @@ +Michael Droetboom,mdboom,2024-06-06,, +Tian Gao,gaogaotiantian,2024-06-06,, Russell Keith-Magee,freakboy3742,2024-05-30,, Sam Gross,colesbury,2024-02-06,, Nikita Sobolev,sobolevn,2024-02-06,, From 1a57b84e50666c8466c61537ec9ceec7ba740166 Mon Sep 17 00:00:00 2001 From: rieck-srlabs <135810953+rieck-srlabs@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:37:19 +0200 Subject: [PATCH 314/538] Minor fixes to compiler internals doc (#1336) - Correct double negations - Fix reference to ADDOP_LOAD_CONST_NEW - Improve grammar --- internals/compiler.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internals/compiler.rst b/internals/compiler.rst index a4e8457c3..4ef79a0de 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -398,7 +398,7 @@ Emission of bytecode is handled by the following macros: add a specified opcode ``ADDOP_NOLINE(struct compiler *, int)`` like ``ADDOP`` without a line number; used for artificial opcodes without - no corresponding token in the source code + a corresponding token in the source code ``ADDOP_IN_SCOPE(struct compiler *, int)`` like ``ADDOP``, but also exits current scope; used for adding return value opcodes in lambdas and closures @@ -421,17 +421,17 @@ Emission of bytecode is handled by the following macros: add the ``LOAD_CONST`` opcode with the proper argument based on the position of the specified PyObject in the consts table. ``ADDOP_LOAD_CONST_NEW(struct compiler *, PyObject *)`` - just like ``ADDOP_LOAD_CONST_NEW``, but steals a reference to PyObject + just like ``ADDOP_LOAD_CONST``, but steals a reference to PyObject ``ADDOP_JUMP(struct compiler *, int, basicblock *)`` create a jump to a basic block ``ADDOP_JUMP_NOLINE(struct compiler *, int, basicblock *)`` like ``ADDOP_JUMP`` without a line number; used for artificial jumps - without no corresponding token in the source code. + without a corresponding token in the source code. ``ADDOP_JUMP_COMPARE(struct compiler *, cmpop_ty)`` depending on the second argument, add an ``ADDOP_I`` with either an ``IS_OP``, ``CONTAINS_OP``, or ``COMPARE_OP`` opcode. -Several helper functions that will emit bytecode and are named +Several helper functions that will emit bytecode are named :samp:`compiler_{xx}()` where *xx* is what the function helps with (``list``, ``boolop``, etc.). A rather useful one is ``compiler_nameop()``. This function looks up the scope of a variable and, based on the From aa942b0b6aaef6177e81ca9fe5d71e4f48645ed9 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:28:19 +0100 Subject: [PATCH 315/538] gh-119786: redirect compiler doc to new location (#1339) --- internals/compiler.rst | 596 +---------------------------------------- internals/parser.rst | 8 +- 2 files changed, 6 insertions(+), 598 deletions(-) diff --git a/internals/compiler.rst b/internals/compiler.rst index 4ef79a0de..5b43e1e6d 100644 --- a/internals/compiler.rst +++ b/internals/compiler.rst @@ -6,597 +6,5 @@ Compiler design .. highlight:: none -Abstract -======== - -In CPython, the compilation from source code to bytecode involves several steps: - -1. Tokenize the source code (:cpy-file:`Parser/lexer/` and :cpy-file:`Parser/tokenizer/`). -2. Parse the stream of tokens into an Abstract Syntax Tree - (:cpy-file:`Parser/parser.c`). -3. Transform AST into an instruction sequence (:cpy-file:`Python/compile.c`). -4. Construct a Control Flow Graph and apply optimizations to it (:cpy-file:`Python/flowgraph.c`). -5. Emit bytecode based on the Control Flow Graph (:cpy-file:`Python/assemble.c`). - -This document outlines how these steps of the process work. - -This document only describes parsing in enough depth to explain what is needed -for understanding compilation. This document provides a detailed, though not -exhaustive, view of the how the entire system works. You will most likely need -to read some source code to have an exact understanding of all details. - - -Parsing -======= - -As of Python 3.9, Python's parser is a PEG parser of a somewhat -unusual design. It is unusual in the sense that the parser's input is a stream -of tokens rather than a stream of characters which is more common with PEG -parsers. - -The grammar file for Python can be found in -:cpy-file:`Grammar/python.gram`. The definitions for literal tokens -(such as ``:``, numbers, etc.) can be found in :cpy-file:`Grammar/Tokens`. -Various C files, including :cpy-file:`Parser/parser.c` are generated from -these. - -.. seealso:: - - :ref:`parser` for a detailed description of the parser. - - :ref:`grammar` for a detailed description of the grammar. - - -Abstract syntax trees (AST) -=========================== - -.. _compiler-ast-trees: - -.. sidebar:: Green Tree Snakes - - See also `Green Tree Snakes - the missing Python AST docs - `_ by Thomas Kluyver. - -The abstract syntax tree (AST) is a high-level representation of the -program structure without the necessity of containing the source code; -it can be thought of as an abstract representation of the source code. The -specification of the AST nodes is specified using the Zephyr Abstract -Syntax Definition Language (ASDL) [Wang97]_. - -The definition of the AST nodes for Python is found in the file -:cpy-file:`Parser/Python.asdl`. - -Each AST node (representing statements, expressions, and several -specialized types, like list comprehensions and exception handlers) is -defined by the ASDL. Most definitions in the AST correspond to a -particular source construct, such as an 'if' statement or an attribute -lookup. The definition is independent of its realization in any -particular programming language. - -The following fragment of the Python ASDL construct demonstrates the -approach and syntax:: - - module Python - { - stmt = FunctionDef(identifier name, arguments args, stmt* body, - expr* decorators) - | Return(expr? value) | Yield(expr? value) - attributes (int lineno) - } - -The preceding example describes two different kinds of statements and an -expression: function definitions, return statements, and yield expressions. -All three kinds are considered of type ``stmt`` as shown by ``|`` separating -the various kinds. They all take arguments of various kinds and amounts. - -Modifiers on the argument type specify the number of values needed; ``?`` -means it is optional, ``*`` means 0 or more, while no modifier means only one -value for the argument and it is required. ``FunctionDef``, for instance, -takes an ``identifier`` for the *name*, ``arguments`` for *args*, zero or more -``stmt`` arguments for *body*, and zero or more ``expr`` arguments for -*decorators*. - -Do notice that something like 'arguments', which is a node type, is -represented as a single AST node and not as a sequence of nodes as with -stmt as one might expect. - -All three kinds also have an 'attributes' argument; this is shown by the -fact that 'attributes' lacks a '|' before it. - -The statement definitions above generate the following C structure type: - -.. code-block:: c - - typedef struct _stmt *stmt_ty; - - struct _stmt { - enum { FunctionDef_kind=1, Return_kind=2, Yield_kind=3 } kind; - union { - struct { - identifier name; - arguments_ty args; - asdl_seq *body; - } FunctionDef; - - struct { - expr_ty value; - } Return; - - struct { - expr_ty value; - } Yield; - } v; - int lineno; - } - -Also generated are a series of constructor functions that allocate (in -this case) a ``stmt_ty`` struct with the appropriate initialization. The -``kind`` field specifies which component of the union is initialized. The -``FunctionDef()`` constructor function sets 'kind' to ``FunctionDef_kind`` and -initializes the *name*, *args*, *body*, and *attributes* fields. - - -Memory management -================= - -Before discussing the actual implementation of the compiler, a discussion of -how memory is handled is in order. To make memory management simple, an **arena** -is used that pools memory in a single location for easy -allocation and removal. This enables the removal of explicit memory -deallocation. Because memory allocation for all needed memory in the compiler -registers that memory with the arena, a single call to free the arena is all -that is needed to completely free all memory used by the compiler. - -In general, unless you are working on the critical core of the compiler, memory -management can be completely ignored. But if you are working at either the -very beginning of the compiler or the end, you need to care about how the arena -works. All code relating to the arena is in either -:cpy-file:`Include/internal/pycore_pyarena.h` or :cpy-file:`Python/pyarena.c`. - -``PyArena_New()`` will create a new arena. The returned ``PyArena`` structure -will store pointers to all memory given to it. This does the bookkeeping of -what memory needs to be freed when the compiler is finished with the memory it -used. That freeing is done with ``PyArena_Free()``. This only needs to be -called in strategic areas where the compiler exits. - -As stated above, in general you should not have to worry about memory -management when working on the compiler. The technical details of memory -management have been designed to be hidden from you for most cases. - -The only exception comes about when managing a PyObject. Since the rest -of Python uses reference counting, there is extra support added -to the arena to cleanup each PyObject that was allocated. These cases -are very rare. However, if you've allocated a PyObject, you must tell -the arena about it by calling ``PyArena_AddPyObject()``. - - -Source code to AST -================== - -The AST is generated from source code using the function -``_PyParser_ASTFromString()`` or ``_PyParser_ASTFromFile()`` -(from :cpy-file:`Parser/peg_api.c`) depending on the input type. - -After some checks, a helper function in :cpy-file:`Parser/parser.c` begins applying -production rules on the source code it receives; converting source code to -tokens and matching these tokens recursively to their corresponding rule. The -production rule's corresponding rule function is called on every match. These rule -functions follow the format :samp:`xx_rule`. Where *xx* is the grammar rule -that the function handles and is automatically derived from -:cpy-file:`Grammar/python.gram` -:cpy-file:`Tools/peg_generator/pegen/c_generator.py`. - -Each rule function in turn creates an AST node as it goes along. It does this -by allocating all the new nodes it needs, calling the proper AST node creation -functions for any required supporting functions and connecting them as needed. -This continues until all nonterminal symbols are replaced with terminals. If an -error occurs, the rule functions backtrack and try another rule function. If -there are no more rules, an error is set and the parsing ends. - -The AST node creation helper functions have the name :samp:`_PyAST_{xx}` -where *xx* is the AST node that the function creates. These are defined by the -ASDL grammar and contained in :cpy-file:`Python/Python-ast.c` (which is -generated by :cpy-file:`Parser/asdl_c.py` from :cpy-file:`Parser/Python.asdl`). -This all leads to a sequence of AST nodes stored in ``asdl_seq`` structs. - -To demonstrate everything explained so far, here's the -rule function responsible for a simple named import statement such as -``import sys``. Note that error-checking and debugging code has been -omitted. Removed parts are represented by ``...``. -Furthermore, some comments have been added for explanation. These comments -may not be present in the actual code. - -.. code-block:: c - - // This is the production rule (from python.gram) the rule function - // corresponds to: - // import_name: 'import' dotted_as_names - static stmt_ty - import_name_rule(Parser *p) - { - ... - stmt_ty _res = NULL; - { // 'import' dotted_as_names - ... - Token * _keyword; - asdl_alias_seq* a; - // The tokenizing steps. - if ( - (_keyword = _PyPegen_expect_token(p, 513)) // token='import' - && - (a = dotted_as_names_rule(p)) // dotted_as_names - ) - { - ... - // Generate an AST for the import statement. - _res = _PyAST_Import ( a , ...); - ... - goto done; - } - ... - } - _res = NULL; - done: - ... - return _res; - } - - -To improve backtracking performance, some rules (chosen by applying a -``(memo)`` flag in the grammar file) are memoized. Each rule function checks if -a memoized version exists and returns that if so, else it continues in the -manner stated in the previous paragraphs. - -There are macros for creating and using ``asdl_xx_seq *`` types, where *xx* is -a type of the ASDL sequence. Three main types are defined -manually -- ``generic``, ``identifier`` and ``int``. These types are found in -:cpy-file:`Python/asdl.c` and its corresponding header file -:cpy-file:`Include/internal/pycore_asdl.h`. Functions and macros -for creating ``asdl_xx_seq *`` types are as follows: - -``_Py_asdl_generic_seq_new(Py_ssize_t, PyArena *)`` - Allocate memory for an ``asdl_generic_seq`` of the specified length -``_Py_asdl_identifier_seq_new(Py_ssize_t, PyArena *)`` - Allocate memory for an ``asdl_identifier_seq`` of the specified length -``_Py_asdl_int_seq_new(Py_ssize_t, PyArena *)`` - Allocate memory for an ``asdl_int_seq`` of the specified length - -In addition to the three types mentioned above, some ASDL sequence types are -automatically generated by :cpy-file:`Parser/asdl_c.py` and found in -:cpy-file:`Include/internal/pycore_ast.h`. Macros for using both manually -defined and automatically generated ASDL sequence types are as follows: - -``asdl_seq_GET(asdl_xx_seq *, int)`` - Get item held at a specific position in an ``asdl_xx_seq`` -``asdl_seq_SET(asdl_xx_seq *, int, stmt_ty)`` - Set a specific index in an ``asdl_xx_seq`` to the specified value - -Untyped counterparts exist for some of the typed macros. These are useful -when a function needs to manipulate a generic ASDL sequence: - -``asdl_seq_GET_UNTYPED(asdl_seq *, int)`` - Get item held at a specific position in an ``asdl_seq`` -``asdl_seq_SET_UNTYPED(asdl_seq *, int, stmt_ty)`` - Set a specific index in an ``asdl_seq`` to the specified value -``asdl_seq_LEN(asdl_seq *)`` - Return the length of an ``asdl_seq`` or ``asdl_xx_seq`` - -Note that typed macros and functions are recommended over their untyped -counterparts. Typed macros carry out checks in debug mode and aid -debugging errors caused by incorrectly casting from ``void *``. - -If you are working with statements, you must also worry about keeping -track of what line number generated the statement. Currently the line -number is passed as the last parameter to each ``stmt_ty`` function. - -.. versionchanged:: 3.9 - The new PEG parser generates an AST directly without creating a - parse tree. ``Python/ast.c`` is now only used to validate the AST for - debugging purposes. - -.. seealso:: :pep:`617` (PEP 617 -- New PEG parser for CPython) - - -Control flow graphs -=================== - -A **control flow graph** (often referenced by its acronym, **CFG**) is a -directed graph that models the flow of a program. A node of a CFG is -not an individual bytecode instruction, but instead represents a -sequence of bytecode instructions that always execute sequentially. -Each node is called a *basic block* and must always execute from -start to finish, with a single entry point at the beginning and a -single exit point at the end. If some bytecode instruction *a* needs -to jump to some other bytecode instruction *b*, then *a* must occur at -the end of its basic block, and *b* must occur at the start of its -basic block. - -As an example, consider the following code snippet: - -.. code-block:: Python - - if x < 10: - f1() - f2() - else: - g() - end() - -The ``x < 10`` guard is represented by its own basic block that -compares ``x`` with ``10`` and then ends in a conditional jump based on -the result of the comparison. This conditional jump allows the block -to point to both the body of the ``if`` and the body of the ``else``. The -``if`` basic block contains the ``f1()`` and ``f2()`` calls and points to -the ``end()`` basic block. The ``else`` basic block contains the ``g()`` -call and similarly points to the ``end()`` block. - -Note that more complex code in the guard, the ``if`` body, or the ``else`` -body may be represented by multiple basic blocks. For instance, -short-circuiting boolean logic in a guard like ``if x or y:`` -will produce one basic block that tests the truth value of ``x`` -and then points both (1) to the start of the ``if`` body and (2) to -a different basic block that tests the truth value of y. - -CFGs are usually one step away from final code output. Code is directly -generated from the basic blocks (with jump targets adjusted based on the -output order) by doing a post-order depth-first search on the CFG -following the edges. - - -AST to CFG to bytecode -====================== - -With the AST created, the next step is to create the CFG. The first step -is to convert the AST to Python bytecode without having jump targets -resolved to specific offsets (this is calculated when the CFG goes to -final bytecode). Essentially, this transforms the AST into Python -bytecode with control flow represented by the edges of the CFG. - -Conversion is done in two passes. The first creates the namespace -(variables can be classified as local, free/cell for closures, or -global). With that done, the second pass essentially flattens the CFG -into a list and calculates jump offsets for final output of bytecode. - -The conversion process is initiated by a call to the function -``_PyAST_Compile()`` in :cpy-file:`Python/compile.c`. This function does both -the conversion of the AST to a CFG and outputting final bytecode from the CFG. -The AST to CFG step is handled mostly by two functions called by -``_PyAST_Compile()``; ``_PySymtable_Build()`` and ``compiler_mod()``. -The former is in :cpy-file:`Python/symtable.c` while the latter is -:cpy-file:`Python/compile.c`. - -``_PySymtable_Build()`` begins by entering the starting code block for the -AST (passed-in) and then calling the proper :samp:`symtable_visit_{xx}` function -(with *xx* being the AST node type). Next, the AST tree is walked with -the various code blocks that delineate the reach of a local variable -as blocks are entered and exited using ``symtable_enter_block()`` and -``symtable_exit_block()``, respectively. - -Once the symbol table is created, it is time for CFG creation, whose -code is in :cpy-file:`Python/compile.c`. This is handled by several functions -that break the task down by various AST node types. The functions are -all named :samp:`compiler_visit_{xx}` where *xx* is the name of the node type (such -as ``stmt``, ``expr``, etc.). Each function receives a ``struct compiler *`` -and :samp:`{xx}_ty` where *xx* is the AST node type. Typically these functions -consist of a large 'switch' statement, branching based on the kind of -node type passed to it. Simple things are handled inline in the -'switch' statement with more complex transformations farmed out to other -functions named :samp:`compiler_{xx}` with *xx* being a descriptive name of what is -being handled. - -When transforming an arbitrary AST node, use the ``VISIT()`` macro. -The appropriate :samp:`compiler_visit_{xx}` function is called, based on the value -passed in for (so :samp:`VISIT({c}, expr, {node})` calls -:samp:`compiler_visit_expr({c}, {node})`). The ``VISIT_SEQ()`` macro is very similar, -but is called on AST node sequences (those values that were created as -arguments to a node that used the '*' modifier). There is also -``VISIT_SLICE()`` just for handling slices. - -Emission of bytecode is handled by the following macros: - -``ADDOP(struct compiler *, int)`` - add a specified opcode -``ADDOP_NOLINE(struct compiler *, int)`` - like ``ADDOP`` without a line number; used for artificial opcodes without - a corresponding token in the source code -``ADDOP_IN_SCOPE(struct compiler *, int)`` - like ``ADDOP``, but also exits current scope; used for adding return value - opcodes in lambdas and closures -``ADDOP_I(struct compiler *, int, Py_ssize_t)`` - add an opcode that takes an integer argument -``ADDOP_O(struct compiler *, int, PyObject *, TYPE)`` - add an opcode with the proper argument based on the position of the - specified PyObject in PyObject sequence object, but with no handling of - mangled names; used for when you - need to do named lookups of objects such as globals, consts, or - parameters where name mangling is not possible and the scope of the - name is known; *TYPE* is the name of PyObject sequence - (``names`` or ``varnames``) -``ADDOP_N(struct compiler *, int, PyObject *, TYPE)`` - just like ``ADDOP_O``, but steals a reference to PyObject -``ADDOP_NAME(struct compiler *, int, PyObject *, TYPE)`` - just like ``ADDOP_O``, but name mangling is also handled; used for - attribute loading or importing based on name -``ADDOP_LOAD_CONST(struct compiler *, PyObject *)`` - add the ``LOAD_CONST`` opcode with the proper argument based on the - position of the specified PyObject in the consts table. -``ADDOP_LOAD_CONST_NEW(struct compiler *, PyObject *)`` - just like ``ADDOP_LOAD_CONST``, but steals a reference to PyObject -``ADDOP_JUMP(struct compiler *, int, basicblock *)`` - create a jump to a basic block -``ADDOP_JUMP_NOLINE(struct compiler *, int, basicblock *)`` - like ``ADDOP_JUMP`` without a line number; used for artificial jumps - without a corresponding token in the source code. -``ADDOP_JUMP_COMPARE(struct compiler *, cmpop_ty)`` - depending on the second argument, add an ``ADDOP_I`` with either an - ``IS_OP``, ``CONTAINS_OP``, or ``COMPARE_OP`` opcode. - -Several helper functions that will emit bytecode are named -:samp:`compiler_{xx}()` where *xx* is what the function helps with (``list``, -``boolop``, etc.). A rather useful one is ``compiler_nameop()``. -This function looks up the scope of a variable and, based on the -expression context, emits the proper opcode to load, store, or delete -the variable. - -As for handling the line number on which a statement is defined, this is -handled by ``compiler_visit_stmt()`` and thus is not a worry. - -Once the CFG is created, it must be flattened and then final emission of -bytecode occurs. Flattening is handled using a post-order depth-first -search. Once flattened, jump offsets are backpatched based on the -flattening and then a ``PyCodeObject`` is created. All of this is -handled by calling ``assemble()``. - - -Code objects -============ - -The result of ``PyAST_CompileObject()`` is a ``PyCodeObject`` which is defined in -:cpy-file:`Include/cpython/code.h`. And with that you now have executable -Python bytecode! - -The code objects (byte code) are executed in :cpy-file:`Python/ceval.c`. This file -will also need a new case statement for the new opcode in the big switch -statement in ``_PyEval_EvalFrameDefault()``. - - -Important files -=============== - -* :cpy-file:`Parser/` - - * :cpy-file:`Parser/Python.asdl`: ASDL syntax file. - - * :cpy-file:`Parser/asdl.py`: Parser for ASDL definition files. - Reads in an ASDL description and parses it into an AST that describes it. - - * :cpy-file:`Parser/asdl_c.py`: Generate C code from an ASDL description. - Generates :cpy-file:`Python/Python-ast.c` and - :cpy-file:`Include/internal/pycore_ast.h`. - - * :cpy-file:`Parser/parser.c`: The new PEG parser introduced in Python 3.9. - Generated by :cpy-file:`Tools/peg_generator/pegen/c_generator.py` - from the grammar :cpy-file:`Grammar/python.gram`. Creates the AST from - source code. Rule functions for their corresponding production rules - are found here. - - * :cpy-file:`Parser/peg_api.c`: Contains high-level functions which are - used by the interpreter to create an AST from source code. - - * :cpy-file:`Parser/pegen.c`: Contains helper functions which are used - by functions in :cpy-file:`Parser/parser.c` to construct the AST. - Also contains helper functions which help raise better error messages - when parsing source code. - - * :cpy-file:`Parser/pegen.h`: Header file for the corresponding - :cpy-file:`Parser/pegen.c`. Also contains definitions of the ``Parser`` - and ``Token`` structs. - -* :cpy-file:`Python/` - - * :cpy-file:`Python/Python-ast.c`: Creates C structs corresponding to - the ASDL types. Also contains code for marshalling AST nodes (core - ASDL types have marshalling code in :cpy-file:`Python/asdl.c`). - "File automatically generated by :cpy-file:`Parser/asdl_c.py`". - This file must be committed separately after every grammar change - is committed since the ``__version__`` value is set to the latest - grammar change revision number. - - * :cpy-file:`Python/asdl.c`: Contains code to handle the ASDL sequence type. - Also has code to handle marshalling the core ASDL types, such as number - and identifier. Used by :cpy-file:`Python/Python-ast.c` for marshalling - AST nodes. - - * :cpy-file:`Python/ast.c`: Used for validating the AST. - - * :cpy-file:`Python/ast_opt.c`: Optimizes the AST. - - * :cpy-file:`Python/ast_unparse.c`: Converts the AST expression node - back into a string (for string annotations). - - * :cpy-file:`Python/ceval.c`: Executes byte code (aka, eval loop). - - * :cpy-file:`Python/compile.c`: Emits bytecode based on the AST. - - * :cpy-file:`Python/symtable.c`: Generates a symbol table from AST. - - * :cpy-file:`Python/pyarena.c`: Implementation of the arena memory manager. - - * :cpy-file:`Python/opcode_targets.h`: One of the files that must be - modified if :cpy-file:`Lib/opcode.py` is. - -* :cpy-file:`Include/` - - * :cpy-file:`Include/cpython/code.h`: Header file for - :cpy-file:`Objects/codeobject.c`; contains definition of ``PyCodeObject``. - - * :cpy-file:`Include/opcode.h`: One of the files that must be modified if - :cpy-file:`Lib/opcode.py` is. - - * :cpy-file:`Include/internal/pycore_ast.h`: Contains the actual definitions - of the C structs as generated by :cpy-file:`Python/Python-ast.c`. - "Automatically generated by :cpy-file:`Parser/asdl_c.py`". - - * :cpy-file:`Include/internal/pycore_asdl.h`: Header for the corresponding - :cpy-file:`Python/ast.c`. - - * :cpy-file:`Include/internal/pycore_ast.h`: Declares ``_PyAST_Validate()`` - external (from :cpy-file:`Python/ast.c`). - - * :cpy-file:`Include/internal/pycore_symtable.h`: Header for - :cpy-file:`Python/symtable.c`. ``struct symtable`` and ``PySTEntryObject`` - are defined here. - - * :cpy-file:`Include/internal/pycore_parser.h`: Header for the - corresponding :cpy-file:`Parser/peg_api.c`. - - * :cpy-file:`Include/internal/pycore_pyarena.h`: Header file for the - corresponding :cpy-file:`Python/pyarena.c`. - -* :cpy-file:`Objects/` - - * :cpy-file:`Objects/codeobject.c`: Contains PyCodeObject-related code - (originally in :cpy-file:`Python/compile.c`). - - * :cpy-file:`Objects/frameobject.c`: Contains the ``frame_setlineno()`` - function which should determine whether it is allowed to make a jump - between two points in a bytecode. - -* :cpy-file:`Lib/` - - * :cpy-file:`Lib/opcode.py`: Master list of bytecode; if this file is - modified you must modify several other files accordingly - - * :cpy-file:`Lib/importlib/_bootstrap_external.py`: Home of the magic number - (named ``MAGIC_NUMBER``) for bytecode versioning. - - -Objects -======= - -* :cpy-file:`Objects/locations.md`: Describes the location table -* :cpy-file:`Objects/frame_layout.md`: Describes the frame stack -* :cpy-file:`Objects/object_layout.md`: Descibes object layout for 3.11 and later -* :cpy-file:`Objects/exception_handling_notes.txt`: Exception handling notes - - -Specializing Adaptive Interpreter -================================= - -Adding a specializing, adaptive interpreter to CPython will bring significant -performance improvements. These documents provide more information: - -* :pep:`659`: Specializing Adaptive Interpreter -* :cpy-file:`Python/adaptive.md`: Adding or extending a family of adaptive instructions - - -References -========== - -.. [Wang97] Daniel C. Wang, Andrew W. Appel, Jeff L. Korn, and Chris - S. Serra. `The Zephyr Abstract Syntax Description Language.`_ - In Proceedings of the Conference on Domain-Specific Languages, pp. - 213--227, 1997. - -.. _The Zephyr Abstract Syntax Description Language.: - https://www.cs.princeton.edu/research/techreps/TR-554-97 +This document is now part of the +`CPython Internals Docs `_. diff --git a/internals/parser.rst b/internals/parser.rst index ac5f9ba49..9ba615013 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -804,10 +804,10 @@ Generating AST objects The output of the C parser used by CPython that is generated by the :cpy-file:`Grammar/python.gram` grammar file is a Python AST object (using C structures). This means that the actions in the grammar file generate AST objects -when they succeed. Constructing these objects can be quite cumbersome (see -the :ref:`AST compiler section ` for more information -on how these objects are constructed and how they are used by the compiler) so -special helper functions are used. These functions are declared in the +when they succeed. Constructing these objects can be quite cumbersome (see the +`AST compiler section `_ +for more information on how these objects are constructed and how they are used +by the compiler) so special helper functions are used. These functions are declared in the :cpy-file:`Parser/pegen.h` header file and defined in the :cpy-file:`Parser/action_helpers.c` file. These functions allow you to join AST sequences, get specific elements from them or to do extra processing on the generated tree. From d7b683f25390b3de0680123133b56cc992960e2c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 24 Jun 2024 01:53:21 -0600 Subject: [PATCH 316/538] Update CPython repo admins (#1341) --- developer-workflow/development-cycle.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 79a9dced4..088998fb1 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -340,17 +340,15 @@ 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.8 and 3.9 Release Manager, | ambv | -| | PSF CPython Developer in Residence 2021-2022 | | -+-------------------+----------------------------------------------------------+-----------------+ -| Ned Deily | Python 3.6 and 3.7 Release Manager | ned-deily | -+-------------------+----------------------------------------------------------+-----------------+ -| Larry Hastings | Retired Release Manager (for Python 3.4 and 3.5) | larryhastings | -+-------------------+----------------------------------------------------------+-----------------+ -| Berker Peksag | Maintainer of bpo-linkify and cpython-emailer-webhook | berkerpeksag | +| | PSF CPython Developer in Residence 2021-present | | +-------------------+----------------------------------------------------------+-----------------+ | Brett Cannon | | brettcannon | +-------------------+----------------------------------------------------------+-----------------+ From fbdcdad4305c03baf79c36f00eea382bc36a3cdc Mon Sep 17 00:00:00 2001 From: Ee Durbin Date: Tue, 2 Jul 2024 18:18:32 -0400 Subject: [PATCH 317/538] update python organization owners (#1345) - @JacobCoffee has started as PSF Infrastructure Engineer - Van is no longer acting as counsel to the PSF and owner role was removed some time ago --- developer-workflow/development-cycle.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 088998fb1..0fd9c1c23 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -301,7 +301,7 @@ Current owners +----------------------+--------------------------------+-----------------+ | Ee Durbin | PSF Director of Infrastructure | ewdurbin | +----------------------+--------------------------------+-----------------+ -| Van Lindberg | PSF General Counsel | VanL | +| Jacob Coffee | PSF Infrastructure Engineer | JacobCoffee | +----------------------+--------------------------------+-----------------+ | Łukasz Langa | CPython Developer in Residence | ambv | +----------------------+--------------------------------+-----------------+ From 99b593ed12dc61759801534bfd6a44a7bffe4a26 Mon Sep 17 00:00:00 2001 From: q-ata <24601033+q-ata@users.noreply.github.com> Date: Fri, 5 Jul 2024 17:35:47 +0200 Subject: [PATCH 318/538] Fix a typo in garbage collector documentation (#1346) --- internals/garbage-collector.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index 7459b23e8..4811383fc 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -229,7 +229,7 @@ unreachable: The GC starts with a set of candidate objects it wants to scan. In the default build, these "objects to scan" might be all container objects or a smaller subset (or "generation"). In the free-threaded build, the collector -always operates scans all container objects. +always scans all container objects. The objective is to identify all the unreachable objects. The collector does this by identifying reachable objects; the remaining objects must be From efa3c68d9bdab5184c43e75db71981b27f308881 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Fri, 5 Jul 2024 17:08:47 -0400 Subject: [PATCH 319/538] Remove e.g. and i.e. throughout (#1343) --- .github/CODE_OF_CONDUCT.md | 2 +- .github/CONTRIBUTING.md | 2 +- core-developers/committing.rst | 20 +++++++------- core-developers/motivations.rst | 4 +-- developer-workflow/c-api.rst | 8 +++--- developer-workflow/development-cycle.rst | 32 +++++++++++----------- developer-workflow/porting.rst | 6 ++-- developer-workflow/stdlib.rst | 2 +- development-tools/clinic.rst | 2 +- development-tools/gdb.rst | 2 +- documentation/help-documenting.rst | 2 +- documentation/markup.rst | 18 ++++++------ documentation/style-guide.rst | 16 +++++++++-- getting-started/git-boot-camp.rst | 4 +-- getting-started/pull-request-lifecycle.rst | 12 ++++---- getting-started/setup-building.rst | 19 +++++++------ index.rst | 6 ++-- internals/garbage-collector.rst | 12 ++++---- internals/interpreter.rst | 12 ++++---- internals/parser.rst | 12 ++++---- testing/coverage.rst | 14 +++++----- testing/new-buildbot-worker.rst | 2 +- testing/run-write-tests.rst | 2 +- testing/silence-warnings.rst | 2 +- triage/triage-team.rst | 2 +- triage/triaging.rst | 2 +- 26 files changed, 114 insertions(+), 103 deletions(-) diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 45402ea7f..376c78461 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -6,7 +6,7 @@ Please note that all interactions on infrastructure is [covered](https://www.python.org/psf/records/board/minutes/2014-01-06/#management-of-the-psfs-web-properties) by the [PSF Code of Conduct](https://www.python.org/psf/conduct/), which includes all infrastructure used in the development of Python itself -(e.g. mailing lists, issue trackers, GitHub, etc.). +(for example, mailing lists, issue trackers, GitHub, etc.). In general this means everyone is expected to be open, considerate, and respectful of others no matter what their position is within the project. diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index c54abaedc..a6bafe511 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -29,7 +29,7 @@ our workflow that are not covered by a bot or status check are: ## Setting Expectations -Due to the fact that this project is entirely volunteer-run (i.e. no one is paid +Due to the fact that this project is entirely volunteer-run (that is, no one is paid to work on Python full-time), we unfortunately can make no guarantees as to if or when a core developer will get around to reviewing your pull request. If no core developer has done a review or responded to changes made because of a diff --git a/core-developers/committing.rst b/core-developers/committing.rst index 3206d991a..e438d39fa 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -44,7 +44,7 @@ to enter the public source tree. Ask yourself the following questions: `__. * **Does documentation need to be updated?** - If the pull request introduces backwards-incompatible changes (e.g. + If the pull request introduces backwards-incompatible changes (for example, deprecating or removing a feature), then make sure that those changes are reflected in the documentation before you merge the pull request. @@ -61,14 +61,14 @@ to enter the public source tree. Ask yourself the following questions: Make sure that the contributor has signed a `Contributor Licensing Agreement `_ (CLA), unless their change has no possible intellectual property - associated with it (e.g. fixing a spelling mistake in documentation). + associated with it (for example, fixing a spelling mistake in documentation). The `CPython CLA Bot `_ checks whether the author has signed the CLA, and replies in the PR if they haven't. For further questions about the CLA process, write to contributors@python.org. * **Were** ``What's New in Python`` **and** ``Misc/NEWS.d/next`` **updated?** - If the change is particularly interesting for end users (e.g. new features, + If the change is particularly interesting for end users (for example, new features, significant improvements, or backwards-incompatible changes), then an entry in the ``What's New in Python`` document (in ``Doc/whatsnew/``) should be added as well. Changes that affect only documentation generally do not @@ -97,7 +97,7 @@ For the last two, note the following: #. **If a change is reverted prior to release**, then the corresponding entry is simply removed. Otherwise, a new entry must be added noting - that the change has been reverted (e.g. when a feature is released in + that the change has been reverted (for example, when a feature is released in an alpha and then cut prior to the first beta). #. **If a change is a fix (or other adjustment) to an earlier unreleased @@ -107,7 +107,7 @@ For the last two, note the following: Changes that require "What's New in Python" entries ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If a change is particularly interesting for end users (e.g. new features, +If a change is particularly interesting for end users (for example, new features, significant improvements, or backwards-incompatible changes), add an entry in the "What's New in Python" document (in :cpy-file:`Doc/whatsnew/`) in addition to the ``NEWS`` entry. @@ -130,16 +130,16 @@ or the :pypi:`blurb` tool and its ``blurb add`` command. If you are unable to use the tool, then you can create the ``NEWS`` entry file manually. The ``Misc/NEWS.d`` directory contains a sub-directory named ``next``, which contains various sub-directories representing classifications -for what was affected (e.g. ``Misc/NEWS.d/next/Library`` for changes relating +for what was affected (for example, ``Misc/NEWS.d/next/Library`` for changes relating to the standard library). The file name itself should be in the format ``.gh-issue-..rst``: * ```` is today's date joined with a hyphen (``-``) to your current - local time, in the ``YYYY-MM-DD-hh-mm-ss`` format (e.g. ``2017-05-27-16-46-23``). -* ```` is the issue number the change is for (e.g. ``12345`` + local time, in the ``YYYY-MM-DD-hh-mm-ss`` format (for example, ``2017-05-27-16-46-23``). +* ```` is the issue number the change is for (for example, ``12345`` for ``gh-issue-12345``). * ```` is a unique string to guarantee that the file name is - unique across branches (e.g. ``Yl4gI2``). It is typically six characters + unique across branches (for example, ``Yl4gI2``). It is typically six characters long, but it can be any length of letters and numbers. Its uniqueness can be satisfied by typing random characters on your keyboard. @@ -159,7 +159,7 @@ the reader to have read the actual diff for the change. The contents of a ``NEWS`` file should be valid reStructuredText. An 80 character column width should be used. There is no indentation or leading marker in the -file (e.g. ``-``). There is also no need to start the entry with the issue +file (for example, ``-``). There is also no need to start the entry with the issue number since it is part of the file name. You can use :ref:`inline markups ` too. Here is an example of a ``NEWS`` entry:: diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index c32304962..dfe41d5ae 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -80,7 +80,7 @@ participating in the CPython core development process: country of residence. Include a "Crowdfunding" bullet point with a link if you'd like to highlight - crowdfunding services (e.g. Patreon) that folks can use to support your core + crowdfunding services (for example, Patreon) that folks can use to support your core development work. Include additional bullet points (without links) for any other affiliations @@ -116,7 +116,7 @@ participating in the CPython core development process: applications and test harnesses from open source components. Note: prior to August 2023, Alyssa used her birth name (Nick Coghlan). Some records - (e.g. mailing list archives, version control history) will still reference that name. + (for example, mailing list archives, version control history) will still reference that name. .. topic:: Steve Dower (United States/Australia) diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index f0620aca5..3f8c03e92 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -219,7 +219,7 @@ Moving an API from the public tier to Unstable * Expose the API under its new name, with the ``PyUnstable_`` prefix. The ``PyUnstable_`` prefix must be used for all symbols (functions, macros, variables, etc.). -* Make the old name an alias (e.g. a ``static inline`` function calling the +* Make the old name an alias (for example, a ``static inline`` function calling the new function). * Deprecate the old name, typically using :c:macro:`Py_DEPRECATED`. * Announce the change in the "What's New". @@ -255,7 +255,7 @@ Moving an API from unstable to public ------------------------------------- * Expose the API under its new name, without the ``PyUnstable_`` prefix. -* Make the old ``PyUnstable_*`` name be an alias (e.g. a ``static inline`` +* Make the old ``PyUnstable_*`` name be an alias (for example, a ``static inline`` function calling the new function). * Announce the change in What's New. @@ -393,7 +393,7 @@ Adding a new definition to the Limited API #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03yy0000 - with the ``yy`` corresponding to the target CPython version, e.g. + with the ``yy`` corresponding to the target CPython version, for example, ``0x030A0000`` for Python 3.10. - Append an entry to the Stable ABI manifest, ``Misc/stable_abi.toml`` - Regenerate the autogenerated files using ``make regen-limited-abi``. @@ -426,7 +426,7 @@ To add a test file: - Add a C file ``Modules/_testcapi/yourfeature_limited.c``. If that file already exists but its ``Py_LIMITED_API`` version is too low, add a version - postfix, e.g. ``yourfeature_limited_3_12.c`` for Python 3.12+. + postfix, for example, ``yourfeature_limited_3_12.c`` for Python 3.12+. - ``#define Py_LIMITED_API`` to the minimum limited API version needed. - ``#include "parts.h"`` after the ``Py_LIMITED_API`` definition - Enclose the entire rest of the file in ``#ifdef LIMITED_API_AVAILABLE``, diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 0fd9c1c23..501df2d43 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -36,8 +36,8 @@ Some examples of release tags: ``v3.7.0a1``, ``v3.6.3``, ``v2.7.14rc1``. Branches -------- -There is a branch for each *feature version*, whether released or not (e.g. -3.7, 3.8). +There is a branch for each *feature version*, whether released or not (for +example, 3.7, 3.8). .. _indevbranch: @@ -57,7 +57,7 @@ For versions 3.4 and before, this was conventionally done when the final release was cut (for example, 3.4.0 final). Starting with the 3.5 release, we create the release maintenance branch -(e.g. 3.5) at the time we enter beta (3.5.0 beta 1). This allows +(``3.5``) at the time we enter beta (3.5.0 beta 1). This allows feature development for the release 3.n+1 to occur within the main branch alongside the beta and release candidate stabilization periods for release 3.n. @@ -89,7 +89,7 @@ since most readers access the `stable documentation rather than the `development documentation `__. A new maintenance branch is normally created when the next feature release -cycle reaches feature freeze, i.e. at its first beta pre-release. +cycle reaches feature freeze, that is, at its first beta pre-release. From that point on, changes intended for remaining pre-releases, the final release (3.x.0), and subsequent bugfix releases are merged to that maintenance branch. @@ -131,7 +131,7 @@ End-of-life branches The code base for a release cycle which has reached end-of-life status is frozen and no longer has a branch in the repo. The final state of the end-of-lifed branch is recorded as a tag with the same name as the -former branch, e.g. ``3.3`` or ``2.6``. +former branch, for example, ``3.3`` or ``2.6``. The :ref:`versions` page contains list of active and end-of-life branches. @@ -191,7 +191,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 -severe enough (e.g. crashes) that they deserve fixing before the final release. +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. @@ -227,13 +227,13 @@ 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 (i.e. `CPython `_) -* Tooling and support around CPython development (e.g. `pyperformance `_, `Bedevere `_) -* Helpers and backports for Python/CPython features (e.g. `typing_extensions `_, `typeshed `_, `tzdata `_, `pythoncapi-compat `_) -* Organization-related repositories (e.g. the `Code of Conduct `_, `.github `_) -* Documentation and websites for all the above (e.g. `python.org repository `_, `PEPs `_, `Devguide `_, docs translations) -* Infrastructure for all the above (e.g. `docsbuild-scripts `_, `buildmaster-config `_) -* Discussions and notes around official development-related processes and events (e.g. `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 `_. @@ -248,13 +248,13 @@ accounts or other GitHub orgs. It is relatively easy to move a repository to the organization once it is mature. For example, this would now apply to experimental features like `asyncio `_, `exceptiongroups `_, -and drafts of new guides and other documentation (e.g. `redistributor-guide +and drafts of new guides and other documentation (for example, `redistributor-guide `_). -General-use tools and libraries (e.g. `mypy `_ +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 e.g. +specifically want to “bless” one implementation (as with `typeshed `_, `tzdata `_, or `pythoncapi-compat `_). diff --git a/developer-workflow/porting.rst b/developer-workflow/porting.rst index 26756bc8f..f308e6c14 100644 --- a/developer-workflow/porting.rst +++ b/developer-workflow/porting.rst @@ -13,11 +13,11 @@ which it has already been ported; preferably Unix, but Windows will do, too. The build process for Python, in particular the ``Makefile`` in the source distribution, will give you a hint on which files to compile for Python. Not all source files are relevant: some are platform-specific, -and others are only used in emergencies (e.g. ``getopt.c``). +and others are only used in emergencies (for example, ``getopt.c``). It is not recommended to start porting Python without at least a medium-level -understanding of your target platform; i.e. how it is generally used, how to -write platform-specific apps, etc. Also, some Python knowledge is required, or +understanding of your target platform; how it is generally used, how to +write platform-specific apps, and so on. Also, some Python knowledge is required, or you will be unable to verify that your port is working correctly. You will need a ``pyconfig.h`` file tailored for your platform. You can diff --git a/developer-workflow/stdlib.rst b/developer-workflow/stdlib.rst index ae0f7208e..732ee8f45 100644 --- a/developer-workflow/stdlib.rst +++ b/developer-workflow/stdlib.rst @@ -108,7 +108,7 @@ year, a module needs to have established itself as (one of) the top choices by the community for solving the problem the module is intended for. The development of the module must move into Python's -infrastructure (i.e., the module is no longer directly maintained outside of +infrastructure (that is, the module is no longer directly maintained outside of Python). This prevents a divergence between the code that is included in the stdlib and that which is released outside the stdlib (typically done to provide the module to older versions of Python). It also removes the burden of forcing diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index 910de404a..642f40dce 100644 --- a/development-tools/clinic.rst +++ b/development-tools/clinic.rst @@ -213,7 +213,7 @@ Classes for extending Argument Clinic The C type to use for this variable. :attr:`!type` should be a Python string specifying the type, - e.g. ``'int'``. + for example, ``'int'``. If this is a pointer type, the type string should end with ``' *'``. .. attribute:: default diff --git a/development-tools/gdb.rst b/development-tools/gdb.rst index e85e826a0..8f89ea136 100644 --- a/development-tools/gdb.rst +++ b/development-tools/gdb.rst @@ -33,7 +33,7 @@ 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 -prefaced with a label named ``TARGET_``, e.g., +prefaced with a label named ``TARGET_``, for example, ``TARGET_LOAD_CONST``. You can then set a breakpoint with a command like:: diff --git a/documentation/help-documenting.rst b/documentation/help-documenting.rst index 06e44549c..0b287df92 100644 --- a/documentation/help-documenting.rst +++ b/documentation/help-documenting.rst @@ -74,7 +74,7 @@ Proofreading While an issue filed on the `issue tracker`_ means there is a known issue somewhere, that does not mean there are not other issues lurking about in the documentation. Proofreading a part of the documentation, such as a "How to" or -OS specific document, can often uncover problems (e.g., documentation that +OS specific document, can often uncover problems (for example, documentation that needs updating for Python 3). If you decide to proofread, read a section of the documentation from start diff --git a/documentation/markup.rst b/documentation/markup.rst index b72e1a952..58b2bdac0 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -385,7 +385,7 @@ As you can see, the module-specific markup consists of two directives, the .. describe:: module This directive marks the beginning of the description of a module, package, - or submodule. The name should be fully qualified (i.e. including the + or submodule. The name should be fully qualified (that is, including the package name for submodules). The ``platform`` option, if present, is a comma-separated list of the @@ -443,7 +443,7 @@ The directives are: .. describe:: c:function - Describes a C function. The signature should be given as in C, e.g.:: + Describes a C function. The signature should be given as in C, for example:: .. c:function:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) @@ -683,7 +683,7 @@ Syntax highlighting is handled in a smart way: encountered. * The ``code-block`` directive can be used to specify the highlight language - of a single code block, e.g.:: + of a single code block, for example:: .. code-block:: c @@ -759,7 +759,7 @@ versatile: ``:meth:`~Queue.Queue.get``` will refer to ``Queue.Queue.get`` but only display ``get`` as the link text. - In HTML output, the link's ``title`` attribute (that is e.g. shown as a + In HTML output, the link's ``title`` attribute (that might be shown as a tool-tip on mouse-hover) will always be the full target name. * Combining ``~`` and ``!`` (for example, ``:meth:`~!Queue.Queue.get```) is not @@ -949,7 +949,7 @@ in a different style: .. describe:: manpage A reference to a Unix manual page including the section, - e.g. ``:manpage:`ls(1)```. + for example, ``:manpage:`ls(1)```. .. describe:: menuselection @@ -1138,7 +1138,7 @@ units as well as normal text: .. describe:: impl-detail This directive is used to mark CPython-specific information. Use either with - a block content or a single sentence as an argument, i.e. either :: + a block content or a single sentence as an argument, that is, either :: .. impl-detail:: @@ -1304,7 +1304,7 @@ the definition of the symbol. There is this directive: Blank lines are not allowed within ``productionlist`` directive arguments. The definition can contain token names which are marked as interpreted text - (e.g. ``unaryneg ::= "-" `integer```) -- this generates cross-references + (for example, ``unaryneg ::= "-" `integer```) -- this generates cross-references to the productions of these tokens. Note that no further reST parsing is done in the production, so that you @@ -1334,12 +1334,12 @@ default. They are set in the build configuration file :file:`conf.py`. .. describe:: |release| Replaced by the Python release the documentation refers to. This is the full - version string including alpha/beta/release candidate tags, e.g. ``2.5.2b3``. + version string including alpha/beta/release candidate tags, for example, ``2.5.2b3``. .. describe:: |version| Replaced by the Python version the documentation refers to. This consists - only of the major and minor version parts, e.g. ``2.5``, even for version + only of the major and minor version parts, for example, ``2.5``, even for version 2.5.1. .. describe:: |today| diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index 1e94e518d..e28691e10 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -88,6 +88,16 @@ Unix 1970s. +Use simple language +=================== + +Avoid esoteric phrasing where possible. Our audience is world-wide and may not +be native English speakers. + +Don't use Latin abbreviations like "e.g." or "i.e." where English words will do, +such as "for example" or "that is." + + .. index:: diataxis Diátaxis @@ -200,8 +210,8 @@ Security considerations (and other concerns) ============================================ Some modules provided with Python are inherently exposed to security issues -(e.g. shell injection vulnerabilities) due to the purpose of the module -(e.g. :mod:`ssl`). Littering the documentation of these modules with red +(for example, shell injection vulnerabilities) due to the purpose of the module +(for example, :mod:`ssl`). Littering the documentation of these modules with red warning boxes for problems that are due to the task at hand, rather than specifically to Python's support for that task, doesn't make for a good reading experience. @@ -213,7 +223,7 @@ similar to :samp:`"Please refer to the :ref:\`{security-considerations}\` section for important information on how to avoid common mistakes."`. Similarly, if there is a common error that affects many interfaces in a -module (e.g. OS level pipe buffers filling up and stalling child processes), +module (for example, OS level pipe buffers filling up and stalling child processes), these can be documented in a "Common Errors" section and cross-referenced rather than repeated for every affected interface. diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 9b60f0e1c..b5465cdb7 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -330,8 +330,8 @@ will automatically add a link to the issue in the first message. In addition, pull requests support `special keywords`_ that can be used to link to an issue and automatically close it when the PR is merged. -However, issues often require multiple PRs before they can be closed (e.g. -backports to other branches), so this features is only useful if +However, issues often require multiple PRs before they can be closed (for +example, backports to other branches), so this features is only useful if you know for sure that a single PR is enough to address and close the issue. .. _bedevere: https://github.com/python/bedevere diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 0cf34766e..42b341281 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -32,7 +32,7 @@ Here is a quick overview of how you can contribute to CPython: #. :ref:`Create a new branch in Git ` from the ``main`` branch -#. Work on changes (e.g. fix a bug or add a new feature) +#. Work on changes: fix a bug or add a new feature #. :ref:`Run tests ` and ``make patchcheck`` @@ -42,7 +42,7 @@ Here is a quick overview of how you can contribute to CPython: #. `Create Pull Request`_ on GitHub to merge a branch from your fork #. Make sure the :ref:`continuous integration checks on your Pull Request - are green ` (i.e. successful) + are green ` (successful) #. Review and address `comments on your Pull Request`_ @@ -51,7 +51,7 @@ Here is a quick overview of how you can contribute to CPython: #. Celebrate contributing to CPython! :) -.. [*] If an issue is trivial (e.g. typo fixes), or if an issue already exists, +.. [*] If an issue is trivial (for example, typo fixes), or if an issue already exists, you can skip this step. .. note:: @@ -358,7 +358,7 @@ changes to your branch. In general you can run ``git commit -a`` and that will commit everything. You can always run ``git status`` to see what changes are outstanding. -When all of your changes are committed (i.e. ``git status`` doesn't +When all of your changes are committed (that is, ``git status`` doesn't list anything), you will want to push your branch to your fork:: git push origin @@ -379,7 +379,7 @@ relevant detail as possible to prevent reviewers from having to delay reviewing your pull request because of lack of information. If this issue is so simple that there's no need for an issue to track -any discussion of what the pull request is trying to solve (e.g. fixing a +any discussion of what the pull request is trying to solve (for example, fixing a spelling mistake), then the pull request needs to have the "skip issue" label added to it by someone with commit access. @@ -419,7 +419,7 @@ your pull request. Getting your pull request reviewed requires a reviewer to have the spare time and motivation to look at your pull request (we cannot force anyone to review pull requests and no one is employed to look at pull requests). If your pull request has not -received any notice from reviewers (i.e., no comment made) after one +received any notice from reviewers (that is, no comment made) after one month, first "ping" the issue on the `issue tracker`_ to remind the subscribers that the pull request needs a review. If you don't get a response within a week after pinging the issue, diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index f653164d3..9960500e6 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -115,7 +115,7 @@ in the ``cpython`` directory and two remotes that refer to your own GitHub fork .. XXX move the text below in pullrequest If you want a working copy of an already-released version of Python, -i.e., a version in :ref:`maintenance mode `, you can checkout +that is, a version in :ref:`maintenance mode `, you can checkout a release branch. For instance, to checkout a working copy of Python 3.8, do ``git switch 3.8``. @@ -226,7 +226,7 @@ If you decide to :ref:`build-dependencies`, you will need to re-run both Once CPython is done building you will then have a working build that can be run in-place; ``./python`` on most machines (and what is used in all examples), ``./python.exe`` wherever a case-insensitive filesystem is used -(e.g. on macOS by default), in order to avoid conflicts with the ``Python`` +(for example, on macOS by default), in order to avoid conflicts with the ``Python`` directory. There is normally no need to install your built copy of Python! The interpreter will realize where it is being run from and thus use the files found in the working copy. If you are worried @@ -286,7 +286,7 @@ Windows :ref:`clone the repository ` from a native Windows shell program like PowerShell or the ``cmd.exe`` command prompt, and use a build of Git targeted for Windows, - e.g. the `Git for Windows download from the official Git website`_. + for example, the `Git for Windows download from the official Git website`_. Otherwise, Visual Studio will not be able to find all the project's files and will fail the build. @@ -375,8 +375,8 @@ host/runtime as a *guest*. To build for WASI, you will need to cross-compile CPython. This requires a C compiler just like building for :ref:`Unix ` as well as: -1. A C compiler that can target WebAssembly (e.g. `WASI SDK`_) -2. A WASI host/runtime (e.g. Wasmtime_) +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 @@ -394,7 +394,7 @@ 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 (i.e. the build Python is not meant for use by +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 @@ -608,7 +608,7 @@ for details. Install dependencies ==================== -This section explains how to install additional extensions (e.g. ``zlib``) +This section explains how to install additional extensions (for example, ``zlib``) on Linux, macOS and iOS. .. tab:: Linux @@ -635,7 +635,8 @@ on Linux, macOS and iOS. $ deb-src http://archive.ubuntu.com/ubuntu/ jammy main - Alternatively, uncomment lines with ``deb-src`` using an editor, e.g.:: + Alternatively, uncomment lines with ``deb-src`` using an editor, for + example:: $ sudo nano /etc/apt/sources.list @@ -931,7 +932,7 @@ every rule. The part of the standard library implemented in pure Python. ``Mac`` - Mac-specific code (e.g., using IDLE as a macOS application). + Mac-specific code (for example, using IDLE as a macOS application). ``Misc`` Things that do not belong elsewhere. Typically this is varying kinds of diff --git a/index.rst b/index.rst index 8f60b8f9f..c8cbc0aba 100644 --- a/index.rst +++ b/index.rst @@ -84,12 +84,12 @@ instructions please see the :ref:`setup guide `. .\python.bat -m test -j3 -5. Create a new branch where your work for the issue will go, e.g.:: +5. Create a new branch where your work for the issue will go, for example:: git checkout -b fix-issue-12345 main If an issue does not already exist, please `create it - `_. Trivial issues (e.g. 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: @@ -289,7 +289,7 @@ infrastructure is `covered `__ by the `PSF Code of Conduct `__, which includes all infrastructure used in the development of Python itself -(e.g. mailing lists, issue trackers, GitHub, etc.). +(for example, mailing lists, issue trackers, GitHub, etc.). In general this means everyone is expected to be open, considerate, and respectful of others no matter what their position is within the project. diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index 4811383fc..5b220bfe5 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -120,7 +120,7 @@ Doubly linked lists are used because they efficiently support most frequently re general, the collection of all objects tracked by GC are partitioned into disjoint sets, each in its own doubly linked list. Between collections, objects are partitioned into "generations", reflecting how often they've survived collection attempts. During collections, the generation(s) being collected -are further partitioned into, e.g., sets of reachable and unreachable objects. Doubly linked lists +are further partitioned into, for example, sets of reachable and unreachable objects. Doubly linked lists support moving an object from one partition to another, adding a new object, removing an object entirely (objects tracked by GC are most often reclaimed by the refcounting system when GC isn't running at all!), and merging partitions, all with a small constant number of pointer updates. @@ -154,7 +154,7 @@ and, during garbage collection, differentiate reachable vs. unreachable objects. Note that not all fields are to scale. ``pad`` is two bytes, ``ob_mutex`` and ``ob_gc_bits`` are each one byte, and ``ob_ref_local`` is four bytes. The other fields, ``ob_tid``, ``ob_ref_shared``, and ``ob_type``, are all -pointer-sized (i.e., eight bytes on a 64-bit platform). +pointer-sized (that is, eight bytes on a 64-bit platform). The garbage collector also temporarily repurposes the ``ob_tid`` (thread ID) @@ -181,7 +181,7 @@ Identifying reference cycles The algorithm that CPython uses to detect those reference cycles is implemented in the ``gc`` module. The garbage collector **only focuses** -on cleaning container objects (i.e. objects that can contain a reference +on cleaning container objects (that is, objects that can contain a reference to one or more objects). These can be arrays, dictionaries, lists, custom class instances, classes in extension modules, etc. One could think that cycles are uncommon but the truth is that many internal references needed by @@ -442,13 +442,13 @@ Collecting the oldest generation In addition to the various configurable thresholds, the GC only triggers a full collection of the oldest generation if the ratio ``long_lived_pending / long_lived_total`` is above a given value (hardwired to 25%). The reason is that, while "non-full" -collections (i.e., collections of the young and middle generations) will always +collections (that is, collections of the young and middle generations) will always examine roughly the same number of objects (determined by the aforementioned thresholds) the cost of a full collection is proportional to the total number of long-lived objects, which is virtually unbounded. Indeed, it has been remarked that doing a full collection every of object creations entails a dramatic performance degradation in workloads which consist -of creating and storing lots of long-lived objects (e.g. building a large list +of creating and storing lots of long-lived objects (for example, building a large list of GC-tracked objects would show quadratic performance, instead of linear as expected). Using the above ratio, instead, yields amortized linear performance in the total number of objects (the effect of which can be summarized thusly: @@ -468,7 +468,7 @@ to the size of the data, often a word or multiple thereof. This discrepancy leaves a few of the least significant bits of the pointer unused, which can be used for tags or to keep other information – most often as a bit field (each bit a separate tag) – as long as code that uses the pointer masks out these -bits before accessing memory. E.g., on a 32-bit architecture (for both +bits before accessing memory. For example, on a 32-bit architecture (for both addresses and word size), a word is 32 bits = 4 bytes, so word-aligned addresses are always a multiple of 4, hence end in ``00``, leaving the last 2 bits available; while on a 64-bit architecture, a word is 64 bits = 8 bytes, so diff --git a/internals/interpreter.rst b/internals/interpreter.rst index a53b6283c..d6feff544 100644 --- a/internals/interpreter.rst +++ b/internals/interpreter.rst @@ -32,9 +32,9 @@ Per :pep:`523`, this function is configurable by setting ``interp->eval_frame``; (This function's signature has evolved and no longer matches what PEP 523 specifies; the thread state argument is added and the stack frame argument is no longer an object.) The interpreter finds the code object by looking in the stack frame (``frame->f_code``). -Various other items needed by the interpreter (e.g. globals and builtins) are also accessed via the stack frame. +Various other items needed by the interpreter (for example, globals and builtins) are also accessed via the stack frame. The thread state stores exception information and a variety of other information, such as the recursion depth. -The thread state is also used to access per-interpreter state (``tstate->interp``) and per-runtime (i.e., truly global) state (``tstate->interp->runtime``). +The thread state is also used to access per-interpreter state (``tstate->interp``) and per-runtime (that is, truly global) state (``tstate->interp->runtime``). Note the slightly confusing terminology here. "Interpreter" refers to the bytecode interpreter, a recursive function. @@ -66,7 +66,7 @@ Bytecode is stored as an array of 16-bit code units (``_Py_CODEUNIT``). Each code unit contains an 8-bit ``opcode`` and an 8-bit argument (``oparg``), both unsigned. In order to make the bytecode format independent of the machine byte order when stored on disk, ``opcode`` is always the first byte and ``oparg`` is always the second byte. Macros are used to extract the ``opcode`` and ``oparg`` from a code unit (``_Py_OPCODE(word)`` and ``_Py_OPARG(word)``). -Some instructions (e.g. ``NOP`` or ``POP_TOP``) have no argument -- in this case we ignore ``oparg``. +Some instructions (for example, ``NOP`` or ``POP_TOP``) have no argument -- in this case we ignore ``oparg``. A simple instruction decoding loop would look like this: @@ -92,7 +92,7 @@ For example, this sequence of code units:: EXTENDED_ARG 0 LOAD_CONST 2 -would set ``opcode`` to ``LOAD_CONST`` and ``oparg`` to ``65538`` (i.e., ``0x1_00_02``). +would set ``opcode`` to ``LOAD_CONST`` and ``oparg`` to ``65538`` (that is, ``0x1_00_02``). The compiler should limit itself to at most three ``EXTENDED_ARG`` prefixes, to allow the resulting ``oparg`` to fit in 32 bits, but the interpreter does not check this. A series of code units starting with zero to three ``EXTENDED_ARG`` opcodes followed by a primary opcode is called a complete instruction, to distinguish it from a single code unit, which is always two bytes. The following loop, to be inserted just above the ``switch`` statement, will make the above snippet decode a complete instruction: @@ -125,7 +125,7 @@ Inline cache entries Some (specialized or specializable) instructions have an associated "inline cache". The inline cache consists of one or more two-byte entries included in the bytecode array as additional words following the ``opcode`` /``oparg`` pair. The size of the inline cache for a particular instruction is fixed by its ``opcode`` alone. -Moreover, the inline cache size for a family of specialized/specializable instructions (e.g., ``LOAD_ATTR``, ``LOAD_ATTR_SLOT``, ``LOAD_ATTR_MODULE``) must all be the same. +Moreover, the inline cache size for a family of specialized/specializable instructions (for example, ``LOAD_ATTR``, ``LOAD_ATTR_SLOT``, ``LOAD_ATTR_MODULE``) must all be the same. Cache entries are reserved by the compiler and initialized with zeros. If an instruction has an inline cache, the layout of its cache can be described by a ``struct`` definition and the address of the cache is given by casting ``next_instr`` to a pointer to the cache ``struct``. The size of such a ``struct`` must be independent of the machine architecture, word size and alignment requirements. @@ -133,7 +133,7 @@ For 32-bit fields, the ``struct`` should use ``_Py_CODEUNIT field[2]``. Even though inline cache entries are represented by code units, they do not have to conform to the ``opcode`` / ``oparg`` format. The instruction implementation is responsible for advancing ``next_instr`` past the inline cache. -For example, if an instruction's inline cache is four bytes (i.e., two code units) in size, the code for the instruction must contain ``next_instr += 2;``. +For example, if an instruction's inline cache is four bytes (that is, two code units) in size, the code for the instruction must contain ``next_instr += 2;``. This is equivalent to a relative forward jump by that many code units. (The proper way to code this is ``JUMPBY(n)``, where ``n`` is the number of code units to jump, typically given as a named constant.) diff --git a/internals/parser.rst b/internals/parser.rst index 9ba615013..d9378dbd7 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -566,9 +566,9 @@ Grammatical elements and rules Pegen has some special grammatical elements and rules: -* Strings with single quotes (') (e.g. ``'class'``) denote KEYWORDS. -* Strings with double quotes (") (e.g. ``"match"``) denote SOFT KEYWORDS. -* Uppercase names (e.g. ``NAME``) denote tokens in the :cpy-file:`Grammar/Tokens` file. +* Strings with single quotes (') (for example, ``'class'``) denote KEYWORDS. +* Strings with double quotes (") (for example, ``"match"``) denote SOFT KEYWORDS. +* Uppercase names (for example, ``NAME``) denote tokens in the :cpy-file:`Grammar/Tokens` file. * Rule names starting with ``invalid_`` are used for specialized syntax errors. - These rules are NOT used in the first pass of the parser. @@ -644,12 +644,12 @@ Hard and soft keywords ---------------------- .. note:: - In the grammar files, keywords are defined using **single quotes** (e.g. ``'class'``) while soft - keywords are defined using **double quotes** (e.g. ``"match"``). + In the grammar files, keywords are defined using **single quotes** (for example, ``'class'``) while soft + keywords are defined using **double quotes** (for example, ``"match"``). There are two kinds of keywords allowed in pegen grammars: *hard* and *soft* keywords. The difference between hard and soft keywords is that hard keywords -are always reserved words, even in positions where they make no sense (e.g. ``x = class + 1``), +are always reserved words, even in positions where they make no sense (for example, ``x = class + 1``), while soft keywords only get a special meaning in context. Trying to use a hard keyword as a variable will always fail: diff --git a/testing/coverage.rst b/testing/coverage.rst index 93273793a..6820a341a 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -55,10 +55,10 @@ statements have been covered. In these instances you can ignore the global statement coverage and simply focus on the local statement coverage. When writing new tests to increase coverage, do take note of the style of tests -already provided for a module (e.g., whitebox, blackbox, etc.). As +already provided for a module (for example, whitebox, blackbox, etc.). As some modules are primarily maintained by a single core developer they may have -a specific preference as to what kind of test is used (e.g., whitebox) and -prefer that other types of tests not be used (e.g., blackbox). When in doubt, +a specific preference as to what kind of test is used (for example, whitebox) and +prefer that other types of tests not be used (for example, blackbox). When in doubt, stick with whitebox testing in order to properly exercise the code. @@ -68,9 +68,9 @@ Measuring coverage It should be noted that a quirk of running coverage over Python's own stdlib is that certain modules are imported as part of interpreter startup. Those modules required by Python itself will not be viewed as executed by the coverage tools -and thus look like they have very poor coverage (e.g., the :py:mod:`stat` +and thus look like they have very poor coverage (for example, the :py:mod:`stat` module). In these instances the module will appear to not have any coverage of -global statements but will have proper coverage of local statements (e.g., +global statements but will have proper coverage of local statements (for example, function definitions will not be traced, but the function bodies will). Calculating the coverage of modules in this situation will simply require manually looking at what local statements were not executed. @@ -146,7 +146,7 @@ Basic usage ^^^^^^^^^^^ The following command will tell you if your copy of coverage works (substitute -``COVERAGEDIR`` with the directory where your clone exists, e.g. +``COVERAGEDIR`` with the directory where your clone exists, for example, ``../coveragepy``):: ./python COVERAGEDIR @@ -189,7 +189,7 @@ you visually see what lines of code were not tested:: This will generate an HTML report in a directory named ``htmlcov`` which ignores any errors that may arise and ignores modules for which test coverage is -unimportant (e.g. tests, temp files, etc.). You can then open the +unimportant (for example, tests, temp files, etc.). You can then open the ``htmlcov/index.html`` file in a web browser to view the coverage results along with pages that visibly show what lines of code were or were not executed. diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index 39742669e..820adb37d 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -199,7 +199,7 @@ idea. 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 (e.g. ``180`` for 3 minutes) + 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. diff --git a/testing/run-write-tests.rst b/testing/run-write-tests.rst index c902a99f5..719591d79 100644 --- a/testing/run-write-tests.rst +++ b/testing/run-write-tests.rst @@ -198,7 +198,7 @@ a more random order which helps to check that the various tests do not interfere with each other. The ``-w`` flag causes failing tests to be run again to see if the failures are transient or consistent. The ``-uall`` flag allows the use of all available -resources so as to not skip tests requiring, e.g., Internet access. +resources so as to not skip tests requiring, for example, Internet access. To check for reference leaks (only needed if you modified C code), use the ``-R`` flag. For example, ``-R 3:2`` will first run the test 3 times to settle diff --git a/testing/silence-warnings.rst b/testing/silence-warnings.rst index e46a11a02..81de500bf 100644 --- a/testing/silence-warnings.rst +++ b/testing/silence-warnings.rst @@ -9,7 +9,7 @@ When running Python's test suite, no warnings should result when you run it under :ref:`strenuous testing conditions ` (you can ignore the extra flags passed to ``test`` that cause randomness and parallel execution if you want). Unfortunately new warnings are added to Python on occasion which -take some time to eliminate (e.g., ``ResourceWarning``). Typically the easy +take some time to eliminate (for example, ``ResourceWarning``). Typically the easy warnings are dealt with quickly, but the more difficult ones that require some thought and work do not get fixed immediately. diff --git a/triage/triage-team.rst b/triage/triage-team.rst index 6255ea429..cef0063b6 100644 --- a/triage/triage-team.rst +++ b/triage/triage-team.rst @@ -38,7 +38,7 @@ following: - PRs proposing fixes for bugs that can no longer be reproduced - PRs proposing changes that have been rejected by Python core developers - elsewhere (e.g. in an issue or a PEP rejection notice) + elsewhere (for example, in an issue or a PEP rejection notice) If a triager has any doubt about whether to close a PR, they should consult a core developer before taking any action. diff --git a/triage/triaging.rst b/triage/triaging.rst index 1d9e8809f..d313ef70e 100644 --- a/triage/triaging.rst +++ b/triage/triaging.rst @@ -31,7 +31,7 @@ This field indicates who is expected to take the next step in resolving the issue. It is acceptable to assign an issue to someone if the issue cannot move -forward without their help; e.g., they need to make a technical decision on +forward without their help; for example, they need to make a technical decision on how to proceed. Also consult the :ref:`experts` as certain stdlib modules should always be assigned to a specific person. From 6ee39a92b3915c2ec10159454afd603b3f86f878 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 11 Jul 2024 23:17:53 -0400 Subject: [PATCH 320/538] Function signatures should use slash/star as needed (#1344) * Function signatures should use slash/star as needed * explain more about the reason to use slash/star --- documentation/style-guide.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index e28691e10..af5c88860 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -99,6 +99,7 @@ such as "for example" or "that is." .. index:: diataxis +.. _diataxis: Diátaxis ======== @@ -291,3 +292,18 @@ errors ("I made a mistake, therefore the docs must be wrong ..."). Typically, the documentation wasn't consulted until after the error was made. It is unfortunate, but typically no documentation edit would have saved the user from making false assumptions about the language ("I was surprised by ..."). + +Function signatures +=================== + +These are the evolving guidelines for how to include function signatures in the +reference guide. As outlined in :ref:`diataxis`, reference material should +prioritize precision and completeness. + +- If a function accepts positional-only or keyword-only arguments, include the + slash and the star in the signature as appropriate:: + + .. function:: some_function(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): + + Although the syntax is terse, it is precise about the allowable ways to call + the function and is taken from Python itself. From 47e18d944abbb14a8205acd90fb68faf6a99a6fb Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 16 Jul 2024 06:01:49 +0300 Subject: [PATCH 321/538] Replace custom roles with styled extlinks (#1351) --- .editorconfig | 2 +- _extensions/custom_roles.py | 43 ---------------------------------- _static/devguide_overrides.css | 11 ++++++++- conf.py | 9 +++---- internals/parser.rst | 2 +- requirements.txt | 2 +- 6 files changed, 16 insertions(+), 53 deletions(-) delete mode 100644 _extensions/custom_roles.py diff --git a/.editorconfig b/.editorconfig index 0169eed95..5230b7695 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,5 +11,5 @@ indent_size = 4 [*.rst] indent_size = 3 -[*.yml] +[*.{css,yml}] indent_size = 2 diff --git a/_extensions/custom_roles.py b/_extensions/custom_roles.py deleted file mode 100644 index f8c9bb895..000000000 --- a/_extensions/custom_roles.py +++ /dev/null @@ -1,43 +0,0 @@ -"""Sphinx extension to add custom roles. - -Based on https://protips.readthedocs.io/link-roles.html -""" -import urllib.parse - -from docutils import nodes - - -def setup(app): - # role to link to cpython files - app.add_role( - "cpy-file", - autolink("https://github.com/python/cpython/blob/main/{}"), - ) - # role to link to cpython labels - app.add_role( - "gh-label", - autolink("https://github.com/python/cpython/labels/{}"), - ) - # Parallel safety: - # https://www.sphinx-doc.org/en/master/extdev/index.html#extension-metadata - return {"parallel_read_safe": True, "parallel_write_safe": True} - - -def autolink(pattern): - def role(name, rawtext, text, lineno, inliner, _options=None, _content=None): - """Combine literal + reference (unless the text is prefixed by a !).""" - if " " in text: - url_text = urllib.parse.quote(text) - else: - url_text = text - url = pattern.format(url_text) - # don't create a reference if the text starts with ! - if text.startswith('!'): - node = nodes.literal(rawtext, text[1:]) - else: - node = nodes.reference( - rawtext, '', nodes.literal(rawtext, text), refuri=url, internal=False - ) - return [node], [] - - return role diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css index e86b6c177..9237445d2 100644 --- a/_static/devguide_overrides.css +++ b/_static/devguide_overrides.css @@ -38,7 +38,7 @@ .release-cycle-chart .release-cycle-blob { stroke-width: 1.6px; - /* default colours, overriden below for individual statuses */ + /* default colours, overridden below for individual statuses */ fill: var(--color-background-primary); stroke: var(--color-foreground-primary); } @@ -85,3 +85,12 @@ .bad pre { border-left: 3px solid rgb(244, 76, 78); } + +.extlink-cpy-file, +.extlink-gh-label { + border: 1px solid var(--color-background-border); + border-radius: .2em; + font-family: var(--font-stack--monospace); + font-size: var(--font-size--small--2); + padding: .1em .2em; +} diff --git a/conf.py b/conf.py index 6de594b23..fc46f3223 100644 --- a/conf.py +++ b/conf.py @@ -1,12 +1,6 @@ -import os -import sys import time -# Location of custom extensions. -sys.path.insert(0, os.path.abspath(".") + "/_extensions") - extensions = [ - 'custom_roles', 'notfound.extension', 'sphinx.ext.extlinks', 'sphinx.ext.intersphinx', @@ -176,7 +170,10 @@ # This config is a dictionary of external sites, # mapping unique short aliases to a base URL and a prefix. # https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html +_repo = "https://github.com/python/cpython" extlinks = { + "cpy-file": (f"{_repo}/blob/main/%s", "%s"), + "gh-label": (f"{_repo}/labels/%s", "%s"), "github": ("https://github.com/%s", "%s"), "github-user": ("https://github.com/%s", "@%s"), "pypi": ("https://pypi.org/project/%s/", "%s"), diff --git a/internals/parser.rst b/internals/parser.rst index d9378dbd7..8ad47c1f7 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -537,7 +537,7 @@ parser (the one used by the interpreter) just execute: :: make regen-pegen -using the :cpy-file:`!Makefile` in the main directory. If you are on Windows you can +using the ``Makefile`` in the main directory. If you are on Windows you can use the Visual Studio project files to regenerate the parser or to execute: :: ./PCbuild/build.bat --regen diff --git a/requirements.txt b/requirements.txt index 7b98f183d..10619e861 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~=7.3.7 +Sphinx~=7.4.0 From 7be740e6bbad2f1eac9b8d4fedb376514fc0c9d6 Mon Sep 17 00:00:00 2001 From: Tomas R Date: Tue, 16 Jul 2024 21:42:01 +0200 Subject: [PATCH 322/538] Fix broken link to LCOV (#1356) --- testing/coverage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/coverage.rst b/testing/coverage.rst index 6820a341a..d01141a7d 100644 --- a/testing/coverage.rst +++ b/testing/coverage.rst @@ -306,5 +306,5 @@ about 20 to 30 minutes on a modern computer. .. _issue tracker: https://github.com/python/cpython/issues .. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html -.. _lcov: https://ltp.sourceforge.net/coverage/lcov.php +.. _lcov: https://github.com/linux-test-project/lcov .. _coverage.py: https://coverage.readthedocs.io/en/latest/ From 890564fec0f1d495194333fa773ddce869ffd6c4 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Tue, 16 Jul 2024 16:03:27 -0500 Subject: [PATCH 323/538] Add PSRT coordination process and messaging templates (#1348) Co-authored-by: Ezio Melotti Co-authored-by: Steve Dower Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Barry Warsaw --- developer-workflow/index.rst | 1 + developer-workflow/psrt.rst | 160 +++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 developer-workflow/psrt.rst diff --git a/developer-workflow/index.rst b/developer-workflow/index.rst index 7b069021b..ca39a7275 100644 --- a/developer-workflow/index.rst +++ b/developer-workflow/index.rst @@ -14,3 +14,4 @@ Development workflow grammar porting sbom + psrt diff --git a/developer-workflow/psrt.rst b/developer-workflow/psrt.rst new file mode 100644 index 000000000..9347a9a81 --- /dev/null +++ b/developer-workflow/psrt.rst @@ -0,0 +1,160 @@ +Python Security Response Team (PSRT) +==================================== + +The Python Security Response Team (PSRT) is responsible for handling +vulnerability reports for CPython and pip. + +Vulnerability report triage +--------------------------- + +Vulnerability reports are sent to one of two locations, +the long-standing ``security@python.org`` mailing list +or using the private vulnerability reporting feature +of GitHub Security Advisories (GHSA). + +For reports sent to ``security@python.org``, a PSRT admin +will triage the report and if the report seems plausible +(that is, not spam and for the correct project) will reply with +instructions on how to report the vulnerability on GitHub. + +If the reporter doesn't want to use GitHub's Security Advisories feature +then the PSRT admins can create a draft report on behalf of the reporter. + +Coordinating a vulnerability report +----------------------------------- + +Each report will have a member of the PSRT assigned as the "coordinator". +The coordinator will be responsible for following the below process and +will be publicly credited on vulnerability records post-publication. + +If a coordinator can't complete the process for any reason (time obligation, +vacation, etc.) they must find a replacement coordinator in the PSRT +and reassign the vulnerability report appropriately. + +Coordinators are expected to collaborate with other PSRT members and core developers +when needed for guidance on whether the report is an actual vulnerability, +severity, advisory text, and fixes. + +**The vulnerability coordination process is:** + +* Coordinator will determine whether the report constitutes a vulnerability. If the report isn't a vulnerability, + the reporter should be notified appropriately. Close the GHSA report, the report can be reopened if + sufficient evidence is later obtained that the report is a vulnerability. + +* After a vulnerability report is accepted, a Common Vulnerabilities and Exposures (CVE) ID must be assigned. If this is not done + automatically, then a CVE ID can be obtained by the coordinator sending an email to ``cna@python.org``. + No details about the vulnerability report need to be shared with the PSF CVE Numbering Authority (CNA) for a CVE ID to be reserved. + +* If the report is a vulnerability, the coordinator will determine the severity of the vulnerability. Severity is one of: + **Low**, **Medium**, **High**, and **Critical**. Coordinators can use their knowledge of the code, how the code is likely used, + or another mechanism like Common Vulnerability Scoring System (CVSS) for determining a severity. Add this information to the GitHub Security Advisory. + +* Once a CVE ID is assigned, the coordinator will share the acceptance and CVE ID with the reporter. + Use this CVE ID for referencing the vulnerability. The coordinator will ask the reporter + if the reporter would like to be credited publicly for the report and if so, how they would like to be credited. + Add this information to the GitHub Security Advisory. + +* The coordinator authors the vulnerability advisory text. The advisory must include the following information: + + * Title should be a brief description of the vulnerability and affected component + (for example, "Buffer over-read in SSLContext.set_npn_protocols()") + + * Short description of the vulnerability, impact, and the conditions where the affected component is vulnerable, if applicable. + + * Affected versions. This could be "all versions", but if the vulnerability exists in a new feature + or removed feature then this could be different. Include versions that are end-of-life in this calculation + (for example, "Python 3.9 and earlier", "Python 3.10 and later", "all versions of Python"). + + * Affected components and APIs. The module, function, class, or method must be specified so users can + search their codebase for usage. For issues affecting the entire project, this can be omitted. + + * Mitigations for the vulnerability beyond upgrading to a patched version, if applicable. + + This can all be done within the GitHub Security Advisory UI for easier collaboration between reporter and coordinator. + +* The coordinator determines the fix approach and who will provide a patch. + Some reporters are willing to provide or collaborate to create a patch, + otherwise relevant core developers can be invited to collaborate by + the coordinator. + + * For **Low** and **Medium** severity vulnerabilities it is acceptable + to develop a patch in public. + The pull request must be marked with the ``security`` and ``release-blocker`` + labels so that a release is not created without including the patch. + + * For **High** and **Critical** severity vulnerabilities the patch must be + developed privately using GitHub Security Advisories' "Private Forks" feature. + Core developers can be added to the GitHub Security Advisory via "collaborators" + to work on the fix together. Once a patch is approved privately and tested, + a public issue and pull request can be created with + the ``security`` and ``release-blocker`` labels. + +* Once the pull request is merged the advisory can be published. The coordinator will send the advisory by email + to ``security-announce@python.org`` using the below template. Backport labels must be added as appropriate. + After the advisory is published a CVE record can be created. + +Template responses +------------------ + +These template responses should be used as guidance for messaging +in various points in the process above. They are not required to be sent as-is, +please feel free to adapt them as needed for the current context. + +**Directing to GitHub Security Advisories:** + +.. highlight:: none + +:: + + Thanks for submitting this report. + We use GitHub Security Advisories for triaging vulnerability reports, + are you able to submit your report directly to GitHub? + + https://github.com/python/cpython/security/advisories/new + + If you're unable to submit a report to GitHub (due to not having a GitHub + account or something else) let me know and I will create a GitHub Security + Advisory on your behalf, although you won't be able to participate directly + in discussions. + +**Rejecting a vulnerability report:** + +:: + + Thanks for your report. We've determined that the report doesn't constitute + a vulnerability. Let us know if you disagree with this determination. + If you are interested in working on this further, you can optionally open a + public issue on GitHub. + +**Accepting a vulnerability report:** + +:: + + Thanks for your report. We've determined that the report + is a vulnerability. We've assigned {CVE-YYYY-XXXX} and determined + a severity of {Low,Medium,High,Critical}. Let us know if you disagree + with the determined severity. + + If you would like to be publicly credited for this vulnerability as the + reporter, please indicate that, along with how you would like to be + credited (name or organization). + + Please keep this vulnerability report private until we've published + an advisory to ``security-announce@python.org``. + +**Advisory email:** + +:: + + Title: [{CVE-YYYY-XXXX}] {title} + + There is a {LOW, MEDIUM, HIGH, CRITICAL} severity vulnerability + affecting {project}. + + {description} + + Please see the linked CVE ID for the latest information on + affected versions: + + * https://www.cve.org/CVERecord?id={CVE-YYYY-XXXX} + * {pull request URL} From 7bd3ae67a04a7b56ef2bc97a8b56507db44c676f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 18 Jul 2024 19:34:01 +0300 Subject: [PATCH 324/538] Add Ned Batchelder to core team (#1357) --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index a87f58df2..9a6a2ee3e 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Ned Batchelder,nedbat,2024-07-16,, Michael Droetboom,mdboom,2024-06-06,, Tian Gao,gaogaotiantian,2024-06-06,, Russell Keith-Magee,freakboy3742,2024-05-30,, From c3950af5c406c548d292dab9d993e5a821dd6ffa Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 18 Jul 2024 13:02:24 -0400 Subject: [PATCH 325/538] Clarify 'time zone' in a Specific words section (#1352) * Clarify 'time zone' in a Specific words section * Use a reference that matches the section title * mention markup use for timezone --- documentation/style-guide.rst | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index af5c88860..8ebcec663 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -54,10 +54,15 @@ starting it with a lowercase letter should be avoided. Many special names are used in the Python documentation, including the names of operating systems, programming languages, standards bodies, and the like. Most of these entities are not assigned any special markup, but the preferred -spellings are given here to aid authors in maintaining the consistency of -presentation in the Python documentation. +spellings are given in :ref:`specific words` to aid authors in maintaining the +consistency of presentation in the Python documentation. -Other terms and words deserve special mention as well; these conventions should +.. _specific words: + +Specific words +============== + +Some terms and words deserve special mention. These conventions should be used to ensure consistency throughout the documentation: C API @@ -79,6 +84,12 @@ reST used to produce Python documentation. When spelled out, it is always one word and both forms start with a lowercase 'r'. +time zone + When referring to a Python term like a module, class, or argument spell it + as one word with appropriate markup (for example, ``:mod:`timezone```). + When talking about the real-world concept spell it as two words with no + markup. + Unicode The name of a character coding system. This is always written capitalized. From d2a63a9285fcd3dd53767446698273cf820dc7db Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:36:30 +0100 Subject: [PATCH 326/538] gh-119786: remove part of devguide documentation which is duplicated in InternalDocs (#1334) --- internals/interpreter.rst | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/internals/interpreter.rst b/internals/interpreter.rst index d6feff544..7405ff246 100644 --- a/internals/interpreter.rst +++ b/internals/interpreter.rst @@ -178,38 +178,15 @@ Then the interpreter function (``_PyEval_EvalFrameDefault()``) returns ``NULL``. However, if an exception is raised in a ``try`` block, the interpreter must jump to the corresponding ``except`` or ``finally`` block. In 3.10 and before, there was a separate "block stack" which was used to keep track of nesting ``try`` blocks. -In 3.11, this mechanism has been replaced by a statically generated table, ``code->co_exceptiontable``. -The advantage of this approach is that entering and leaving a ``try`` block normally does not execute any code, making execution faster. -But of course, this table needs to be generated by the compiler, and decoded (by ``get_exception_handler``) when an exception happens. - -Exception table format ----------------------- - -The table is conceptually a list of records, each containing four variable-length integer fields (in a unique format, see below): - -- start: start of ``try`` block, in code units from the start of the bytecode -- length: size of the ``try`` block, in code units -- target: start of the first instruction of the ``except`` or ``finally`` block, in code units from the start of the bytecode -- depth_and_lasti: the low bit gives the "lasti" flag, the remaining bits give the stack depth - -The stack depth is used to clean up evaluation stack entries above this depth. -The "lasti" flag indicates whether, after stack cleanup, the instruction offset of the raising instruction should be pushed (as a ``PyLongObject *``). -For more information on the design, see :cpy-file:`Objects/exception_handling_notes.txt`. - -Each varint is encoded as one or more bytes. -The high bit (bit 7) is reserved for random access -- it is set for the first varint of a record. -The second bit (bit 6) indicates whether this is the last byte or not -- it is set for all but the last bytes of a varint. -The low 6 bits (bits 0-5) are used for the integer value, in big-endian order. - -To find the table entry (if any) for a given instruction offset, we can use bisection without decoding the whole table. -We bisect the raw bytes, at each probe finding the start of the record by scanning back for a byte with the high bit set, and then decode the first varint. -See ``get_exception_handler()`` in :cpy-file:`Python/ceval.c` for the exact code (like all bisection algorithms, the code is a bit subtle). +In 3.11, this mechanism has been replaced by a statically generated table, ``code->co_exceptiontable``, +which is described in detail in the `internals documentation +`_. The locations table ------------------- Whenever an exception is raised, we add a traceback entry to the exception. -The ``tb_lineno`` field of a traceback entry must be set to the line number of the instruction that raised it. +The ``tb_lineno`` field of a traceback entry is (lazily) set to the line number of the instruction that raised it. This field is computed from the locations table, ``co_linetable`` (this name is an understatement), using :c:func:`PyCode_Addr2Line`. This table has an entry for every instruction rather than for every ``try`` block, so a compact format is very important. From 45618a95860f6a80db59f1e4b9fe3c4e25a2da5f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 4 Aug 2024 20:15:28 +0300 Subject: [PATCH 327/538] Remove GNU make-specific directive from Makefile (#1362) --- Makefile | 52 ++++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index d005d01bb..1f8e73e28 100644 --- a/Makefile +++ b/Makefile @@ -2,15 +2,17 @@ # # You can set these variables from the command line. -PYTHON = python3 -VENVDIR = ./venv -SPHINXBUILD = $(VENVDIR)/bin/sphinx-build -SPHINXOPTS = --fail-on-warning --keep-going -BUILDDIR = _build -BUILDER = html -JOBS = auto -PAPER = -SPHINXLINT = $(VENVDIR)/bin/sphinx-lint +PYTHON = python3 +VENVDIR = ./venv +UV = uv +SPHINXBUILD = $(VENVDIR)/bin/sphinx-build +SPHINXOPTS = --fail-on-warning --keep-going +BUILDDIR = _build +BUILDER = html +JOBS = auto +PAPER = +SPHINXLINT = $(VENVDIR)/bin/sphinx-lint +REQUIREMENTS = requirements.txt # Internal variables. PAPEROPT_a4 = --define latex_paper_size=a4 @@ -70,13 +72,13 @@ venv: ensure-venv: @if [ ! -d $(VENVDIR) ] ; then \ echo "Creating venv in $(VENVDIR)"; \ - if uv --version > /dev/null; then \ - uv venv $(VENVDIR); \ - VIRTUAL_ENV=$(VENVDIR) uv pip install -r requirements.txt; \ + if $(UV) --version >/dev/null 2>&1; then \ + $(UV) venv $(VENVDIR); \ + VIRTUAL_ENV=$(VENVDIR) $(UV) pip install -r $(REQUIREMENTS); \ else \ $(PYTHON) -m venv $(VENVDIR); \ $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \ - $(VENVDIR)/bin/python3 -m pip install -r requirements.txt; \ + $(VENVDIR)/bin/python3 -m pip install -r $(REQUIREMENTS); \ fi; \ echo "The venv has been created in the $(VENVDIR) directory"; \ fi @@ -180,19 +182,21 @@ check: ensure-venv # Ignore the tools and venv dirs and check that the default role is not used. $(SPHINXLINT) -i tools -i $(VENVDIR) --enable default-role -.PHONY: lint -lint: venv - if uv --version > /dev/null; then \ - $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || VIRTUAL_ENV=$(VENVDIR) uv pip install pre-commit; \ +.PHONY: _ensure-package +_ensure-package: venv + if $(UV) --version >/dev/null 2>&1; then \ + VIRTUAL_ENV=$(VENVDIR) $(UV) pip install $(PACKAGE); \ else \ - $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit; \ - fi; - $(VENVDIR)/bin/python3 -m pre_commit run --all-files + $(VENVDIR)/bin/python3 -m pip install $(PACKAGE); \ + fi -.PHONY: serve -serve: - @echo "The 'serve' target was removed, use 'htmlview' instead" \ - "(see https://github.com/python/cpython/issues/80510)" +.PHONY: _ensure-pre-commit +_ensure-pre-commit: + make _ensure-package PACKAGE=pre-commit + +.PHONY: lint +lint: _ensure-pre-commit + $(VENVDIR)/bin/python3 -m pre_commit run --all-files include/branches.csv: include/release-cycle.json $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py From 559bd1f1e3e1d8257035d3dc35b6dc9edb7c758e Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Tue, 6 Aug 2024 16:32:55 -0500 Subject: [PATCH 328/538] Request 'sethmlarson' be added as repo admin (#1363) --- developer-workflow/development-cycle.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 501df2d43..9c156abbd 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -356,6 +356,8 @@ Current administrators +-------------------+----------------------------------------------------------+-----------------+ | 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 b2d4974aad0d5082015ea9002f92815e3c71c45a Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Thu, 8 Aug 2024 16:42:39 +0200 Subject: [PATCH 329/538] Remove obsolete `serve` target from `make.bat`. (#1365) --- make.bat | 5 ----- 1 file changed, 5 deletions(-) diff --git a/make.bat b/make.bat index 64661e8d2..3358cb693 100644 --- a/make.bat +++ b/make.bat @@ -218,11 +218,6 @@ rem Ignore the tools and venv dirs and check that the default role is not used. cmd /S /C "%SPHINXLINT% -i tools -i venv --enable default-role" goto end -:serve - echo.The serve target was removed, use htmlview instead ^ -(see https://github.com/python/cpython/issues/80510) -goto end - if "%1" == "versions" ( %PYTHON% _tools/generate_release_cycle.py if errorlevel 1 exit /b 1 From 7f03e7a3f8b953e4b61a10216f06054807573ff9 Mon Sep 17 00:00:00 2001 From: Anders Lehmann Date: Fri, 9 Aug 2024 01:42:29 +0200 Subject: [PATCH 330/538] Use latest version of OenSSL (#1349) The dev guide pins the version of OpenSSL to version 3.0, but the current latest version i 3.3.1 (July 2024). The change pins the OpenSSL version to 3. --- 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 9960500e6..fc197c067 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -691,7 +691,7 @@ on Linux, macOS and iOS. For **Homebrew**, install dependencies using ``brew``:: - $ brew install pkg-config openssl@3.0 xz gdbm tcl-tk mpdecimal + $ brew install pkg-config openssl@3 xz gdbm tcl-tk mpdecimal .. tab:: Python 3.13+ @@ -701,7 +701,7 @@ on Linux, macOS and iOS. GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ ./configure --with-pydebug \ --with-system-libmpdec \ - --with-openssl="$(brew --prefix openssl@3.0)" + --with-openssl="$(brew --prefix openssl@3)" .. tab:: Python 3.11-3.12 @@ -710,7 +710,7 @@ on Linux, macOS and iOS. $ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@3.0)" + --with-openssl="$(brew --prefix openssl@3)" .. tab:: Python 3.8-3.10 @@ -719,7 +719,7 @@ on Linux, macOS and iOS. $ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ ./configure --with-pydebug \ - --with-openssl="$(brew --prefix openssl@3.0)" \ + --with-openssl="$(brew --prefix openssl@3)" \ --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ --with-tcltk-includes="$(pkg-config --cflags tcl tk)" From 63a242ff4fb5b4950e740e5a6df8389edf7116e6 Mon Sep 17 00:00:00 2001 From: Paul Ross Date: Fri, 9 Aug 2024 12:54:32 +0100 Subject: [PATCH 331/538] Exploring: Python Extension Patterns v0.2.1 now supports Python 3.9 to Python 3.13. (#1367) --- internals/exploring.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internals/exploring.rst b/internals/exploring.rst index 8f4a565fb..0ae8337e8 100644 --- a/internals/exploring.rst +++ b/internals/exploring.rst @@ -60,7 +60,7 @@ building your understanding of CPython internals and its evolution: "`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 "`Python Asynchronous I/O Walkthrough`_", "How CPython async I/O, generator and coroutine works", Philip Guo, 3.5 - "`Coding Patterns for Python Extensions`_", "Reliable patterns of coding Python Extensions in C", Paul Ross, 3.4 + "`Coding Patterns for Python Extensions`_", "Reliable patterns of coding Python Extensions in C", Paul Ross, 3.9+ "`Your Guide to the CPython Source Code`_", "Your Guide to the CPython Source Code", Anthony Shaw, 3.8 .. csv-table:: **Historical references** From d1f8560f7c086a17a426d6a52d80093ad8926d2b Mon Sep 17 00:00:00 2001 From: Udit Kumar Nayak <142026166+UditNayak@users.noreply.github.com> Date: Mon, 12 Aug 2024 09:25:18 +0530 Subject: [PATCH 332/538] Fix typo in documentation/style-guide.rst (#1368) --- documentation/style-guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index 8ebcec663..f3791f4d5 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -132,7 +132,7 @@ explanation. 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, - how-to guides make more assumptions about the user's knoweldge and + how-to guides make more assumptions about the user's knowledge and focus on the user finding the best way to solve their own particular problem. From 9526d31a88cbc9522fc885f169fa9e3f4d35611d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 12:11:05 +0100 Subject: [PATCH 333/538] Update Sphinx to 8.0.2 (#1361) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 10619e861..57755eb76 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~=7.4.0 +Sphinx~=8.0.2 From e8db12138a1ce1b239839258c6caa1de14593e80 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:51:54 +0100 Subject: [PATCH 334/538] Use ``uv`` to install packages (#1369) --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f798d074..22ad254eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,10 +13,11 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3" - cache: pip + - name: Install uv + uses: hynek/setup-cached-uv@v2 - name: Build docs run: make html - name: Link check From 9447a88d894b932916d220f0687e432c5bd81cd8 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 14 Aug 2024 13:39:52 -0700 Subject: [PATCH 335/538] Update developers.csv (#1374) --- core-developers/developers.csv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 9a6a2ee3e..3c8e6e643 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,6 +1,6 @@ Ned Batchelder,nedbat,2024-07-16,, -Michael Droetboom,mdboom,2024-06-06,, Tian Gao,gaogaotiantian,2024-06-06,, +Michael Droettboom,mdboom,2024-06-06,, Russell Keith-Magee,freakboy3742,2024-05-30,, Sam Gross,colesbury,2024-02-06,, Nikita Sobolev,sobolevn,2024-02-06,, @@ -111,7 +111,7 @@ Jeroen Ruigrok van der Werven,,2008-04-12,2017-02-10,For documentation; did not Benjamin Peterson,benjaminp,2008-03-25,,For bug triage David Wolever,wolever,2008-03-17,2020-11-21,For 2to3 module Trent Nelson,tpn,2008-03-17,2020-11-26, -Mark Dickinson,mdickinson,2008-01-06,,For maths-related work +Mark Dickinson,mdickinson,2008-01-06,2024-08-13,For maths-related work Amaury Forgeot d'Arc,amauryfa,2007-11-09,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 @@ -188,7 +188,7 @@ Just van Rossum,,1999-01-22,2017-02-10,Did not make GitHub transition Greg Ward,,1998-12-18,2017-02-10,Did not make GitHub transition Andrew Kuchling,akuchling,1998-04-09,, Ken Manheimer,,1998-03-03,2005-04-08,Privileges relinquished on 2005-04-08 -Jeremy Hylton,jeremyhylton,1997-08-13,2020-11-26, +Jeremy Hylton,jeremyhylton,1997-08-13,, Roger E. Masse,,1996-12-09,2017-02-10,Did not make GitHub transition Fred Drake,freddrake,1996-07-23,, Barry Warsaw,warsaw,1994-07-25,, From cedcb49acec877fd220c4fd642f5016c42f1bd71 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:07:44 +0100 Subject: [PATCH 336/538] Modernise the `make` templates (#1370) --- Makefile | 134 ++++++---------------------------------- make.bat | 182 +++++++++---------------------------------------------- make.ps1 | 99 ++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 271 deletions(-) create mode 100644 make.ps1 diff --git a/Makefile b/Makefile index 1f8e73e28..5503d3e15 100644 --- a/Makefile +++ b/Makefile @@ -10,50 +10,31 @@ SPHINXOPTS = --fail-on-warning --keep-going BUILDDIR = _build BUILDER = html JOBS = auto -PAPER = SPHINXLINT = $(VENVDIR)/bin/sphinx-lint REQUIREMENTS = requirements.txt # Internal variables. -PAPEROPT_a4 = --define latex_paper_size=a4 -PAPEROPT_letter = --define latex_paper_size=letter -ALLSPHINXOPTS = --builder $(BUILDER) \ - --doctree-dir $(BUILDDIR)/doctrees \ - --jobs $(JOBS) \ - $(PAPEROPT_$(PAPER)) \ - $(SPHINXOPTS) \ - . $(BUILDDIR)/$(BUILDER) +_ALL_SPHINX_OPTS = --jobs $(JOBS) $(SPHINXOPTS) +_RELEASE_CYCLE = include/branches.csv \ + include/end-of-life.csv \ + include/release-cycle.svg .PHONY: help help: @echo "Please use \`make ' where is one of" @echo " venv to create a venv with necessary tools" @echo " html to make standalone HTML files" + @echo " linkcheck to check all external links for integrity" @echo " htmlview to open the index page built by the html target in your browser" @echo " htmllive to rebuild and reload HTML files in your browser" @echo " clean to remove the venv and build files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " check to run a check for frequent markup errors" @echo " lint to lint all the files" - @echo " versions to update release cycle after changing release-cycle.json" .PHONY: clean clean: clean-venv -rm -rf $(BUILDDIR)/* + -rm -rf $(_RELEASE_CYCLE) .PHONY: clean-venv clean-venv: @@ -83,89 +64,6 @@ ensure-venv: echo "The venv has been created in the $(VENVDIR) directory"; \ fi -.PHONY: html -html: ensure-venv versions - $(SPHINXBUILD) $(ALLSPHINXOPTS) - -.PHONY: dirhtml -dirhtml: BUILDER = dirhtml -dirhtml: html - -.PHONY: singlehtml -singlehtml: BUILDER = singlehtml -singlehtml: html - -.PHONY: pickle -pickle: BUILDER = pickle -pickle: html - @echo - @echo "Build finished; now you can process the pickle files." - -.PHONY: json -json: BUILDER = json -json: html - @echo - @echo "Build finished; now you can process the JSON files." - -.PHONY: htmlhelp -htmlhelp: BUILDER = htmlhelp -htmlhelp: html - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/$(BUILDER)." - -.PHONY: qthelp -qthelp: BUILDER = qthelp -qthelp: html - -.PHONY: devhelp -devhelp: BUILDER = devhelp -devhelp: html - -.PHONY: epub -epub: BUILDER = epub -epub: html - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/$(BUILDER)." - -.PHONY: latex -latex: BUILDER = latex -latex: html - -.PHONY: latexpdf -latexpdf: BUILDER = latex -latexpdf: html - @echo "Running LaTeX files through pdflatex..." - make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/$(BUILDER)." - -.PHONY: text -text: BUILDER = text -text: html - -.PHONY: man -man: BUILDER = man -man: html - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/$(BUILDER)." - -.PHONY: changes -changes: BUILDER = changes -changes: html - -.PHONY: linkcheck -linkcheck: BUILDER = linkcheck -linkcheck: html - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/$(BUILDER)/output.txt." - -.PHONY: doctest -doctest: BUILDER = doctest -doctest: html - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/$(BUILDER)/output.txt." - .PHONY: htmlview htmlview: html $(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('_build/html/index.html'))" @@ -198,15 +96,17 @@ _ensure-pre-commit: lint: _ensure-pre-commit $(VENVDIR)/bin/python3 -m pre_commit run --all-files -include/branches.csv: include/release-cycle.json - $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py - -include/end-of-life.csv: include/release-cycle.json - $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py +# Defined so that "include/release-cycle.json" +# doesn't fall through to the catch-all target. +include/release-cycle.json: + @exit -include/release-cycle.svg: include/release-cycle.json +$(_RELEASE_CYCLE): include/release-cycle.json $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py - -.PHONY: versions -versions: venv include/branches.csv include/end-of-life.csv include/release-cycle.svg @echo Release cycle data generated. + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. +.PHONY: Makefile +%: Makefile ensure-venv $(_RELEASE_CYCLE) + $(SPHINXBUILD) -M $@ "." "$(BUILDDIR)" $(_ALL_SPHINX_OPTS) diff --git a/make.bat b/make.bat index 3358cb693..c2ba9b714 100644 --- a/make.bat +++ b/make.bat @@ -10,23 +10,9 @@ if "%PYTHON%" == "" ( set PYTHON=py -3 ) -if not defined SPHINXLINT ( - %PYTHON% -c "import sphinxlint" > nul 2> nul - if errorlevel 1 ( - echo Installing sphinx-lint with %PYTHON% - rem Should have been installed with Sphinx earlier - %PYTHON% -m pip install "sphinx-lint<1" - if errorlevel 1 exit /B - ) - set SPHINXLINT=%PYTHON% -m sphinxlint -) - set BUILDDIR=_build -set SPHINXOPTS=-W --keep-going --nitpicky -set ALLSPHINXOPTS=--doctree-dir %BUILDDIR%/doctrees %SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% -) +set SPHINXOPTS=--fail-on-warning --keep-going +set _ALL_SPHINX_OPTS=%SPHINXOPTS% if "%1" == "check" goto check @@ -60,6 +46,14 @@ if "%1" == "clean" ( goto end ) +if "%1" == "versions" ( + %PYTHON% _tools/generate_release_cycle.py + if errorlevel 1 exit /b 1 + echo. + echo Release cycle data generated. + goto end +) + rem Targets other than "clean", "check", "help", or "" need the rem Sphinx build command, which the user may define via SPHINXBUILD. @@ -75,157 +69,37 @@ if not defined SPHINXBUILD ( set SPHINXBUILD=venv\Scripts\sphinx-build ) -if "%1" == "html" ( - %SPHINXBUILD% --builder html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - if "%1" == "htmlview" ( - cmd /C %this% html - - if EXIST "%BUILDDIR%\html\index.html" ( - echo.Opening "%BUILDDIR%\html\index.html" in the default web browser... - start "" "%BUILDDIR%\html\index.html" - ) - - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% --builder dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% --builder singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% --builder pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% --builder json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% --builder htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% --builder qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PythonDevelopersGuide.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PythonDevelopersGuide.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% --builder devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% --builder epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% --builder latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) + cmd /C %this% html -if "%1" == "text" ( - %SPHINXBUILD% --builder text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% --builder man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) + if EXIST "%BUILDDIR%\html\index.html" ( + echo.Opening "%BUILDDIR%\html\index.html" in the default web browser... + start "" "%BUILDDIR%\html\index.html" + ) -if "%1" == "changes" ( - %SPHINXBUILD% --builder changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. goto end ) -if "%1" == "linkcheck" ( - %SPHINXBUILD% --builder linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) +%SPHINXBUILD% -M %1 "." %BUILDDIR% %_ALL_SPHINX_OPTS% +goto end -if "%1" == "doctest" ( - %SPHINXBUILD% --builder doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end +:check +if not defined SPHINXLINT ( + rem If it is not defined, we build in a virtual environment + if not exist venv ( + echo. Setting up the virtual environment + %PYTHON% -m venv venv + echo. Installing requirements + venv\Scripts\python -m pip install -r requirements.txt + ) + set PYTHON=venv\Scripts\python + set SPHINXLINT=%PYTHON% -m sphinxlint ) -:check rem Ignore the tools and venv dirs and check that the default role is not used. cmd /S /C "%SPHINXLINT% -i tools -i venv --enable default-role" goto end -if "%1" == "versions" ( - %PYTHON% _tools/generate_release_cycle.py - if errorlevel 1 exit /b 1 - echo. - echo Release cycle data generated. - goto end -) - :end popd endlocal diff --git a/make.ps1 b/make.ps1 new file mode 100644 index 000000000..71a8f56f4 --- /dev/null +++ b/make.ps1 @@ -0,0 +1,99 @@ +# Command file for Sphinx documentation + +param ( + [string]$target = "help" +) + +Set-StrictMode -Version 3.0 +$ErrorActionPreference = "Stop" + +$BUILDDIR = "_build" +$SPHINXOPTS = "--fail-on-warning --keep-going" +$_ALL_SPHINX_OPTS = $SPHINXOPTS + +$_PYTHON = $Env:PYTHON ?? "py -3" +$_SPHINX_BUILD = $Env:SPHINXBUILD ?? ".\venv\Scripts\sphinx-build" +$_SPHINX_LINT = $Env:SPHINXLINT ?? ".\venv\Scripts\sphinx-lint" +$_VENV_DIR = "venv" + +function New-VirtualEnviromnent +{ + Write-Host "Creating venv in $_VENV_DIR" + if (Get-Command "uv" -ErrorAction SilentlyContinue) { + & uv venv $_VENV_DIR + $Env:VIRTUAL_ENV = $_VENV_DIR + & uv pip install -r requirements.txt + Remove-Item Env:VIRTUAL_ENV + } else { + & $_PYTHON -m venv venv + Write-Host "Installing requirements" + & venv\Scripts\python -m pip install -r requirements.txt + $Script:_PYTHON = "venv\Scripts\python" + } +} + +function Invoke-SphinxBuild +{ + param ( + [string]$BuilderName, + [string]$BuildDir, + [string]$Options + ) + if (-Not (Test-Path -Path $_VENV_DIR)) { New-VirtualEnviromnent } + & $_SPHINX_BUILD -M $BuilderName "." $BuildDir $Options.Split(" ") +} + +function Invoke-Check { + if (-Not (Test-Path -Path $_VENV_DIR)) { New-VirtualEnviromnent } + & $_SPHINX_LINT -i tools -i venv --enable default-role +} + +if ($target -Eq "help") { + Write-Host "Please use `make ` where is one of" + Write-Host " venv to create a venv with necessary tools" + Write-Host " html to make standalone HTML files" + Write-Host " linkcheck to check all external links for integrity" + Write-Host " htmlview to open the index page built by the html target in your browser" + Write-Host " clean to remove the venv and build files" + Write-Host " check to check for stylistic and formal issues using sphinx-lint" + Write-Host " versions to update release cycle after changing release-cycle.json" + Exit +} + +if ($target -Eq "clean") { + $ToClean = @( + $BUILDDIR, + $_VENV_DIR, + "include/branches.csv", "include/end-of-life.csv", "include/release-cycle.svg" + ) + foreach ($item in $ToClean) { + if (Test-Path -Path $item) { + Remove-Item -Path $item -Force -Recurse + } + } + Exit $LASTEXITCODE +} + +if ($target -Eq "check") { + Invoke-Check + Exit $LASTEXITCODE +} + +if ($target -Eq "versions") { + & $_PYTHON _tools/generate_release_cycle.py + if ($LASTEXITCODE -Ne 0) { exit 1 } + Write-Host "Release cycle data generated." + Exit $LASTEXITCODE +} + +if ($target -Eq "htmlview") { + Invoke-SphinxBuild "html" "$BUILDDIR" "$_ALL_SPHINX_OPTS" + if (Test-Path -Path "$BUILDDIR\html\index.html") { + Write-Host "Opening $BUILDDIR\html\index.html in the default web browser..." + Start-Process "$BUILDDIR\html\index.html" + } + Exit $LASTEXITCODE +} + +Invoke-SphinxBuild "$target" "$BUILDDIR" "$_ALL_SPHINX_OPTS" +Exit $LASTEXITCODE From 8e00ff2804d48de9fd62c870aa54b31148efeccb Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:12:59 +0100 Subject: [PATCH 337/538] Adopt Ruff (#1372) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .flake8 | 2 -- .pre-commit-config.yaml | 38 ++++++++------------------------ .ruff.toml | 35 +++++++++++++++++++++++++++++ _tools/generate_release_cycle.py | 7 ++---- 4 files changed, 46 insertions(+), 36 deletions(-) delete mode 100644 .flake8 create mode 100644 .ruff.toml diff --git a/.flake8 b/.flake8 deleted file mode 100644 index f4546adb4..000000000 --- a/.flake8 +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max_line_length = 88 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 60ea4bc4b..ae27fd1f2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,33 +1,13 @@ repos: - - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 - hooks: - - id: pyupgrade - args: [--py38-plus] - - - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.12.1 - hooks: - - id: black - args: [--skip-string-normalization] - - - repo: https://github.com/PyCQA/isort - rev: 5.13.2 - hooks: - - id: isort - args: [--profile=black] - - - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 - hooks: - - id: flake8 - additional_dependencies: - [flake8-2020, flake8-implicit-str-concat] - - - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.10.0 - hooks: - - id: python-check-blanket-noqa + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.5.7 + hooks: + - id: ruff + name: Run Ruff (lint) + args: [--exit-non-zero-on-fix] + - id: ruff-format + name: Run Ruff (format) + args: [--check] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 000000000..550f27e61 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,35 @@ +target-version = "py311" +fix = true +output-format = "full" +line-length = 88 + +[lint] +preview = true +select = [ + "C4", # flake8-comprehensions + "B", # flake8-bugbear + "E", # pycodestyle + "F", # pyflakes + "FA", # flake8-future-annotations + "FLY", # flynt + "FURB", # refurb + "G", # flake8-logging-format + "I", # isort + "ISC", # flake8-implicit-str-concat + "LOG", # flake8-logging + "PERF", # perflint + "PGH", # pygrep-hooks + "PT", # flake8-pytest-style + "TCH", # flake8-type-checking + "UP", # pyupgrade + "W", # pycodestyle + "YTT", # flake8-2020 +] +ignore = [ + "E501", # Ignore line length errors (we use auto-formatting) +] + +[format] +preview = true +quote-style = "preserve" +docstring-code-format = true diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index 27b5cc3ec..ed27424dd 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -1,11 +1,11 @@ """Read in a JSON and generate two CSVs and an SVG file.""" + from __future__ import annotations import argparse import csv import datetime as dt import json -import sys import jinja2 @@ -45,10 +45,7 @@ def __init__(self) -> None: def write_csv(self) -> None: """Output CSV files.""" - if sys.version_info >= (3, 11): - now_str = str(dt.datetime.now(dt.UTC)) - else: - now_str = str(dt.datetime.utcnow()) + now_str = str(dt.datetime.now(dt.UTC)) versions_by_category = {"branches": {}, "end-of-life": {}} headers = None From df767646281f73ae4fd7d1f6dc6c07e28d9269f8 Mon Sep 17 00:00:00 2001 From: Kevin Bowen Date: Thu, 22 Aug 2024 23:54:42 -0700 Subject: [PATCH 338/538] Improve forking instructions (#1375) (#1376) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- getting-started/git-boot-camp.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index b5465cdb7..c857f688e 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -44,11 +44,13 @@ You will only need to do this once. 1. Go to https://github.com/python/cpython. -2. Press ``Fork`` on the top right. +2. Press ``Fork`` located near the top right of the page. -3. When asked where to fork the repository, choose to fork it to your username. +3. Uncheck the "Copy the ``main`` branch only" button. -4. Your forked CPython repository will be created at https://github.com//cpython. +4. Press the ``Create fork`` button. + +5. Your forked CPython repository will be created at ``https://github.com//cpython``. .. _clone-your-fork: @@ -105,6 +107,10 @@ To verify the upstream for ``main``:: It should emit ``upstream``, indicating to track/pull changes for ``main`` from the ``upstream`` remote. +Once this is verified, update your local clone with the upstream branches:: + + $ git fetch upstream + .. _set-up-name-email: From 94d4d6046da25cb6c4c435d13db1b94864dc059f Mon Sep 17 00:00:00 2001 From: Nate Ohlson Date: Sat, 24 Aug 2024 06:49:30 -0500 Subject: [PATCH 339/538] Add compiler warning tracking tooling failure remediation guidance (#1364) Co-authored-by: Ezio Melotti Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- development-tools/index.rst | 1 + development-tools/warnings.rst | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 development-tools/warnings.rst diff --git a/development-tools/index.rst b/development-tools/index.rst index d7b88bf6d..d62a84769 100644 --- a/development-tools/index.rst +++ b/development-tools/index.rst @@ -9,3 +9,4 @@ Development tools gdb clang coverity + warnings diff --git a/development-tools/warnings.rst b/development-tools/warnings.rst new file mode 100644 index 000000000..dc4fb197e --- /dev/null +++ b/development-tools/warnings.rst @@ -0,0 +1,51 @@ +.. warnings: + +Tools for tracking compiler warnings +==================================== + +.. highlight:: bash + +The compiler warning tracking tooling is intended to alert developers about new +compiler warnings introduced by their contributions. The tooling consists of +a Python script which is ran by the following GitHub workflows: + +* Ubuntu/build and test (:cpy-file:`.github/workflows/reusable-ubuntu.yml`) +* macOS/build and test (:cpy-file:`.github/workflows/reusable-macos.yml`) + +You can check the documentation for the :cpy-file:`Tools/build/check_warnings.py` tool +by running:: + + python Tools/build/check_warnings.py --help + +The script can be run locally by providing the compiler output file +(where the output is saved) and the compiler output type +(either ``json`` or ``clang``) to see a list of unique warnings:: + + python Tools/build/check_warnings.py --compiler-output-file-path=compiler_output.txt --compiler-output-type=json + +.. note:: The ``-fdiagnostics-format=json`` flag is required when compiling with GCC + for the script to properly parse the compiler output. + +.. _warning-check-failure: + +What to do if a warning check fails GitHub CI +--------------------------------------------- + +The :cpy-file:`Tools/build/check_warnings.py` tool will fail if the compiler generates +more or less warnings than expected for a given source file as defined in the +platform-specific warning ignore file. The warning ignore file is either +:cpy-file:`Tools/build/.warningignore_ubuntu` or +:cpy-file:`Tools/build/.warningignore_macos` depending on the platform. + +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. +* 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. From ac0391512eb3df4444f0cc0bb5fbae663f36e57c Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 26 Aug 2024 13:58:08 +0200 Subject: [PATCH 340/538] Modernize "Dynamic analysis with Clang" (GH-1378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove instructions to build from source. Clang 18.x or 20.x is much easier to get “normally” than 3.4 was, and it has its own documentation. Mention the configure options, but keep the previous instructions (seting CC/CXX) as “thorough setup”. Use the modern option name `-fsanitize-ignorelist`. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- development-tools/clang.rst | 235 +++++++++++++----------------------- 1 file changed, 81 insertions(+), 154 deletions(-) diff --git a/development-tools/clang.rst b/development-tools/clang.rst index 14040dd8b..3f62f69f3 100644 --- a/development-tools/clang.rst +++ b/development-tools/clang.rst @@ -7,9 +7,7 @@ Dynamic analysis with Clang .. highlight:: bash This document describes how to use Clang to perform analysis on Python and its -libraries. In addition to performing the analysis, the document will cover -downloading, building and installing the latest Clang/LLVM combination (which -is currently 3.4). +libraries. This document does not cover interpreting the findings. For a discussion of interpreting results, see Marshall Clow's `Testing libc++ with @@ -17,6 +15,13 @@ interpreting results, see Marshall Clow's `Testing libc++ with blog posting is a detailed examinations of issues uncovered by Clang in ``libc++``. +The document focuses on Clang, although most techniques should generally apply +to GCC's sanitizers as well. + +The instructions were tested on Linux, but they should work on macOS as well. +Instructions for Windows are incomplete. + + What is Clang? ============== @@ -49,177 +54,95 @@ A complete list of sanitizers can be found at `Controlling Code Generation Clang and its sanitizers have strengths (and weaknesses). Its just one tool in the war chest to uncovering bugs and improving code quality. Clang should be -used to compliment other methods, including Code Reviews, Valgrind, Coverity, +used to complement other methods, including Code Reviews, Valgrind, Coverity, etc. Clang/LLVM setup ================ -This portion of the document covers downloading, building and installing Clang -and LLVM. There are three components to download and build. They are the LLVM -compiler, the compiler front end and the compiler runtime library. - -In preparation you should create a scratch directory. Also ensure you are using -Python 2 and not Python 3. Python 3 will cause the build to fail. - -Download, build and install ---------------------------- - -Perform the following to download, build and install the Clang/LLVM 3.4. :: - - # Download - wget https://llvm.org/releases/3.4/llvm-3.4.src.tar.gz - wget https://llvm.org/releases/3.4/clang-3.4.src.tar.gz - wget https://llvm.org/releases/3.4/compiler-rt-3.4.src.tar.gz - - # LLVM - tar xvf llvm-3.4.src.tar.gz - cd llvm-3.4/tools +Pre-built Clang builds are available for most platforms: - # Clang Front End - tar xvf ../../clang-3.4.src.tar.gz - mv clang-3.4 clang +- On macOS, Clang is the default compiler. +- For mainstream Linux distros, you can install a ``clang`` package. + In some cases, you also need to install ``llvm`` separately, otherwise + some tools are not available. +- On Windows, the installer for Visual Studio (not Code) + includes the "C++ clang tools for windows" feature. - # Compiler RT - cd ../projects - tar xvf ../../compiler-rt-3.4.src.tar.gz - mv compiler-rt-3.4/ compiler-rt +You can also build ``clang`` from source; refer to +`the clang documentation `_ for details. - # Build - cd .. - ./configure --enable-optimized --prefix=/usr/local - make -j4 - sudo make install - -.. note:: - - If you receive an error ``'LibraryDependencies.inc' file not found``, then - ensure you are utilizing Python 2 and not Python 3. If you encounter the - error after switching to Python 2, then delete everything and start over. - -After ``make install`` executes, the compilers will be installed in -``/usr/local/bin`` and the various libraries will be installed in -``/usr/local/lib/clang/3.4/lib/linux/``: - -.. code-block:: console +The installer does not install all the components needed on occasion. For +example, you might want to run a ``scan-build`` or examine the results with +``scan-view``. If this is your case, you can build Clang from source and +copy tools from ``tools/clang/tools`` to a directory on your ``PATH``. - $ ls /usr/local/lib/clang/3.4/lib/linux/ - libclang_rt.asan-x86_64.a libclang_rt.profile-x86_64.a - libclang_rt.dfsan-x86_64.a libclang_rt.san-x86_64.a - libclang_rt.full-x86_64.a libclang_rt.tsan-x86_64.a - libclang_rt.lsan-x86_64.a libclang_rt.ubsan_cxx-x86_64.a - libclang_rt.msan-x86_64.a libclang_rt.ubsan-x86_64.a +Another reason to build from source is to get the latest version of Clang/LLVM, +if your platform's channels don't provide it yet. +Newer versions of Clang/LLVM introduce new sanitizer checks. -On macOS, the libraries are installed in -``/usr/local/lib/clang/3.3/lib/darwin/``: -.. code-block:: console +Python build setup +================== - $ ls /usr/local/lib/clang/3.3/lib/darwin/ - libclang_rt.10.4.a libclang_rt.ios.a - libclang_rt.asan_osx.a libclang_rt.osx.a - libclang_rt.asan_osx_dynamic.dylib libclang_rt.profile_ios.a - libclang_rt.cc_kext.a libclang_rt.profile_osx.a - libclang_rt.cc_kext_ios5.a libclang_rt.ubsan_osx.a - libclang_rt.eprintf.a +This portion of the document covers invoking Clang and LLVM with the options +required so the sanitizers analyze Python with under its test suite. -.. note:: +Set the compiler to Clang, in case it's not the default:: - You should never have to add the libraries to a project. Clang will handle - it for you. If you find you cannot pass the ``-fsanitize=XXX`` flag through - ``make``'s implicit variables (``CFLAGS``, ``CXXFLAGS``, ``CC``, - ``CXXFLAGS``, ``LDFLAGS``) during ``configure``, then you should modify the - makefile after configuring to ensure the flag is passed through the - compiler. + export CC="clang" -The installer does not install all the components needed on occasion. For -example, you might want to run a ``scan-build`` or examine the results with -``scan-view``. You can copy the components by hand with: :: +If you want to use additional sanitizer options (found in Clang documentation), +add them to the ``CFLAGS`` variable. +For example, you may want the checked process to exit after the first failure:: - sudo mkdir /usr/local/bin/scan-build - sudo cp -r llvm-3.4/tools/clang/tools/scan-build /usr/local/bin - sudo mkdir /usr/local/bin/scan-view - sudo cp -r llvm-3.4/tools/clang/tools/scan-view /usr/local/bin + export CFLAGS="-fno-sanitize-recover" -.. note:: +Then, run ``./configure`` with the relevant flags: - Because the installer does not install all the components needed on - occasion, you should not delete the scratch directory until you are sure - things work as expected. If a library is missing, then you should search for - it in the Clang/LLVM build directory. +* ASan: ``--with-address-sanitizer --without-pymalloc`` +* UBsan: ``--with-undefined-behavior-sanitizer`` -Python build setup -================== +It is OK to specify both sanitizers. -This portion of the document covers invoking Clang and LLVM with the options -required so the sanitizers analyze Python with under its test suite. Two -checkers are used - ASan and UBSan. +After that, run ``make`` and ``make test`` as usual. +Note that ``make`` itself may fail with a sanitizer failure, +since the just-compiled Python runs during later stages of the build. -Because the sanitizers are runtime checkers, its best to have as many positive -and negative self tests as possible. You can never have enough self tests. -The general idea is to compile and link with the sanitizer flags. At link time, -Clang will include the needed runtime libraries. However, you can't use -``CFLAGS`` and ``CXXFLAGS`` to pass the options through the compiler to the -linker because the makefile rules for ``BUILDPYTHON``, ``_testembed`` and -``_freeze_importlib`` don't use the implicit variables. +Build setup for enabling sanitizers for all code +------------------------------------------------ -As a workaround to the absence of flags to the linker, you can pass the -sanitizer options by way of the compilers - ``CC`` and ``CXX``. Passing the -flags though the compiler is used below, but passing them through ``LDFLAGS`` is -also reported to work. +Some parts of Python (for example, ``_testembed``, ``_freeze_importlib``, +``test_cppext``) may not use the variables set by ``configure``, +and with the above settings they'll be compiled without sanitization. -Building Python ---------------- +As a workaround, you can pass the sanitizer options by way of the *compilers*, +``CC`` (for C) and ``CXX`` (for C++). This is used below. +Passing the options through ``LDFLAGS`` is also reported to work. -To begin, export the variables of interest with the desired sanitizers. Its OK -to specify both sanitizers: :: +For ASan, use:: # ASan - export CC="/usr/local/bin/clang -fsanitize=address" - export CXX="/usr/local/bin/clang++ -fsanitize=address -fno-sanitize=vptr" + export CC="clang -fsanitize=address" + export CXX="clang++ -fsanitize=address -fno-sanitize=vptr" -Or: :: +And for UBSan:: # UBSan - export CC="/usr/local/bin/clang -fsanitize=undefined" - export CXX="/usr/local/bin/clang++ -fsanitize=undefined -fno-sanitize=vptr" - -The ``-fno-sanitize=vptr`` removes vtable checks that are part of UBSan from C++ -projects due to noise. Its not needed with Python, but you will likely need it -for other C++ projects. - -After exporting ``CC`` and ``CXX``, ``configure`` as normal: - -.. code-block:: console - - $ ./configure - checking build system type... x86_64-unknown-linux-gnu - checking host system type... x86_64-unknown-linux-gnu - checking for --enable-universalsdk... no - checking for --with-universal-archs... 32-bit - checking MACHDEP... linux - checking for --without-gcc... no - checking for gcc... /usr/local/bin/clang -fsanitize=undefined - checking whether the C compiler works... yes - ... + export CC="clang -fsanitize=undefined" + export CXX="clang++ -fsanitize=undefined -fno-sanitize=vptr" -Next is a standard ``make`` (formatting added for clarity): +It's OK to specify both sanitizers. -.. code-block:: console +After this, run ``./configure``, ``make`` and ``make test`` as usual. - $ make - /usr/local/bin/clang -fsanitize=undefined -c -Wno-unused-result - -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I. - -IInclude -I./Include -DPy_BUILD_CORE -o Modules/python.o - ./Modules/python.c - /usr/local/bin/clang -fsanitize=undefined -c -Wno-unused-result - -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I. - -IInclude -I./Include -DPy_BUILD_CORE -o Parser/acceler.o - Parser/acceler.c - ... -Finally is ``make test`` (formatting added for clarity): +Analyzing the output +==================== + +Sanitizer failures will make the process fail and output a diagnostic, +for example: .. code-block:: none @@ -233,8 +156,12 @@ Finally is ``make test`` (formatting added for clarity): ^ ... -If you are using the address sanitizer, its important to pipe the output through -``asan_symbolize.py`` to get a good trace. For example, from Issue 20953 during +If you are using the address sanitizer, an additional tool is needed to +get good traces. Usually, this happens automatically through the +``llvm-symbolizer`` tool. If this tool is not installed on your ``PATH``, +you can set ``ASAN_SYMBOLIZER_PATH`` to the location of the tool, +or pipe test output through ``asan_symbolize.py`` script from the +Clang distribution. For example, from Issue 20953 during compile (formatting added for clarity): .. code-block:: none @@ -302,25 +229,25 @@ compile (formatting added for clarity): .. note:: - ``asan_symbolize.py`` is supposed to be installed during ``make install``. - If its not installed, then look in the Clang/LLVM build directory for it and - copy it to ``/usr/local/bin``. + If ``asan_symbolize.py`` is not installed, build Clang from source, then + look in the Clang/LLVM build directory for it and use it directly or copy + it to a directory on ``PATH``. -Blacklisting (ignoring) findings --------------------------------- +Ignoring findings +----------------- .. highlight:: none Clang allows you to alter the behavior of sanitizer tools for certain -source-level by providing a special blacklist file at compile-time. The -blacklist is needed because it reports every instance of an issue, even if the +source-level by providing a special ignorelist file at compile-time. The +ignorelist is needed because it reports every instance of an issue, even if the issue is reported 10's of thousands of time in un-managed library code. -You specify the blacklist with ``-fsanitize-blacklist=XXX``. For example:: +You specify the ignorelist with ``-fsanitize-ignorelist=XXX``. For example:: - -fsanitize-blacklist=my_blacklist.txt + -fsanitize-ignorelist=my_ignorelist.txt -``my_blacklist.txt`` would then contain entries such as the following. The entry +``my_ignorelist.txt`` would then contain entries such as the following. The entry will ignore a bug in ``libc++``'s ``ios`` formatting functions:: fun:_Ios_Fmtflags @@ -342,7 +269,7 @@ findings:: ... One of the function of interest is ``audioop_getsample_impl`` (flagged at line -422), and the blacklist entry would include:: +422), and the ignorelist entry would include:: fun:audioop_getsample_imp @@ -350,7 +277,7 @@ Or, you could ignore the entire file with:: src:Modules/audioop.c -Unfortunately, you won't know what to blacklist until you run the sanitizer. +Unfortunately, you won't know what to ignorelist until you run the sanitizer. The documentation is available at `Sanitizer special case list `_. From 790795caec132da7eb724bd69985bf1356bb619b Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 21 Aug 2024 07:12:52 -0400 Subject: [PATCH 341/538] move style guide recommendations into devguide These are the remaining items from the (private) Editorial Board style guide suggestions: https://docs.google.com/document/d/1rSkUIGFuI5zDMYturyJCo9agYPQ-d53Z3MntSV0rB3E/edit --- documentation/style-guide.rst | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index f3791f4d5..fbf4da158 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -26,6 +26,7 @@ the footnote reference. Footnotes may appear in the middle of sentences where appropriate. + Capitalization ============== @@ -154,6 +155,7 @@ explanation. Please consult the `Diátaxis `_ guide for more detail. + Links ===== @@ -182,6 +184,7 @@ documentation for ``map``. You can suppress the link while keeping the semantic presentation of the function name by adding an exclamation point prefix: ``:func:`!map```. See :ref:`roles` for more details. + Affirmative tone ================ @@ -207,6 +210,34 @@ language): achieve the same effect. This assures that files are flushed and file descriptor resources are released in a timely manner. + +Bylines +======= + +For new documentation, do not use bylines. They tend to discourage other users +from updating community documentation. + +Existing documentation with bylines will not be changed unless the author +decides to do so. This is subject to change in the future. + + +First-person language +===================== + +Avoid first-person language. Our documentation is owned and maintained by a +community. First-person language mistakenly implies a single author. + + +Pronunciation of dunders +======================== + +"Dunder methods" like ``__init__`` can be awkward in running prose: is it "an +__init__" or "a __init__"? A `quick poll`__ indicates we should use +"an __init__." + +__ https://hachyderm.io/@nedbat/112129685322594689 + + Economy of expression ===================== @@ -218,6 +249,7 @@ to understanding and can result in even more ways to misread or misinterpret the text. Long descriptions full of corner cases and caveats can create the impression that a function is more complex or harder to use than it actually is. + Security considerations (and other concerns) ============================================ @@ -239,6 +271,7 @@ module (for example, OS level pipe buffers filling up and stalling child process these can be documented in a "Common Errors" section and cross-referenced rather than repeated for every affected interface. + .. _code-examples: Code examples @@ -259,6 +292,7 @@ lines and output lines. Besides contributing visual clutter, it makes it difficult for readers to cut-and-paste examples so they can experiment with variations. + Code equivalents ================ @@ -283,6 +317,7 @@ An example of when not to use a code equivalent is for the :func:`oct` function. The exact steps in converting a number to octal doesn't add value for a user trying to learn what the function does. + Audience ======== @@ -304,6 +339,7 @@ the documentation wasn't consulted until after the error was made. It is unfortunate, but typically no documentation edit would have saved the user from making false assumptions about the language ("I was surprised by ..."). + Function signatures =================== From 0df75a77c9d60fb7a2f151180c6ff80998f18f1b Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 21 Aug 2024 11:22:22 -0400 Subject: [PATCH 342/538] clarify what a byline is --- documentation/style-guide.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index fbf4da158..f78cd7255 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -211,11 +211,12 @@ language): descriptor resources are released in a timely manner. -Bylines -======= +Author attribution +================== -For new documentation, do not use bylines. They tend to discourage other users -from updating community documentation. +For new documentation, do not use a byline (naming the author of the document). +Explicit attribution tends to discourage other users from updating community +documentation. Existing documentation with bylines will not be changed unless the author decides to do so. This is subject to change in the future. From 756db9618e379d2f73f52047c65cc7d357b7ad5a Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 21 Aug 2024 19:31:18 -0400 Subject: [PATCH 343/538] expand on the style recommendation for dunder pronunciation --- documentation/style-guide.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index f78cd7255..ea6578c96 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -229,12 +229,13 @@ Avoid first-person language. Our documentation is owned and maintained by a community. First-person language mistakenly implies a single author. -Pronunciation of dunders -======================== +Pronunciation of dunder names +============================= -"Dunder methods" like ``__init__`` can be awkward in running prose: is it "an -__init__" or "a __init__"? A `quick poll`__ indicates we should use -"an __init__." +"Dunder names" like ``__init__`` can be awkward in running prose: is it "an +init" or "a dunder init"? Our recommendation is to ignore the underscores and +use the article that is appropriate for the word in the name. A `quick poll`__ +backs this up: "an __init__." __ https://hachyderm.io/@nedbat/112129685322594689 From b16430b449e6407e9d239b9b91b1e361e37c14d0 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 22 Aug 2024 07:34:38 -0400 Subject: [PATCH 344/538] remove 'avoid first person' for now --- documentation/style-guide.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/documentation/style-guide.rst b/documentation/style-guide.rst index ea6578c96..49bd15b1d 100644 --- a/documentation/style-guide.rst +++ b/documentation/style-guide.rst @@ -222,13 +222,6 @@ Existing documentation with bylines will not be changed unless the author decides to do so. This is subject to change in the future. -First-person language -===================== - -Avoid first-person language. Our documentation is owned and maintained by a -community. First-person language mistakenly implies a single author. - - Pronunciation of dunder names ============================= From 3cea2492f06474468636e6821236d328ba5c12ed Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 28 Aug 2024 23:21:32 +0300 Subject: [PATCH 345/538] Update hyperlink redirects (#1380) * Update hyperlink redirects * Update index.rst Co-authored-by: Ezio Melotti --------- Co-authored-by: Ezio Melotti --- .github/CODE_OF_CONDUCT.md | 2 +- .github/CONTRIBUTING.md | 2 +- core-developers/become-core-developer.rst | 2 +- core-developers/responsibilities.rst | 2 +- developer-workflow/communication-channels.rst | 2 +- getting-started/setup-building.rst | 2 +- index.rst | 4 ++-- internals/interpreter.rst | 2 +- internals/parser.rst | 2 +- testing/new-buildbot-worker.rst | 2 +- triage/triage-team.rst | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 376c78461..235382276 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -4,7 +4,7 @@ Code of Conduct Please note that all interactions on [Python Software Foundation](https://www.python.org/psf-landing/)-supported infrastructure is [covered](https://www.python.org/psf/records/board/minutes/2014-01-06/#management-of-the-psfs-web-properties) -by the [PSF Code of Conduct](https://www.python.org/psf/conduct/), +by the [PSF Code of Conduct](https://policies.python.org/python.org/code-of-conduct/), which includes all infrastructure used in the development of Python itself (for example, mailing lists, issue trackers, GitHub, etc.). diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a6bafe511..218b07b63 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -40,6 +40,6 @@ someone could take a look at your pull request. ## Code of Conduct All interactions for this project are covered by the -[PSF Code of Conduct](https://www.python.org/psf/conduct/). Everyone is +[PSF Code of Conduct](https://policies.python.org/python.org/code-of-conduct/). Everyone is expected to be open, considerate, and respectful of others no matter their position within the project. diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index 4c0251933..a97cd6bce 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -59,6 +59,6 @@ are granted through these steps: were in the form of a separate post on the already open topic with the poll. -.. _Code of Conduct: https://www.python.org/psf/conduct/ +.. _Code of Conduct: https://policies.python.org/python.org/code-of-conduct/ .. _Committers category: https://discuss.python.org/c/committers/5 .. _Python Discourse: https://discuss.python.org diff --git a/core-developers/responsibilities.rst b/core-developers/responsibilities.rst index 0638a967e..1ea1a0994 100644 --- a/core-developers/responsibilities.rst +++ b/core-developers/responsibilities.rst @@ -127,4 +127,4 @@ And finally, enjoy yourself! Contributing to open source software should be fun (overall). If you find yourself no longer enjoying the work then either take a break or figure out what you need to do to make it enjoyable again. -.. _PSF Code of Conduct: https://www.python.org/psf/conduct/ +.. _PSF Code of Conduct: https://policies.python.org/python.org/code-of-conduct/ diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 0f7970fad..5118da916 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -181,7 +181,7 @@ mailing list mode" and save changes. .. _Core Development: https://discuss.python.org/c/core-dev/23 .. _Committers: https://discuss.python.org/c/committers/5 .. _Ideas: https://discuss.python.org/c/ideas/6 -.. _Python Help: https://discuss.python.org/c/users/7 +.. _Python Help: https://discuss.python.org/c/help/7 Discord (private chat server) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index fc197c067..e0630c1b3 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -43,7 +43,7 @@ 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 `_ + `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 diff --git a/index.rst b/index.rst index c8cbc0aba..b385b1ee1 100644 --- a/index.rst +++ b/index.rst @@ -287,7 +287,7 @@ Please note that all interactions on `Python Software Foundation `__-supported infrastructure is `covered `__ -by the `PSF Code of Conduct `__, +by the `PSF Code of Conduct `__, which includes all infrastructure used in the development of Python itself (for example, mailing lists, issue trackers, GitHub, etc.). In general this means everyone is expected to be open, considerate, and @@ -322,7 +322,7 @@ Full table of contents .. _python.org maintenance: https://pythondotorg.readthedocs.io/ .. _Python: https://www.python.org/ .. _Core Python Mentorship: https://www.python.org/dev/core-mentorship/ -.. _PyPy: https://www.pypy.org +.. _PyPy: https://pypy.org .. _Jython: https://www.jython.org/ .. _IronPython: https://ironpython.net/ .. _Stackless: https://github.com/stackless-dev/stackless/wiki/ diff --git a/internals/interpreter.rst b/internals/interpreter.rst index 7405ff246..50332ac5e 100644 --- a/internals/interpreter.rst +++ b/internals/interpreter.rst @@ -190,7 +190,7 @@ The ``tb_lineno`` field of a traceback entry is (lazily) set to the line number This field is computed from the locations table, ``co_linetable`` (this name is an understatement), using :c:func:`PyCode_Addr2Line`. This table has an entry for every instruction rather than for every ``try`` block, so a compact format is very important. -The full design of the 3.11 locations table is written up in :cpy-file:`Objects/locations.md`. +The full design of the 3.11 locations table is written up in :cpy-file:`InternalDocs/locations.md`. While there are rumors that this file is slightly out of date, it is still the best reference we have. Don't be confused by :cpy-file:`Objects/lnotab_notes.txt`, which describes the 3.10 format. For backwards compatibility this format is still supported by the ``co_lnotab`` property. diff --git a/internals/parser.rst b/internals/parser.rst index 8ad47c1f7..ad97950ef 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -914,7 +914,7 @@ References https://pdos.csail.mit.edu/~baford/packrat/thesis/ .. [2] Medeiros et al. - https://arxiv.org/pdf/1207.0443.pdf + https://arxiv.org/pdf/1207.0443 .. [3] Warth et al. http://web.cs.ucla.edu/~todd/research/pepm08.pdf diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index 820adb37d..debd8df2f 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -207,7 +207,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 diff --git a/triage/triage-team.rst b/triage/triage-team.rst index cef0063b6..68a88457e 100644 --- a/triage/triage-team.rst +++ b/triage/triage-team.rst @@ -53,7 +53,7 @@ or a veteran core developer, they're actively choosing to voluntarily donate the time towards the improvement of Python. As is the case with any member of the Python Software Foundation, always follow the `PSF Code of Conduct`_. -.. _PSF Code of Conduct: https://www.python.org/psf/conduct/ +.. _PSF Code of Conduct: https://policies.python.org/python.org/code-of-conduct/ Becoming a member of the Python triage team From 3a7f5289cbc525e82c4183398c821a8dc62f3f09 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Sat, 31 Aug 2024 08:30:12 +0200 Subject: [PATCH 346/538] Add a note about translating code examples (#1382) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- documentation/translating.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/documentation/translating.rst b/documentation/translating.rst index 12aea204e..1645eb7f2 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -230,5 +230,13 @@ 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? +------------------------------------- + +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 1a5919c71b589a9408d62c0fc10f835375fe08aa Mon Sep 17 00:00:00 2001 From: Wulian <1055917385@qq.com> Date: Sat, 31 Aug 2024 17:44:08 +0800 Subject: [PATCH 347/538] Python 3.14 now is the main branch (#1383) --- core-developers/experts.rst | 1 + versions.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index f61f1439c..438d0351a 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -225,6 +225,7 @@ traceback iritkatriel tracemalloc vstinner tty Yhg1s* turtle gregorlingl^, willingc +turtledemo terryjreedy* types 1st1 typing gvanrossum, JelleZijlstra*, AlexWaygood*, carljm, sobolevn* unicodedata malemburg, ezio-melotti diff --git a/versions.rst b/versions.rst index 6ca0d440d..2606999e5 100644 --- a/versions.rst +++ b/versions.rst @@ -5,7 +5,7 @@ Status of Python versions ========================= -The ``main`` branch is currently the future Python 3.13, and is the only +The ``main`` branch is currently the future Python 3.14, and is the only branch that accepts new features. The latest release for each Python version can be found on the `download page `_. From b28b06616e2a233d42a7d68bea8d554fd253439f Mon Sep 17 00:00:00 2001 From: Hugh Secker-Walker Date: Sun, 1 Sep 2024 01:29:49 -0400 Subject: [PATCH 348/538] Note a workaround for missing system libmpdec-dev when building (#1371) --- getting-started/setup-building.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index e0630c1b3..2d6f10e3f 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -660,6 +660,8 @@ on Linux, macOS and iOS. libncurses5-dev libreadline6-dev libsqlite3-dev libssl-dev \ lzma lzma-dev tk-dev uuid-dev zlib1g-dev libmpdec-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. .. tab:: macOS From b6038680035688a3ce472601fdf5c6dd8fde1894 Mon Sep 17 00:00:00 2001 From: Lorenzo Del Signore <66021430+lorenzo-delsignore@users.noreply.github.com> Date: Mon, 2 Sep 2024 14:06:56 +0200 Subject: [PATCH 349/538] Add htmllive to make.bat (#1373) * Add htmllive * Fix typo Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> * Whitespace --------- Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com> --- make.bat | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/make.bat b/make.bat index c2ba9b714..b48678366 100644 --- a/make.bat +++ b/make.bat @@ -67,6 +67,7 @@ if not defined SPHINXBUILD ( ) set PYTHON=venv\Scripts\python set SPHINXBUILD=venv\Scripts\sphinx-build + set SPHINXAUTOBUILD=venv\Scripts\sphinx-autobuild ) if "%1" == "htmlview" ( @@ -80,6 +81,12 @@ if "%1" == "htmlview" ( goto end ) +if "%1" == "htmllive" ( + %SPHINXAUTOBUILD% --re-ignore="/\.idea/|/venv/" --open-browser --delay 0 --port 55301 . %BUILDDIR%/html + if errorlevel 1 exit /b 1 + goto end +) + %SPHINXBUILD% -M %1 "." %BUILDDIR% %_ALL_SPHINX_OPTS% goto end From ee5a793d79b5d1e7923caf1b36c6cf9ecae59c50 Mon Sep 17 00:00:00 2001 From: Panagiotis Skias Date: Mon, 9 Sep 2024 12:21:50 +0300 Subject: [PATCH 350/538] Update contacts in Greek translation (#1386) --- documentation/translating.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 1645eb7f2..bad1966ff 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -29,7 +29,8 @@ in production; others are works in progress. - :github:`GitHub ` * - Greek (gr) - Lysandros Nikolaou (:github-user:`lysnikolaou`), - Fanis Petkos (:github-user:`thepetk`) + Fanis Petkos (:github-user:`thepetk`), + Panagiotis Skias (:github-user:`skpanagiotis`) - :github:`GitHub ` * - Hindi as spoken in India (hi_IN) - Sanyam Khurana (:github-user:`CuriousLearner`) From 89254a9997838af95d499bcb430295c28917a707 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:03:31 +0300 Subject: [PATCH 351/538] Use Sphinx `guilabel` role for buttons (#1387) --- core-developers/committing.rst | 2 +- developer-workflow/communication-channels.rst | 27 +++++++++++-------- getting-started/git-boot-camp.rst | 20 +++++++------- getting-started/pull-request-lifecycle.rst | 6 ++--- triage/github-bpo-faq.rst | 8 +++--- triage/issue-tracker.rst | 2 +- 6 files changed, 35 insertions(+), 30 deletions(-) diff --git a/core-developers/committing.rst b/core-developers/committing.rst index e438d39fa..cf859ab9f 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -260,7 +260,7 @@ can apply labels to GitHub pull requests). Reverting a merged pull request ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To revert a merged pull request, press the ``Revert`` button at the +To revert a merged pull request, press the :guilabel:`Revert` button at the bottom of the pull request. That will bring up the page to create a new pull request where the commit can be reverted. It will also create a new branch on the main CPython repository. Delete the branch once diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 5118da916..60ba90339 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -98,8 +98,8 @@ Tutorials for new users To start a topic or participate in any discussions in the forum, sign up and create an account using an email address or GitHub account. You can do so by -clicking the "Sign Up" button on the top right hand corner of the `Discourse`_ -main page. +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 @@ -110,15 +110,18 @@ These tutorials can be activated by replying to a welcome message from "discours Greetings!" received under Notifications and Messages in your user account. * Click on your personal account found on the top right hand corner of the page. -* The dropdown menu will show four different icons: 🔔 (Notifications), - 🔖 (Bookmarks), ✉️ (Messages), and 👤 (Preferences). +* The dropdown menu will show four different icons: + :guilabel:`🔔` (Notifications), + :guilabel:`🔖` (Bookmarks), + :guilabel:`✉️` (Messages), and + :guilabel:`👤` (Preferences). * Select either Notifications or Messages. * Open the "Greetings!" message sent by Discobot to start the tutorial. Ensure that you read through the `Python Code of Conduct `_. We are to be open, considerate and respectful to all users in the community. You can report messages that don't respect the CoC by clicking on the three -dots under the message and then on the ⚐ icon. You can also mention the +dots under the message and then on the :guilabel:`⚐` icon. You can also mention the `@staff `_, `@moderators `_, or `@admins `_ groups in a message. @@ -126,7 +129,8 @@ dots under the message and then on the ⚐ icon. You can also mention the Reading topics ------------------ +-------------- + Click a topic title and read down the list of replies in chronological order, following links or previewing replies and quotes as you go. Use your mouse to scroll the screen, or use the timeline scroll bar on the right which also shows @@ -142,10 +146,11 @@ Following categories (category notifications) Notifications can be set for individual categories and topics. To change any of these defaults, you can either go to your user preferences, or visit the category -page, and use the notification button 🔔 above the topic list, -on the top right hand corner of the category page beside the "+ New Topic" button. +page, and use the notification button :guilabel:`🔔` above the topic list, +on the top right hand corner of the category page beside the +:guilabel:`+ New Topic` button. -Clicking on the Notification control 🔔 will show a drop-down panel with 5 +Clicking on the notification control :guilabel:`🔔` will show a drop-down panel with 5 different options: Watching, Tracking, Watching First Post, Normal, and Muted. All categories are set by default in Normal mode where you will only be notified if someone mentions your @name or replies to you. @@ -154,7 +159,7 @@ Following individual threads (topic notifications) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To follow any individual topics or threads, you can adjust your notifications -through the notification button 🔔 found on the right of the topic at the end +through the notification button :guilabel:`🔔` found on the right of the topic at the end of the timeline. You can also do so at the bottom of each topic. Select "Watching" and you will be notified when there is any new updated reply from that particular thread. @@ -235,7 +240,7 @@ Blogs Several core developers are active bloggers and discuss Python's development that way. You can find their blogs (and various other developers who use Python) -at https://planetpython.org/. +at `Planet Python `__. Setting expectations for open source participation diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index c857f688e..f28ebefbc 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -44,11 +44,11 @@ You will only need to do this once. 1. Go to https://github.com/python/cpython. -2. Press ``Fork`` located near the top right of the page. +2. Press :guilabel:`Fork` located near the top right of the page. -3. Uncheck the "Copy the ``main`` branch only" button. +3. Uncheck "Copy the ``main`` branch only". -4. Press the ``Create fork`` button. +4. Press the :guilabel:`Create fork` button. 5. Your forked CPython repository will be created at ``https://github.com//cpython``. @@ -310,7 +310,7 @@ Creating a pull request 1. Go to https://github.com/python/cpython. -2. Press the ``New pull request`` button. +2. Press the :guilabel:`New pull request` button. 3. Click the ``compare across forks`` link. @@ -319,7 +319,7 @@ Creating a pull request 5. Select the head repository: ``/cpython`` and head branch: the branch containing your changes. -6. Press the ``Create pull request`` button. +6. Press the :guilabel:`Create pull request` button. You should include the issue number in the title of the PR, in the format ``gh-NNNNN: ``. @@ -486,14 +486,14 @@ can be merged. See :ref:`"Keeping CI green" ` for some simple things you can do to help the checks turn green. At any point, a core developer can schedule an automatic merge of the change -by clicking the gray ``Enable auto-merge (squash)`` button. You will find +by clicking the gray :guilabel:`Enable auto-merge (squash)` button. You will find it at the bottom of the pull request page. The auto-merge will only happen if all the required checks pass, but the PR does not need to have been approved for a successful auto-merge to take place. If all required checks are already finished on a PR you're reviewing, -in place of the gray ``Enable auto-merge`` button you will find a green -``Squash and merge`` button. +in place of the gray :guilabel:`Enable auto-merge` button you will find a green +:guilabel:`Squash and merge` button. In either case, adjust and clean up the commit message. @@ -526,7 +526,7 @@ PR life cycle, while being irrelevant to the final change. `How to Write a Git Commit Message `_ is a nice article describing how to write a good commit message. -Finally, press the ``Confirm squash and merge`` button. +Finally, press the :guilabel:`Confirm squash and merge` button. Cancelling an automatic merge ----------------------------- @@ -535,7 +535,7 @@ If you notice a problem with a pull request that was accepted and where auto-merge was enabled, you can still cancel the workflow before GitHub automatically merges the change. -Press the gray "Disable auto-merge" button on the bottom of the +Press the gray :guilabel:`Disable auto-merge` button on the bottom of the pull request page to disable automatic merging entirely. This is the recommended approach. diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 42b341281..07416aec1 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -531,9 +531,9 @@ 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 to re-run that particular failed check. Go to the red GitHub Action job, -click on the "Re-run jobs" button on the top right, and select -"Re-run failed jobs". The button will only be present when all other jobs -finished running. +click on the :guilabel:`Re-run jobs` button on the top right, and select +:guilabel:`Re-run failed jobs`. The button will only be present when all other +jobs finished running. Re-running failed jobs shouldn't be your first instinct but it is occasionally helpful because distributed systems can have intermittent failures, and diff --git a/triage/github-bpo-faq.rst b/triage/github-bpo-faq.rst index 1385be052..8c21a17fe 100644 --- a/triage/github-bpo-faq.rst +++ b/triage/github-bpo-faq.rst @@ -57,12 +57,12 @@ Where is the "nosy list"? Subscribe another person to the issue by tagging them in the comment with ``@username``. -If you want to subscribe yourself to an issue, click the *🔔 Subscribe* -button in the sidebar. +If you want to subscribe yourself to an issue, click the +:guilabel:`🔔 Subscribe` button in the sidebar. Similarly, if you were tagged by somebody else but -decided this issue is not for you, you might click the *🔕 Unsubscribe* -button in the sidebar. +decided this issue is not for you, you might click the +:guilabel:`🔕 Unsubscribe` button in the sidebar. There is no exact equivalent of the "nosy list" feature, so to preserve this information during the transfer, we list the previous members of diff --git a/triage/issue-tracker.rst b/triage/issue-tracker.rst index c139f5d36..a38e8d9e0 100644 --- a/triage/issue-tracker.rst +++ b/triage/issue-tracker.rst @@ -50,7 +50,7 @@ Reporting an issue ------------------ If the problem you're reporting is not already in the `issue tracker`_, you -can report it using the green "New issue" button on the right of the search +can report it using the green :guilabel:`New issue` button on the right of the search box above the list of bugs. If you're not already signed in to GitHub, it will ask you to do so now. From 3070b7c08374fc2b350648c16cfa91d4d7ea61f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:33:57 +0200 Subject: [PATCH 352/538] Explain how to add an extension module (#1350) * explain how to add modules * Update extension-modules.rst * Update extension-modules.rst * Update extension-modules.rst * Update extension-modules.rst * Update extension-modules.rst * Update extension-modules.rst * Update extension-modules.rst * Update extension-modules.rst * Update extension-modules.rst * Address Hugo's feedback * Update extension-modules.rst * Update extension-modules.rst * improvements - use distinct names for files to highlight differences in configurations - be more precise on the terminology of an extension module - explain how to build a required module (always built-in) vs an optional module (built-in or dynamic) - address Ezio's review * fixup! sphinx * fixup! indents * fixup! warnings * improve sections * fix markup * improve titles * improve presentation * fixup! markup * simplify snippets * improvements * improvements * some rewordings and cleanups * simplify wording * address Erlend's review * fix indents? * add ref to clinic everywhere when needed * fix typos * address encukou's review * improve the page flow * use sentence case (that's the reason why the previous title felt wrong to me!) * add podman tip * address rest of the review * address Alyssa's review * add details * address review - Add details on `Py_BUILD_CORE_*` macros - Add tips for `Py_LIMITED_API` * Make it easier to update the required ubuntu version * fixup! * fixup! * improve comment * use double quotes instead of single quotes * Address Carol's review. --- _extensions/ubuntu_version.py | 28 + conf.py | 8 + developer-workflow/extension-modules.rst | 672 ++++++++++++++++++++++- 3 files changed, 703 insertions(+), 5 deletions(-) create mode 100644 _extensions/ubuntu_version.py diff --git a/_extensions/ubuntu_version.py b/_extensions/ubuntu_version.py new file mode 100644 index 000000000..1298f35d9 --- /dev/null +++ b/_extensions/ubuntu_version.py @@ -0,0 +1,28 @@ +"""Sphinx extension to update the required Ubuntu version. + +The required Ubuntu version should be specified in conf.py by:: + + configure_ubuntu_version = "MAJOR.MINOR" # e.g., "22.04" + +The version must match the one used to regenerate the configure script in +https://github.com/python/cpython/blob/main/Tools/build/regen-configure.sh. +""" + +from sphinx.errors import ExtensionError + + +def replace_ubuntu_version(app, docname, source): + """Replace all occurrences of $CONFIGURE_UBUNTU_VERSION$. + + This is needed since RST replacement via ``|...|`` is not supported + in code-blocks directives. + """ + if (ubuntu_version := app.config.configure_ubuntu_version) is None: + raise ExtensionError("configure_ubuntu_version is not set in conf.py") + source[0] = source[0].replace("$CONFIGURE_UBUNTU_VERSION$", ubuntu_version) + + +def setup(app): + app.add_config_value("configure_ubuntu_version", None, "env", types=(str,)) + app.connect("source-read", replace_ubuntu_version) + return {"parallel_read_safe": True, "parallel_write_safe": True} diff --git a/conf.py b/conf.py index fc46f3223..569245df0 100644 --- a/conf.py +++ b/conf.py @@ -1,6 +1,10 @@ +import sys import time +sys.path.insert(0, '_extensions') + extensions = [ + 'ubuntu_version', 'notfound.extension', 'sphinx.ext.extlinks', 'sphinx.ext.intersphinx', @@ -194,3 +198,7 @@ copybutton_prompt_text = "$ " # https://sphinx-copybutton.readthedocs.io/en/latest/use.html#honor-line-continuation-characters-when-copying-multline-snippets copybutton_line_continuation_character = "\\" + +# Must be synchronized with the Ubuntu image version in +# https://github.com/python/cpython/blob/main/Tools/build/regen-configure.sh +configure_ubuntu_version = "22.04" diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index 0384c2b38..db391357a 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -5,13 +5,675 @@ Standard library extension modules ================================== -In this section, we could explain how to write a CPython extension with the C language, but the topic can take a complete book. - -For this reason, we prefer to give you some links where you can read a very good documentation. - -Read the following references: +In this section, we explain how to configure and compile the CPython project +with a C :term:`extension module`. We will not explain how to write a C +extension module and prefer to give you some links where you can read good +documentation: * https://docs.python.org/dev/c-api/ * https://docs.python.org/dev/extending/ * :pep:`399` * https://pythonextensionpatterns.readthedocs.io/en/latest/ + +Some modules in the standard library, such as :mod:`datetime` or :mod:`pickle`, +have identical implementations in C and Python; the C implementation, when +available, is expected to improve performance (such extension modules are +commonly referred to as *accelerator modules*). + +Other modules mainly implemented in Python may import a C helper extension +providing implementation details (for instance, the :mod:`csv` module uses +the internal :mod:`!_csv` module defined in :cpy-file:`Modules/_csv.c`). + +Classifying extension modules +============================= + +Extension modules can be classified into two categories: + +* A *built-in* extension module is a module built and shipped with + the Python interpreter. A built-in module is *statically* linked + into the interpreter, thereby lacking a :attr:`__file__` attribute. + + .. seealso:: :data:`sys.builtin_module_names` --- names of built-in modules. + + Built-in modules are built with the :c:macro:`!Py_BUILD_CORE_BUILTIN` + macro defined. + +* A *shared* (or *dynamic*) extension module is built as a shared library + (``.so`` or ``.dll`` file) and is *dynamically* linked into the interpreter. + + In particular, the module's :attr:`__file__` attribute contains the path + to the ``.so`` or ``.dll`` file. + + Shared modules are built with the :c:macro:`!Py_BUILD_CORE_MODULE` + macro defined. Using the :c:macro:`!Py_BUILD_CORE_BUILTIN` macro + instead causes an :exc:`ImportError` when importing the module. + +.. note:: + + Informally, built-in extension modules can be regarded as *required* + while shared extension modules are *optional* in the sense that they + might be supplied, overridden or disabled externally. + + Usually, accelerator modules are built as *shared* extension modules, + especially if they already have a pure Python implementation. + +According to :pep:`399`, *new* extension modules MUST provide a working and +tested pure Python implementation, unless a special dispensation from +the :github:`Steering Council ` is given. + +Adding an extension module to CPython +===================================== + +Assume that the standard library contains a pure Python module :mod:`!foo` +with the following :func:`!foo.greet` function: + +.. code-block:: python + :caption: Lib/foo.py + + def greet(): + return "Hello World!" + +Instead of using the Python implementation of :func:`!foo.greet`, we want to +use its corresponding C extension implementation exposed in the :mod:`!_foo` +module. Ideally, we want to modify :cpy-file:`!Lib/foo.py` as follows: + +.. code-block:: python + :caption: Lib/foo.py + + try: + # use the C implementation if possible + from _foo import greet + except ImportError: + # fallback to the pure Python implementation + def greet(): + return "Hello World!" + +.. note:: + + Accelerator modules should *never* be imported directly. The convention is + to mark them as private implementation details with the underscore prefix + (namely, :mod:`!_foo` in this example). + +In order to incorporate the accelerator module, we need to determine: + +- where to update the CPython project tree with the extension module source code, +- which files to modify to configure and compile the CPython project, and +- which ``Makefile`` rules to invoke at the end. + +Updating the CPython project tree +--------------------------------- + +Usually, accelerator modules are added in the :cpy-file:`Modules` directory of +the CPython project. If more than one file is needed for the extension module, +it is more convenient to create a sub-directory in :cpy-file:`Modules`. + +In the simplest example where the extension module consists of one file, it may +be placed in :cpy-file:`Modules` as ``Modules/_foomodule.c``. For a non-trivial +example of the extension module :mod:`!_foo`, we consider the following working +tree: + +- :ref:`Modules/_foo/_foomodule.c` --- the extension module implementation. +- :ref:`Modules/_foo/helper.h` --- the extension helpers declarations. +- :ref:`Modules/_foo/helper.c` --- the extension helpers implementations. + +By convention, the source file containing the extension module implementation +is called ``module.c``, where ```` is the name of the module that +will be later imported (in our case :mod:`!_foo`). In addition, the directory +containing the implementation should also be named similarly. + +.. code-block:: c + :caption: Modules/_foo/helper.h + :name: Modules/_foo/helper.h + + #ifndef _FOO_HELPER_H + #define _FOO_HELPER_H + + #include "Python.h" + + typedef struct { + /* ... */ + } foomodule_state; + + static inline foomodule_state * + get_foomodule_state(PyObject *module) + { + void *state = PyModule_GetState(module); + assert(state != NULL); + return (foomodule_state *)state; + } + + /* Helper used in Modules/_foo/_foomodule.c + * but implemented in Modules/_foo/helper.c. + */ + extern PyObject * + _Py_greet_fast(void); + + #endif // _FOO_HELPER_H + +.. tip:: + + Functions or data that do not need to be shared across different C source + files should be declared ``static`` to avoid exporting their symbols from + ``libpython``. + + If symbols need to be exported, their names must start with ``Py`` or + ``_Py``. This can be verified by ``make smelly``. For more details, + please refer to the section on :ref:`Changing Python's C API `. + +.. code-block:: c + :caption: Modules/_foo/helper.c + :name: Modules/_foo/helper.c + + #include "_foomodule.h" + + PyObject *_Py_greet_fast(void) { + return PyUnicode_FromString("Hello World!"); + } + +.. code-block:: c + :caption: Modules/_foo/_foomodule.c + :name: Modules/_foo/_foomodule.c + + #include "helper.h" + #include "clinic/_foomodule.c.h" + + /* Functions for the extension module's state */ + static int + foomodule_exec(PyObject *module) + { + // imports, static attributes, exported classes, etc + return 0; + } + + static int + foomodule_traverse(PyObject *m, visitproc visit, void *arg) + { + foomodule_state *st = get_foomodule_state(m); + // call Py_VISIT() on the state attributes + return 0; + } + + static int + foomodule_clear(PyObject *m) + { + foomodule_state *st = get_foomodule_state(m); + // call Py_CLEAR() on the state attributes + return 0; + } + + static void + foomodule_free(void *m) { + (void)foomodule_clear((PyObject *)m); + } + + /* Implementation of publicly exported functions. */ + + /*[clinic input] + module foo + [clinic start generated code]*/ + /*[clinic end generated code: output=... input=...]*/ + + /*[clinic input] + foo.greet -> object + + [clinic start generated code]*/ + + static PyObject * + foo_greet_impl(PyObject *module) + /*[clinic end generated code: output=... input=...]*/ + { + return _Py_greet_fast(); + } + + /* Exported module's data */ + + static PyMethodDef foomodule_methods[] = { + // macro in 'clinic/_foomodule.c.h' after running 'make clinic' + FOO_GREET_METHODDEF + {NULL, NULL} + }; + + static struct PyModuleDef_Slot foomodule_slots[] = { + // 'foomodule_exec' may be NULL if the state is trivial + {Py_mod_exec, foomodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, + {0, NULL}, + }; + + static struct PyModuleDef foomodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_foo", + .m_doc = "some doc", // or NULL if not needed + .m_size = sizeof(foomodule_state), + .m_methods = foomodule_methods, + .m_slots = foomodule_slots, + .m_traverse = foomodule_traverse, // or NULL if the state is trivial + .m_clear = foomodule_clear, // or NULL if the state is trivial + .m_free = foomodule_free, // or NULL if the state is trivial + }; + + PyMODINIT_FUNC + PyInit__foo(void) + { + return PyModuleDef_Init(&foomodule); + } + +.. tip:: + + Recall that the ``PyInit_`` function must be suffixed by the + module name ```` used in import statements (here ``_foo``), + and which usually coincides with :c:member:`PyModuleDef.m_name`. + + Other identifiers such as those used in :ref:`Argument Clinic ` + inputs do not have such naming requirements. + +Configuring the CPython project +------------------------------- + +Now that we have added our extension module to the CPython source tree, +we need to update some configuration files in order to compile the CPython +project on different platforms. + +Updating :cpy-file:`!Modules/Setup.{bootstrap,stdlib}.in` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Depending on whether the extension module is required to get a functioning +interpreter or not, we update :cpy-file:`Modules/Setup.bootstrap.in` or +:cpy-file:`Modules/Setup.stdlib.in`. In the former case, the extension +module is necessarily built as a built-in extension module. + +.. tip:: + + For accelerator modules, :cpy-file:`Modules/Setup.stdlib.in` should be + preferred over :cpy-file:`Modules/Setup.bootstrap.in`. + +For built-in extension modules, update :cpy-file:`Modules/Setup.bootstrap.in` +by adding the following line after the ``*static*`` marker: + +.. code-block:: text + :caption: :cpy-file:`Modules/Setup.bootstrap.in` + :emphasize-lines: 3 + + *static* + ... + _foo _foo/_foomodule.c _foo/helper.c + ... + +The syntax is `` `` where ```` is the name of the +module used in :keyword:`import` statements and ```` is the list +of space-separated source files. + +For other extension modules, update :cpy-file:`Modules/Setup.stdlib.in` +by adding the following line after the ``*@MODULE_BUILDTYPE@*`` marker +but before the ``*shared*`` marker: + +.. code-block:: text + :caption: :cpy-file:`Modules/Setup.stdlib.in` + :emphasize-lines: 3 + + *@MODULE_BUILDTYPE@* + ... + @MODULE__FOO_TRUE@_foo _foo/_foomodule.c _foo/helper.c + ... + *shared* + +The ``@MODULE__TRUE@`` marker expects ```` to +be the upper-cased form of ````, where ```` has the same meaning +as before (in our case, ```` and ```` are ``_FOO`` and +``_foo`` respectively). The marker is followed by the list of source files. + +If the extension module must be built as a *shared* module, put the +``@MODULE__FOO_TRUE@_foo`` line after the ``*shared*`` marker: + +.. code-block:: text + :caption: :cpy-file:`Modules/Setup.stdlib.in` + :emphasize-lines: 4 + + ... + *shared* + ... + @MODULE__FOO_TRUE@_foo _foo/_foomodule.c _foo/helper.c + +Updating :cpy-file:`configure.ac` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. add section about configuration variable afterwards + +* Locate the ``SRCDIRS`` variable and add the following line: + + .. code-block:: text + :caption: :cpy-file:`configure.ac` + :emphasize-lines: 4 + + AC_SUBST([SRCDIRS]) + SRCDIRS="\ + ... + Modules/_foo \ + ..." + + .. note:: + + This step is only needed when adding new source directories to + the CPython project. + +* Find the section containing ``PY_STDLIB_MOD`` and ``PY_STDLIB_MOD_SIMPLE`` + usages and add the following line: + + .. code-block:: text + :caption: :cpy-file:`configure.ac` + :emphasize-lines: 3 + + dnl always enabled extension modules + ... + PY_STDLIB_MOD_SIMPLE([_foo], [-I\$(srcdir)/Modules/_foo], []) + ... + + The ``PY_STDLIB_MOD_SIMPLE`` macro takes as arguments: + + * the module name ```` used in :keyword:`import` statements, + * the compiler flags (CFLAGS), and + * the linker flags (LDFLAGS). + + If the extension module may not be enabled or supported depending on the + host configuration, use the ``PY_STDLIB_MOD`` macro instead, which takes + as arguments: + + * the module name ```` used in :keyword:`import` statements, + * a boolean indicating whether the extension is **enabled** or not, + * a boolean indicating whether the extension is **supported** or not, + * the compiler flags (CFLAGS), and + * the linker flags (LDFLAGS). + + For instance, enabling the :mod:`!_foo` extension on Linux platforms, but + only providing support for 32-bit architecture, is achieved as follows: + + .. code-block:: text + :caption: :cpy-file:`configure.ac` + :emphasize-lines: 2, 3 + + PY_STDLIB_MOD([_foo], + [test "$ac_sys_system" = "Linux"], + [test "$ARCH_RUN_32BIT" = "true"], + [-I\$(srcdir)/Modules/_foo], []) + + More generally, the host's configuration status of the extension is + determined as follows: + + +-----------+-----------------+----------+ + | Enabled | Supported | Status | + +===========+=================+==========+ + | true | true | yes | + +-----------+-----------------+----------+ + | true | false | missing | + +-----------+-----------------+----------+ + | false | true or false | disabled | + +-----------+-----------------+----------+ + + The extension status is ``n/a`` if the extension is marked unavailable + by the ``PY_STDLIB_MOD_SET_NA`` macro. To mark an extension as unavailable, + find the usages of ``PY_STDLIB_MOD_SET_NA`` in :cpy-file:`configure.ac` and + add the following line: + + .. code-block:: text + :caption: :cpy-file:`configure.ac` + :emphasize-lines: 4 + + dnl Modules that are not available on some platforms + AS_CASE([$ac_sys_system], + ... + [PLATFORM_NAME], [PY_STDLIB_MOD_SET_NA([_foo])], + ... + ) + +.. tip:: + + Consider reading the comments and configurations for existing modules + in :cpy-file:`configure.ac` for guidance on adding new external build + dependencies for extension modules that need them. + +Updating :cpy-file:`Makefile.pre.in` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If needed, add the following line to the section for module dependencies: + +.. code-block:: text + :caption: :cpy-file:`Makefile.pre.in` + :emphasize-lines: 4 + + ########################################################################## + # Module dependencies and platform-specific files + ... + MODULE__FOO_DEPS=$(srcdir)/Modules/_foo/helper.h + ... + +The ``MODULE__DEPS`` variable follows the same naming +requirements as the ``@MODULE__TRUE@`` marker. + +Updating MSVC project files +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We describe the minimal steps for compiling on Windows using MSVC. + +* Update :cpy-file:`PC/config.c`: + + .. code-block:: c + :caption: :cpy-file:`PC/config.c` + :emphasize-lines: 3, 8 + + ... + // add the entry point prototype + extern PyObject* PyInit__foo(void); + ... + // update the entry points table + struct _inittab _PyImport_Inittab[] = { + ... + {"_foo", PyInit__foo}, + ... + {0, 0} + }; + ... + + Each item in ``_PyImport_Inittab`` consists of the module name to import, + here :mod:`!_foo`, with the corresponding ``PyInit_*`` function correctly + suffixed. + +* Update :cpy-file:`PCbuild/pythoncore.vcxproj`: + + .. code-block:: xml + :caption: :cpy-file:`PCbuild/pythoncore.vcxproj` + :emphasize-lines: 4, 11-12 + + + + ... + + ... + + + + + ... + + + ... + + +* Update :cpy-file:`PCbuild/pythoncore.vcxproj.filters`: + + .. code-block:: xml + :caption: :cpy-file:`PCbuild/pythoncore.vcxproj.filters` + :emphasize-lines: 4-6, 13-18 + + + + ... + + Modules\_foo + + ... + + + + + ... + + Modules\_foo + + + Modules\_foo + + ... + + +.. tip:: + + Header files use ```` tags, whereas + source files use ```` tags. + + +Compiling the CPython project +----------------------------- + +Now that the configuration is in place, it remains to compile the project: + +.. code-block:: shell + + make regen-configure + ./configure + make regen-all + make regen-stdlib-module-names + make + +.. tip:: + + Use ``make -j`` to speed-up compilation by utilizing as many CPU cores + as possible or ``make -jN`` to allow at most *N* concurrent jobs. + +* ``make regen-configure`` updates the :cpy-file:`configure` script. + +* ``make regen-all`` is responsible for regenerating header files and + invoking other scripts, such as :ref:`Argument Clinic `. + Execute this rule if you do not know which files should be updated. + +* ``make regen-stdlib-module-names`` updates the standard module names, making + :mod:`!_foo` discoverable and importable via ``import _foo``. + +* The final ``make`` step is generally not needed since the previous ``make`` + invokations may completely rebuild the project, but it could be needed in + some specific cases. + +Troubleshooting +--------------- + +This section addresses common issues that you may face when following +this example of adding an extension module. + +No rule to make target ``regen-configure`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This usually happens after running ``make distclean`` (which removes +the ``Makefile``). The solution is to regenerate the :cpy-file:`configure` +script as follows: + +.. code-block:: shell + + ./configure # for creating the 'Makefile' file + make regen-configure # for updating the 'configure' script + ./configure # for updating the 'Makefile' file + +If missing, the :cpy-file:`configure` script can be regenerated +by executing :cpy-file:`Tools/build/regen-configure.sh`: + +.. code-block:: shell + + ./Tools/build/regen-configure.sh # create an up-to-date 'configure' + ./configure # create an up-to-date 'Makefile' + +``make regen-configure`` and missing permissions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Since this rule requires `Docker `_ to be +running, the following can be done on Linux platforms (``systemctl``-based): + +.. code-block:: shell + + systemctl status docker # is the Docker service running? + sudo systemctl start docker # start it if it is not + sudo systemctl restart docker # or restart it if the issue persists + +If Docker complains about missing permissions, this Stack Overflow post +could be useful in solving the issue: `How to fix docker: permission denied +`_. + +Once the Docker service is running, check that you have an `Ubuntu +$CONFIGURE_UBUNTU_VERSION$ image `_, +or pull it if it is not case: + +.. code-block:: shell + + # check for the Docker image presence + docker images ubuntu:$CONFIGURE_UBUNTU_VERSION$ + # pull the Docker image if needed + docker image pull ubuntu:$CONFIGURE_UBUNTU_VERSION$ + +.. tip:: + + If the issue persists, you may try `podman `_. + The commands for listing or pulling an image are the same as ``docker``. + +Missing ``Py_BUILD_CORE`` define when using internal headers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, the CPython :ref:`Stable ABI ` is exposed via +:code:`#include "Python.h"`. In some cases, this may be insufficient +and internal headers from :cpy-file:`Include/internal` are needed; +in particular, those headers require the :c:macro:`!Py_BUILD_CORE` +macro to be defined. + +To that end, one should define the :c:macro:`!Py_BUILD_CORE_BUILTIN` +or the :c:macro:`!Py_BUILD_CORE_MODULE` macro depending on whether the +extension module is built-in or shared. Using either of the two macros +implies :c:macro:`!Py_BUILD_CORE` and gives access to CPython internals: + +.. code-block:: c + :caption: Definition of :c:macro:`!Py_BUILD_CORE_BUILTIN` + + #ifndef Py_BUILD_CORE_MODULE + # define Py_BUILD_CORE_BUILTIN 1 + #endif + +.. code-block:: c + :caption: Definition of :c:macro:`!Py_BUILD_CORE_MODULE` + + #ifndef Py_BUILD_CORE_BUILTIN + # define Py_BUILD_CORE_MODULE 1 + #endif + +Tips +---- + +In this section, we give some tips for improving the quality of +extension modules meant to be included in the standard library. + +Restricting to the Limited API +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In order for non-CPython implementations to benefit from new extension modules, +it is recommended to use the :ref:`Limited API `. Instead of +exposing the entire Stable ABI, define the :c:macro:`Py_LIMITED_API` macro +*before* the :code:`#include "Python.h"` directive: + +.. code-block:: c + :caption: Using the 3.13 Limited API. + :emphasize-lines: 3, 6 + + #include "pyconfig.h" // Py_GIL_DISABLED + #ifndef Py_GIL_DISABLED + # define Py_LIMITED_API 0x030d0000 + #endif + + #include "Python.h" + +This makes the extension module non-CPython implementation-friendly by +removing the dependencies to CPython internals. From 84f480d6657dd630494bba7a45c4a3f341729b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:34:37 +0200 Subject: [PATCH 353/538] fixup RST title (#1391) --- developer-workflow/extension-modules.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index db391357a..118fe02d2 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -275,8 +275,8 @@ Now that we have added our extension module to the CPython source tree, we need to update some configuration files in order to compile the CPython project on different platforms. -Updating :cpy-file:`!Modules/Setup.{bootstrap,stdlib}.in` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Updating ``Modules/Setup.{bootstrap,stdlib}.in`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Depending on whether the extension module is required to get a functioning interpreter or not, we update :cpy-file:`Modules/Setup.bootstrap.in` or From 47d9d12ad9af7a38b5ed1b918a14fcd2eb3eec75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Fri, 13 Sep 2024 11:46:15 +0200 Subject: [PATCH 354/538] Add a template for the core developer nomination poll (#1396) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Jelle Zijlstra Co-authored-by: Victor Stinner --- core-developers/become-core-developer.rst | 45 +++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index a97cd6bce..a9460b377 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -28,11 +28,12 @@ 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 in the - `Committers category`_ on the `Python Discourse`_. +#. A core developer (submitter, usually the mentor) starts a poll + (see the :ref:`template ` below) in + the `Committers category`_ on the `Python Discourse`_. - open for 7 days - - results shown upon close + - results shown only upon closing #. If the candidate receives at least two-thirds positive votes when the poll closes (as per :pep:`13`), the submitter `emails the steering council @@ -59,6 +60,44 @@ are granted through these steps: were in the form of a separate post on the already open topic with the poll. +Poll template +============= + +.. _coredev-template: + +While Discourse uses Markdown for formatting, the poll functionality is +custom and somewhat resembles BBcode. There's a creator for polls in the +UI (click the cog icon in the edit box toolbar and choose "Build Poll"). +Here's what it outputs, you can copy and paste it for your poll: + +.. code-block:: bbcode + + [poll type=regular results=on_close public=false chartType=bar groups=committers close=2024-07-15T21:15:00.000Z] + * Promote Basil Fawlty + * Do not promote + [/poll] + +The important options in the poll builder set to get this result: + - Show who voted: **disabled** (``public=false``) + - Limit voting to these groups: **committers** (``groups=committers``) + - Automatically close poll: **in 7 days** (``close=...``) + - Show results: **When poll is closed** (``results=on_close``) + +.. raw:: html + + + .. _Code of Conduct: https://policies.python.org/python.org/code-of-conduct/ .. _Committers category: https://discuss.python.org/c/committers/5 .. _Python Discourse: https://discuss.python.org From d31db924356e0ad57e03902df4f7fd3f016be2a2 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 13 Sep 2024 20:28:53 +0100 Subject: [PATCH 355/538] Remove mdickinson from experts.rst (#1397) --- core-developers/experts.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 438d0351a..cff90478f 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -68,7 +68,7 @@ bisect rhettinger* builtins bz2 calendar -cmath mdickinson +cmath cmd code codecs malemburg, doerwalter @@ -90,7 +90,7 @@ curses Yhg1s dataclasses ericvsmith*, carljm datetime abalkin, pganssle dbm -decimal facundobatista, rhettinger, mdickinson +decimal facundobatista, rhettinger difflib tim-one (inactive) dis 1st1 doctest tim-one (inactive) @@ -104,7 +104,7 @@ fcntl Yhg1s filecmp fileinput fnmatch -fractions mdickinson +fractions ftplib giampaolo* functools rhettinger* gc pitrou, pablogsal @@ -137,7 +137,7 @@ logging vsajip lzma mailbox marshal -math mdickinson, rhettinger, stutzbach^ +math rhettinger, stutzbach^ mimetypes mmap Yhg1s modulefinder theller (inactive), jvr^ @@ -174,7 +174,7 @@ pyclbr isidentical pydoc AA-Turner queue rhettinger* quopri -random rhettinger, mdickinson +random rhettinger re ezio-melotti, serhiy-storchaka readline Yhg1s reprlib @@ -201,7 +201,7 @@ stat tiran statistics stevendaprano, rhettinger string stringprep -struct mdickinson, meadori +struct meadori subprocess astrand^ (inactive), giampaolo, gpshead* symtable benjaminp sys @@ -321,7 +321,7 @@ context managers ncoghlan core workflow Mariatta, ezio-melotti, hugovk, AA-Turner coverity scan tiran, Yhg1s cryptography gpshead, dstufft -data formats mdickinson +data formats database malemburg devguide merwok, ezio-melotti, willingc, Mariatta, hugovk, AA-Turner @@ -338,7 +338,7 @@ import machinery brettcannon, ncoghlan, ericsnowcurrently io benjaminp, stutzbach^, gpshead JIT brandtbucher* locale malemburg -mathematics mdickinson, malemburg, stutzbach^, rhettinger +mathematics malemburg, stutzbach^, rhettinger memory management tim-one, malemburg, Yhg1s memoryview networking giampaolo, gpshead From d493655277198789fa70b9e3b91b9e84af0398c6 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:28:49 +0300 Subject: [PATCH 356/538] Fix linkcheck (#1398) * Don't linkcheck stackoverflow.com, it's rate limited and times out * Fix XZ link post-backdoor --- conf.py | 4 +++- getting-started/setup-building.rst | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index 569245df0..44e625a83 100644 --- a/conf.py +++ b/conf.py @@ -105,8 +105,10 @@ r'https://github.com/python/bedevere/#pr-state-machine', # "Anchor not found": r'https://packaging.python.org/.*#', + # "-rate limited-", causing a timeout + r'https://stackoverflow.com/.*', # Discord doesn't allow robot crawlers: "403 Client Error: Forbidden" - r'https://support.discord.com/hc/en-us/articles/219070107-Server-Nicknames', + 'https://support.discord.com/hc/en-us/articles/219070107-Server-Nicknames', ] rediraffe_redirects = { diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 2d6f10e3f..8d432f0c0 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -779,7 +779,7 @@ on Linux, macOS and iOS. As with CPython itself, the dependencies for CPython must be compiled for each of the hardware architectures that iOS supports. Consult the - documentation for `XZ `__, `bzip2 + documentation for `XZ `__, `bzip2 `__, `OpenSSL `__ and `libffi `__ for details on how to configure the project for cross-platform iOS builds. From 22bfaedb5b92a79f8502a3dd33d636c43e08d4ab Mon Sep 17 00:00:00 2001 From: Nate Ohlson Date: Wed, 18 Sep 2024 02:50:32 -0500 Subject: [PATCH 357/538] Warning ignore file modification guidance for check warning tooling (#1399) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- development-tools/warnings.rst | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/development-tools/warnings.rst b/development-tools/warnings.rst index dc4fb197e..b6448f397 100644 --- a/development-tools/warnings.rst +++ b/development-tools/warnings.rst @@ -19,12 +19,9 @@ by running:: The script can be run locally by providing the compiler output file (where the output is saved) and the compiler output type -(either ``json`` or ``clang``) to see a list of unique warnings:: +(either ``gcc`` or ``clang``) to see a list of unique warnings:: - python Tools/build/check_warnings.py --compiler-output-file-path=compiler_output.txt --compiler-output-type=json - -.. note:: The ``-fdiagnostics-format=json`` flag is required when compiling with GCC - for the script to properly parse the compiler output. + python Tools/build/check_warnings.py --compiler-output-file-path=compiler_output.txt --compiler-output-type=gcc .. _warning-check-failure: @@ -49,3 +46,21 @@ If a warning check fails with: * 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: + +Updating the warning ignore file +-------------------------------- + +The warning ignore files can be found in the :cpy-file:`Tools/build/` directory. +Both files and directories can be added to the ignore file. Files can have an explicit warning count or a wildcard count. +Directories must be followed by a wildcard count. Wildcards indicate that 0 or more warnings will be ignored. +The following is an example of the warning ignore file format:: + + Modules/_ctypes/_ctypes_test_generated.c.h * + Objects/longobject.c 46 + Objects/methodobject.c 1 + Objects/mimalloc/ * + +Using wildcards is reserved for code that is not maintained by CPython, or code that is for tests. +Keep lines in warning ignore files sorted lexicographically. From da98447c6cc770bae127f453d5bcac766f90067d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 19 Sep 2024 02:39:27 +0300 Subject: [PATCH 358/538] Add guidance about the 'Update branch' button (#1392) --- getting-started/pull-request-lifecycle.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 07416aec1..cd037789f 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -542,6 +542,22 @@ If you identify such flaky behavior, look for an issue in the `issue tracker`_ that describes this particular flakiness. Create a new issue if you can't find one. +:guilabel:`Update branch` button +================================ + +You can click on the :guilabel:`Update branch` button to merge the latest +changes from the base branch (usually ``main``) into the PR. +This is useful to :ref:`keep the CI green ` for old PRs, +or to check if a CI failure has been fixed in the base branch. + +If the PR is very old, it may be useful to update the branch before merging to +ensure that the PR does not fail any CI checks that were added or changed since +CI last ran. + +Do not click :guilabel:`Update branch` without a good reason because it notifies +everyone watching the PR that there are new changes, when there are not, +and it uses up limited CI resources. + Committing/rejecting ==================== From 9ef77025d3fa2ec81e5d0a23a57e007ef70be7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20C=C3=A1rdenas?= <78029302+miguelcsx@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:39:04 -0500 Subject: [PATCH 359/538] Clarify the documentation update process (#1395) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- documentation/devguide.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/documentation/devguide.rst b/documentation/devguide.rst index a17ed342a..7c53d054e 100644 --- a/documentation/devguide.rst +++ b/documentation/devguide.rst @@ -19,10 +19,12 @@ main Python documentation, except for some small differences. The source lives in a `separate repository`_ and bug reports should be submitted to the `devguide GitHub tracker`_. -Our devguide workflow uses continuous integration and deployment so changes to -the devguide are normally published when the pull request is merged. Changes -to CPython documentation follow the workflow of a CPython release and are -published in the release. +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 `_, +which may also be used by redistributors. Developer's Guide workflow From 7eac98a877f3aa5819c70e26b0483f46096250c4 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 19 Sep 2024 06:46:32 +0100 Subject: [PATCH 360/538] Require sphinx-autobuild>=2024.9.19 (#1400) --- Makefile | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5503d3e15..5f9e96546 100644 --- a/Makefile +++ b/Makefile @@ -72,7 +72,7 @@ htmlview: html htmllive: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild # Arbitrarily selected ephemeral port between 49152–65535 # to avoid conflicts with other processes: -htmllive: SPHINXOPTS = --re-ignore="/\.idea/|/venv/" --open-browser --delay 0 --port 55301 +htmllive: SPHINXOPTS = --open-browser --delay 0 --port 55301 htmllive: html .PHONY: check diff --git a/requirements.txt b/requirements.txt index 57755eb76..fd04efd8c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ furo>=2022.6.4 jinja2 -sphinx-autobuild +sphinx-autobuild>=2024.9.19 sphinx-inline-tabs>=2023.4.21 sphinx-lint==0.9.1 sphinx-notfound-page>=1.0.0 From 8fcb7a5ccc96751299cb2e8bf5c8ad4fa8eaeb59 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 19 Sep 2024 19:56:34 +0200 Subject: [PATCH 361/538] Experts list: update David Edelsohn's user name (#1401) David Edelsohn still wants to be notified of AIX issues, see: https://github.com/python/cpython/issues/82809#issuecomment-2361112194 Update to his GitHub username. --- 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 cff90478f..77af366e6 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -286,7 +286,7 @@ for “their” platform as a third-party project. =================== =========== Platform Maintainers =================== =========== -AIX David.Edelsohn^ +AIX edelsohn Android mhsmith Cygwin jlt63^, stutzbach^ Emscripten hoodmane, pmp-p, rdb, rth, ryanking13 From 8bf6312bdfc67fcab2ede7262002ab9b5f92047b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Sat, 21 Sep 2024 04:33:58 +0200 Subject: [PATCH 362/538] Add Kirill Podoprigora to core developers (#1405) Co-authored-by: Kirill Podoprigora --- core-developers/developers.csv | 1 + core-developers/experts.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 3c8e6e643..3808e76c9 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Kirill Podoprigora,Eclips4,2024-09-20,, Ned Batchelder,nedbat,2024-07-16,, Tian Gao,gaogaotiantian,2024-06-06,, Michael Droettboom,mdboom,2024-06-06,, diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 77af366e6..61ad86b8e 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -58,7 +58,7 @@ _thread abc argparse array -ast benjaminp, pablogsal, isidentical, JelleZijlstra +ast benjaminp, pablogsal, isidentical, JelleZijlstra, eclips4 asyncio 1st1, asvetlov, gvanrossum, graingert, kumaraditya303, willingc atexit base64 From 4ae370793b97d03f733d542bd74bdf63a2e3c00b Mon Sep 17 00:00:00 2001 From: Malcolm Smith Date: Tue, 24 Sep 2024 19:38:35 +0100 Subject: [PATCH 363/538] Add Android instructions to the devguide (GH-1402) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- getting-started/setup-building.rst | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 8d432f0c0..0c0e28691 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -458,6 +458,12 @@ used in ``python.sh``: .. _wasmtime: https://wasmtime.dev .. _WebAssembly: https://webassembly.org +Android +------- + +Build and test instructions for Android are maintained in the CPython repository +at :cpy-file:`Android/README.md`. + iOS --- @@ -608,8 +614,8 @@ for details. Install dependencies ==================== -This section explains how to install additional extensions (for example, ``zlib``) -on Linux, macOS and iOS. +This section explains how to install libraries which are needed to compile +some of CPython's modules (for example, ``zlib``). .. tab:: Linux @@ -775,6 +781,16 @@ on Linux, macOS and iOS. On Windows, extensions are already included and built automatically. +.. tab:: Android + + The BeeWare project maintains `scripts for building Android dependencies`_, + and distributes `pre-compiled binaries`_ for each of them. + These binaries are automatically downloaded and used by the CPython + build script at :cpy-file:`Android/android.py`. + + .. _scripts for building Android dependencies: https://github.com/beeware/cpython-android-source-deps + .. _pre-compiled binaries: https://github.com/beeware/cpython-android-source-deps/releases + .. tab:: iOS As with CPython itself, the dependencies for CPython must be compiled for From 009574812e266f870a360e694215d8c67008908a Mon Sep 17 00:00:00 2001 From: Mariatta Date: Tue, 24 Sep 2024 13:14:39 -0700 Subject: [PATCH 364/538] Remove coverity from the DevGuide (#1411) * Remove coverity * Update conf.py * Link to valgrind doc on CPython repo. * Update development-tools/clang.rst Co-authored-by: Jelle Zijlstra --- conf.py | 2 - core-developers/experts.rst | 1 - development-tools/clang.rst | 4 +- development-tools/coverity.rst | 141 --------------------------------- development-tools/index.rst | 1 - 5 files changed, 3 insertions(+), 146 deletions(-) delete mode 100644 development-tools/coverity.rst diff --git a/conf.py b/conf.py index 44e625a83..64d7c68b9 100644 --- a/conf.py +++ b/conf.py @@ -114,11 +114,9 @@ rediraffe_redirects = { # Development Tools "clang.rst": "development-tools/clang.rst", - "coverity.rst": "development-tools/coverity.rst", "gdb.rst": "development-tools/gdb.rst", # Advanced Tools was renamed Development Tools in gh-1149 "advanced-tools/clang.rst": "development-tools/clang.rst", - "advanced-tools/coverity.rst": "development-tools/coverity.rst", "advanced-tools/gdb.rst": "development-tools/gdb.rst", # Core Developers "coredev.rst": "core-developers/become-core-developer.rst", diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 61ad86b8e..950efc656 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -319,7 +319,6 @@ buildbots zware, pablogsal bytecode benjaminp, 1st1, markshannon, brandtbucher, carljm, iritkatriel context managers ncoghlan core workflow Mariatta, ezio-melotti, hugovk, AA-Turner -coverity scan tiran, Yhg1s cryptography gpshead, dstufft data formats database malemburg diff --git a/development-tools/clang.rst b/development-tools/clang.rst index 3f62f69f3..f06834731 100644 --- a/development-tools/clang.rst +++ b/development-tools/clang.rst @@ -54,7 +54,7 @@ A complete list of sanitizers can be found at `Controlling Code Generation Clang and its sanitizers have strengths (and weaknesses). Its just one tool in the war chest to uncovering bugs and improving code quality. Clang should be -used to complement other methods, including Code Reviews, Valgrind, Coverity, +used to complement other methods, including Code Reviews, `Valgrind`_, etc. Clang/LLVM setup @@ -281,3 +281,5 @@ 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/coverity.rst b/development-tools/coverity.rst deleted file mode 100644 index 7c165a312..000000000 --- a/development-tools/coverity.rst +++ /dev/null @@ -1,141 +0,0 @@ -.. _coverity: - -============= -Coverity Scan -============= - -Coverity Scan is a free service for static code analysis of Open Source -projects. It is based on Coverity's commercial product and is able to analyze -C, C++ and Java code. - -Coverity's static code analysis doesn't run the code. Instead of that it uses -abstract interpretation to gain information about the code's control flow and -data flow. It's able to follow all possible code paths that a program may -take. For example the analyzer understands that ``malloc()`` returns a memory -that must be freed with ``free()`` later. It follows all branches and function -calls to see if all possible combinations free the memory. The analyzer is -able to detect all sorts of issues like resource leaks (memory, file -descriptors), NULL dereferencing, use after free, unchecked return values, -dead code, buffer overflows, integer overflows, uninitialized variables, and -many more. - - -Access to analysis reports -========================== - -The results are available on the `Coverity Scan`_ website. In order to -access the results you have to create an account yourself. Then go to -*Projects using Scan* and add yourself to the Python project. New members must -be approved by an admin (see `Contact`_). - -Access is restricted to Python core developers only. Other individuals may be -given access at our own discretion, too. Every now and then Coverity detects a -critical issue in Python's code -- new analyzers may even find new bugs in -mature code. We don't want to disclose issues prematurely. - - -Building and uploading analysis -=============================== - -The process is automated. A script checks out the code, runs -``cov-build`` and uploads the latest analysis to Coverity. Since Coverity has -limited the maximum number of builds per week Python is analyzed every second -day. The build runs on a dedicated virtual machine on PSF's infrastructure at -OSU Open Source Labs. The process is maintained by Christian Heimes (see -`Contact`_). At present only the tip is analyzed with the 64bit Linux tools. - - -Known limitations -================= - -Some aspects of Python's C code are not yet understood by Coverity. - -False positives ---------------- - -``Py_BuildValue("N", PyObject*)`` - Coverity doesn't understand that ``N`` format char passes the object along - without touching its reference count. On this ground the analyzer detects - a resource leak. CID 719685 - -``PyLong_FromLong()`` for negative values - Coverity claims that ``PyLong_FromLong()`` and other ``PyLong_From*()`` - functions cannot handle a negative value because the value might be used as - an array index in ``get_small_int()``. CID 486783 - -``PyLong_FromLong()`` for n in [-5 ... +255] - For integers in the range of Python's small int cache the ``PyLong_From*()`` - function can never fail and never returns NULL. CID 1058291 - -``PyArg_ParseTupleAndKeywords(args, kwargs, "s#", &data, &length)`` - Some functions use the format char combination such as ``s#``, ``u#`` or - ``z#`` to get data and length of a character array. Coverity doesn't - recognize the relation between data and length. Sometimes it detects a buffer - overflow if data is written to a fixed size buffer although - ``length <= sizeof(buffer)``. CID 486613 - -``path_converter()`` dereferencing after null check - The ``path_converter()`` function in ``posixmodule.c`` makes sure that - either ``path_t.narrow`` or ``path_t.wide`` is filled unless - ``path_t.nullable`` is explicitly enabled. CID 719648 - - -Modeling -======== - -Modeling is explained in the *Coverity Help Center* which is available in -the help menu of `Coverity Connect`_. `coverity_model.c`_ contains a copy of -Python's modeling file for Coverity. Please keep the copy in sync with the -model file in *Analysis Settings* of `Coverity Scan`_. - - -Workflow -======== - -False positive and intentional issues -------------------------------------- - -If the problem is listed under `Known limitations`_ then please set the -classification to either "False positive" or "Intentional", the action to -"Ignore", owner to your own account and add a comment why the issue -is considered false positive or intentional. - -If you think it's a new false positive or intentional then please contact an -admin. The first step should be an updated to Python's `Modeling`_ file. - - -Positive issues ---------------- - -You should always create an issue unless it's really a trivial case. Please -add the full url to the ticket under *Ext. Reference* and add the CID -(Coverity ID) to both the ticket and the checkin message. It makes it much -easier to understand the relation between tickets, fixes and Coverity issues. - - -Contact -======= - -Please include both Brett and Christian in any mail regarding Coverity. Mails -to Coverity should go through Brett or Christian, too. - -Christian Heimes - admin, maintainer of build machine, intermediary between Python and Coverity - -Brett Cannon - co-admin - -Dakshesh Vyas - Technical Manager - Coverity Scan - - -.. seealso:: - - `Coverity Scan FAQ `_ - - -.. _Coverity Scan: https://scan.coverity.com/ - -.. _Coverity Connect: https://scan.coverity.com/projects/python - -.. _coverity_model.c: https://github.com/python/cpython/blob/main/Misc/coverity_model.c diff --git a/development-tools/index.rst b/development-tools/index.rst index d62a84769..610d8d8ea 100644 --- a/development-tools/index.rst +++ b/development-tools/index.rst @@ -8,5 +8,4 @@ Development tools clinic gdb clang - coverity warnings From 539703be4f095c7bbeee54e95a4f8759c8585d75 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Tue, 24 Sep 2024 14:14:37 -0700 Subject: [PATCH 365/538] Remove the inactionable TODO (#1412) The TODO has been there for 14 years. --- getting-started/fixing-issues.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/getting-started/fixing-issues.rst b/getting-started/fixing-issues.rst index 6161f4aa6..6b752d79d 100644 --- a/getting-started/fixing-issues.rst +++ b/getting-started/fixing-issues.rst @@ -23,5 +23,3 @@ you can also always provide useful comments if you do attempt a fix, successful or not. .. _"easy" issues: https://github.com/python/cpython/issues?q=is%3Aissue+is%3Aopen+label%3Aeasy - -.. TODO: add something about no active core developer for the area? From 0f959e02e0a2c8eb4ee547411a310c70605c6c31 Mon Sep 17 00:00:00 2001 From: Ayappan Perumal Date: Fri, 27 Sep 2024 21:36:36 +0530 Subject: [PATCH 366/538] Update AIX Maintainers list (#1417) --- 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 950efc656..10f6b5727 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -286,7 +286,7 @@ for “their” platform as a third-party project. =================== =========== Platform Maintainers =================== =========== -AIX edelsohn +AIX edelsohn, ayappanec Android mhsmith Cygwin jlt63^, stutzbach^ Emscripten hoodmane, pmp-p, rdb, rth, ryanking13 From f7b933cf50ba03fcdba3d181614b328694ccedd9 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Sat, 28 Sep 2024 00:16:18 +0200 Subject: [PATCH 367/538] Document ``next`` in versionadded & similar directives (GH-1413) --- documentation/markup.rst | 43 +++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index 58b2bdac0..a7a9bcb76 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -1083,8 +1083,11 @@ units as well as normal text: (``class``, ``attribute``, ``function``, ``method``, ``c:type``, etc), a ``versionadded`` should be included at the end of its description block. - The first argument must be given and is the version in question. The second - argument is optional and can be used to describe the details of the feature. + The first argument must be given and is the version in question. + Instead of a specific version number, you can---and should---use + the word ``next``, indicating that the API will first appear in the + upcoming release. + The second argument is optional and can be used to describe the details of the feature. Example:: @@ -1092,7 +1095,30 @@ units as well as normal text: Return foo and bar. - .. versionadded:: 3.5 + .. versionadded:: next + + When a release is made, the release manager will change the ``next`` to + the just-released version. For example, if ``func`` in the above example is + released in 3.14, the snippet will be changed to:: + + .. function:: func() + + Return foo and bar. + + .. versionadded:: 3.14 + + The tool to do this replacement is `update_version_next.py`_ + in the release-tools repository. + + .. _update_version_next.py: https://github.com/python/release-tools/blob/master/update_version_next.py + + When backporting to versions before 3.14, check if ``Doc/tools/extensions/pyspecific.py`` + contains the function ``expand_version_arg``. If it's not there, + use a specific version instead of ``next``. + + When adding documentation for a function that existed in a past version, + but wasn't documented yet, use the version number where the function was + added instead of ``next``. .. describe:: versionchanged @@ -1106,7 +1132,7 @@ units as well as normal text: Return foo and bar, optionally with *spam* applied. - .. versionchanged:: 3.6 + .. versionchanged:: next Added the *spam* parameter. Note that there should be no blank line between the directive head and the @@ -1118,10 +1144,12 @@ units as well as normal text: There is one required argument: the version from which the feature is deprecated. + Similarly to ``versionadded``, you should use the word ``next`` to indicate + the API will be first deprecated in the upcoming release. Example:: - .. deprecated:: 3.8 + .. deprecated:: next .. describe:: deprecated-removed @@ -1129,11 +1157,12 @@ units as well as normal text: removed. There are two required arguments: the version from which the feature is - deprecated, and the version in which the feature is removed. + deprecated (usually ``next``), and the version in which the feature + is removed, which must be a specific version number (*not* ``next``). Example:: - .. deprecated-removed:: 3.8 4.0 + .. deprecated-removed:: next 4.0 .. describe:: impl-detail From 1f2722ee56ef2604fed7f7a109c9a79be808a986 Mon Sep 17 00:00:00 2001 From: Itamar Oren Date: Fri, 27 Sep 2024 16:53:52 -0700 Subject: [PATCH 368/538] Update the link to the buildbot docs about setting up the worker as a Windows service (#1422) --- testing/new-buildbot-worker.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index debd8df2f..2ddbfaeac 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -179,7 +179,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:: From 87d74cee97ca59cc06c5b066d955a0de571cf376 Mon Sep 17 00:00:00 2001 From: Itamar Oren Date: Fri, 27 Sep 2024 17:06:06 -0700 Subject: [PATCH 369/538] gh-1420: Add a note about long paths support to Windows buildbot setup (#1421) --- testing/new-buildbot-worker.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index 2ddbfaeac..5da61b937 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -102,6 +102,18 @@ can put the ``buildarea`` wherever you want to):: (Note that on Windows, the ``buildbot-worker`` command will be in the :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:: + + Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" + +If the value is not "1", you can enable long paths using this PowerShell command:: + + New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force + Once this initial worker setup completes, you should edit the files ``buildarea/info/admin`` and ``buildarea/info/host`` to provide your contact info and information on the host configuration, respectively. This information From 3defe53bdafc253a2a602d2c6f1d66ca654296be Mon Sep 17 00:00:00 2001 From: Itamar Oren Date: Sat, 28 Sep 2024 06:24:57 -0700 Subject: [PATCH 370/538] Add more packages to CentOS setup instructions (#1423) --- getting-started/setup-building.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 0c0e28691..021916e4d 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -627,9 +627,19 @@ some of CPython's modules (for example, ``zlib``). On **Fedora**, **RHEL**, **CentOS** and other ``dnf``-based systems:: + $ sudo dnf install git pkg-config $ sudo dnf install dnf-plugins-core # install this to use 'dnf builddep' $ sudo dnf builddep python3 + Some optional development dependencies are not included in the above. + To install some additional dependencies for optional build and test components:: + + $ sudo dnf install \ + gcc gcc-c++ gdb lzma glibc-devel libstdc++-devel openssl-devel \ + readline-devel zlib-devel libffi-devel bzip2-devel xz-devel \ + sqlite sqlite-devel sqlite-libs libuuid-devel gdbm-libs perf \ + expat expat-devel mpdecimal python3-pip + On **Debian**, **Ubuntu**, and other ``apt``-based systems, try to get the dependencies for the Python you're working on by using the ``apt`` command. From 91a1d1dfc9232f0cc4052fec9eaa3d9066646858 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 06:56:12 +0300 Subject: [PATCH 371/538] Bump sphinx-lint from 0.9.1 to 1.0.0 (#1425) 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 fd04efd8c..ea5fdb74d 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==0.9.1 +sphinx-lint==1.0.0 sphinx-notfound-page>=1.0.0 sphinx_copybutton>=0.3.3 sphinxext-opengraph>=0.7.1 From e8a01957825ef8455431d5c80a2591011e40a067 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Thu, 3 Oct 2024 13:18:52 -0500 Subject: [PATCH 372/538] Update 3.13.0 expected release date (#1427) --- 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 fdb574b11..5070eace2 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -11,7 +11,7 @@ "branch": "3.13", "pep": 719, "status": "prerelease", - "first_release": "2024-10-01", + "first_release": "2024-10-07", "end_of_life": "2029-10", "release_manager": "Thomas Wouters" }, From 26de21433345d26262bec340ea0952a81c20150f Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Sat, 5 Oct 2024 00:50:46 +0100 Subject: [PATCH 373/538] gh-124989: remove exception related details which have moved to cpython/InternalsDoc (#1428) --- internals/interpreter.rst | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/internals/interpreter.rst b/internals/interpreter.rst index 50332ac5e..477a688d9 100644 --- a/internals/interpreter.rst +++ b/internals/interpreter.rst @@ -171,15 +171,7 @@ Do not confuse the evaluation stack with the call stack, which is used to implem Error handling ============== -When an instruction like ``BINARY_OP`` encounters an error, an exception is raised. -At this point, a traceback entry is added to the exception (by ``PyTraceBack_Here()``) and cleanup is performed. -In the simplest case (absent any ``try`` blocks), this results in the remaining objects being popped off the evaluation stack and their reference count decremented (if not ``NULL``) . -Then the interpreter function (``_PyEval_EvalFrameDefault()``) returns ``NULL``. - -However, if an exception is raised in a ``try`` block, the interpreter must jump to the corresponding ``except`` or ``finally`` block. -In 3.10 and before, there was a separate "block stack" which was used to keep track of nesting ``try`` blocks. -In 3.11, this mechanism has been replaced by a statically generated table, ``code->co_exceptiontable``, -which is described in detail in the `internals documentation +See the `internals documentation `_. The locations table @@ -206,18 +198,6 @@ From C code, you have to call :c:func:`PyCode_Addr2Location`. Fortunately, the locations table is only consulted by exception handling (to set ``tb_lineno``) and by tracing (to pass the line number to the tracing function). In order to reduce the overhead during tracing, the mapping from instruction offset to line number is cached in the ``_co_linearray`` field. -Exception chaining ------------------- - -When an exception is raised during exception handling, the new exception is chained to the old one. -This is done by making the ``__context__`` field of the new exception point to the old one. -This is the responsibility of ``_PyErr_SetObject()`` in :cpy-file:`Python/errors.c` (which is ultimately called by all ``PyErr_Set*()`` functions). -Separately, if a statement of the form :samp:`raise {X} from {Y}` is executed, the ``__cause__`` field of the raised exception (:samp:`{X}`) is set to :samp:`{Y}`. -This is done by :c:func:`PyException_SetCause`, called in response to all ``RAISE_VARARGS`` instructions. -A special case is :samp:`raise {X} from None`, which sets the ``__cause__`` field to ``None`` (at the C level, it sets ``cause`` to ``NULL``). - -(TODO: Other exception details.) - Python-to-Python calls ====================== From 9433f72238cebfd5014e1febb72d30baf65cf500 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:34:38 +0100 Subject: [PATCH 374/538] Latest and greatest (3.13.0) (#1429) --- 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 5070eace2..ede790069 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -10,7 +10,7 @@ "3.13": { "branch": "3.13", "pep": 719, - "status": "prerelease", + "status": "bugfix", "first_release": "2024-10-07", "end_of_life": "2029-10", "release_manager": "Thomas Wouters" From f7ce17f936921690419d4e618a2197acb7e3f756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Mon, 7 Oct 2024 20:10:39 +0200 Subject: [PATCH 375/538] So long, Python 3.8 (#1430) --- 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 ede790069..b77e90487 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -50,9 +50,9 @@ "3.8": { "branch": "3.8", "pep": 569, - "status": "security", + "status": "end-of-life", "first_release": "2019-10-14", - "end_of_life": "2024-10", + "end_of_life": "2024-10-07", "release_manager": "Łukasz Langa" }, "3.7": { From bd3f9fd7f58d0cafd999a45e869c8542fca76ae1 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Tue, 8 Oct 2024 17:37:16 -0500 Subject: [PATCH 376/538] feat: add `infra` label (#1432) * feat: add `infra` label Closes: #1418 * chore: hierarchical sort grouped by levels * chore: apply review Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --------- Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- triage/labels.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/triage/labels.rst b/triage/labels.rst index 783bb555d..b75f75721 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -109,21 +109,23 @@ for a list of active branches. Other labels ============ -* :gh-label:`triaged`: for issue has been accepted as valid by a triager. -* :gh-label:`easy`: for issues that are considered easy. * :gh-label:`build`/:gh-label:`performance`: for issues related to the build process or performance, respectively. +* :gh-label:`easy`: for issues that are considered easy. +* :gh-label:`infra`: for issues related to the infrastructure of the + project (for example, GitHub Actions, dependabot, the buildbots). +* :gh-label:`pending`: for issues/PRs that will be closed unless further + feedback is provided. * :gh-label:`release-blocker`/:gh-label:`deferred-blocker`: for issues/PRs + and the :ref:`branch's release manager ` + removing or retaining the label as appropriate. that, unless fixed, will hold the current or next release respectively. Triagers may set these labels for issues that must be fixed before a release, - and the :ref:`branch's release manager ` will review them and determine if they indeed qualify, - removing or retaining the label as appropriate. -* :gh-label:`pending`: for issues/PRs that will be closed unless further - feedback is provided. -* :gh-label:`stale`: for issues/PRs that have been inactive for a while. * :gh-label:`sprint`: for easier filtering of issues/PRs being worked on during official sprints. +* :gh-label:`stale`: for issues/PRs that have been inactive for a while. +* :gh-label:`triaged`: for issue has been accepted as valid by a triager. .. _GitHub Labels for PRs: From 9fb3c00caa608f91040546b278f40e6cdbc8ce7c Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 9 Oct 2024 15:28:46 +0200 Subject: [PATCH 377/538] Use --with-dbmliborder or macOS+Homebrew on 3.10 and below (#1433) --- getting-started/setup-building.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 021916e4d..4f7478dbc 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -739,7 +739,12 @@ some of CPython's modules (for example, ``zlib``). ./configure --with-pydebug \ --with-openssl="$(brew --prefix openssl@3)" \ --with-tcltk-libs="$(pkg-config --libs tcl tk)" \ - --with-tcltk-includes="$(pkg-config --cflags tcl tk)" + --with-tcltk-includes="$(pkg-config --cflags tcl tk)" \ + --with-dbmliborder=gdbm:ndbm + + (``--with-dbmliborder`` is a workaround for a Homebrew-specific change + to ``gdbm``; see `#89452 `_ + for details.) .. tab:: MacPorts From f4524c425db5918c14a693b2e97ba1de90e1c268 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Wed, 9 Oct 2024 18:23:31 +0100 Subject: [PATCH 378/538] gh-119786: Move parser doc from devguide to InternalDocs (#1431) --- internals/parser.rst | 920 +------------------------------------------ 1 file changed, 2 insertions(+), 918 deletions(-) diff --git a/internals/parser.rst b/internals/parser.rst index ad97950ef..688ad61e7 100644 --- a/internals/parser.rst +++ b/internals/parser.rst @@ -6,921 +6,5 @@ Guide to the parser .. highlight:: none -Abstract -======== - -The Parser in CPython is currently a `PEG (Parser Expression Grammar) -`_ parser. The first -version of the parser used to be an `LL(1) -`_ based parser that was one of the -oldest parts of CPython implemented before it was replaced by :pep:`617`. In -particular, both the current parser and the old LL(1) parser are the output of a -`parser generator `_. This -means that the way the parser is written is by feeding a description of the -Grammar of the Python language to a special program (the parser generator) which -outputs the parser. The way the Python language is changed is therefore by -modifying the grammar file and developers rarely need to interact with the -parser generator itself other than use it to generate the parser. - -How PEG parsers work -==================== - -.. _how-peg-parsers-work: - -A PEG (Parsing Expression Grammar) grammar (like the current one) differs from a -context-free grammar in that the way it is written more closely -reflects how the parser will operate when parsing it. The fundamental technical -difference is that the choice operator is ordered. This means that when writing:: - - rule: A | B | C - -a context-free-grammar parser (like an LL(1) parser) will generate constructions -that given an input string will *deduce* which alternative (``A``, ``B`` or ``C``) -must be expanded, while a PEG parser will check if the first alternative succeeds -and only if it fails, will it continue with the second or the third one in the -order in which they are written. This makes the choice operator not commutative. - -Unlike LL(1) parsers, PEG-based parsers cannot be ambiguous: if a string parses, -it has exactly one valid parse tree. This means that a PEG-based parser cannot -suffer from the ambiguity problems that can arise with LL(1) parsers and with -context-free grammars in general. - -PEG parsers are usually constructed as a recursive descent parser in which every -rule in the grammar corresponds to a function in the program implementing the -parser and the parsing expression (the "expansion" or "definition" of the rule) -represents the "code" in said function. Each parsing function conceptually takes -an input string as its argument, and yields one of the following results: - -* A "success" result. This result indicates that the expression can be parsed by - that rule and the function may optionally move forward or consume one or more - characters of the input string supplied to it. -* A "failure" result, in which case no input is consumed. - -Notice that "failure" results do not imply that the program is incorrect, nor do -they necessarily mean that the parsing has failed. Since the choice operator is -ordered, a failure very often merely indicates "try the following option". A -direct implementation of a PEG parser as a recursive descent parser will present -exponential time performance in the worst case, because PEG parsers have -infinite lookahead (this means that they can consider an arbitrary number of -tokens before deciding for a rule). Usually, PEG parsers avoid this exponential -time complexity with a technique called "packrat parsing" [1]_ which not only -loads the entire program in memory before parsing it but also allows the parser -to backtrack arbitrarily. This is made efficient by memoizing the rules already -matched for each position. The cost of the memoization cache is that the parser -will naturally use more memory than a simple LL(1) parser, which normally are -table-based. - - -Key ideas ---------- - -.. important:: - Don't try to reason about a PEG grammar in the same way you would to with an EBNF - or context free grammar. PEG is optimized to describe **how** input strings will - be parsed, while context-free grammars are optimized to generate strings of the - language they describe (in EBNF, to know if a given string is in the language, you need - to do work to find out as it is not immediately obvious from the grammar). - -* Alternatives are ordered ( ``A | B`` is not the same as ``B | A`` ). -* If a rule returns a failure, it doesn't mean that the parsing has failed, - it just means "try something else". -* By default PEG parsers run in exponential time, which can be optimized to linear by - using memoization. -* If parsing fails completely (no rule succeeds in parsing all the input text), the - PEG parser doesn't have a concept of "where the :exc:`SyntaxError` is". - - -.. _consequences-of-ordered-choice: - -Consequences of the ordered choice operator -------------------------------------------- - -Although PEG may look like EBNF, its meaning is quite different. The fact -that in PEG parsers alternatives are ordered (which is at the core of how PEG -parsers work) has deep consequences, other than removing ambiguity. - -If a rule has two alternatives and the first of them succeeds, the second one is -**not** attempted even if the caller rule fails to parse the rest of the input. -Thus the parser is said to be "eager". To illustrate this, consider -the following two rules (in these examples, a token is an individual character): :: - - first_rule: ( 'a' | 'aa' ) 'a' - second_rule: ('aa' | 'a' ) 'a' - -In a regular EBNF grammar, both rules specify the language ``{aa, aaa}`` but -in PEG, one of these two rules accepts the string ``aaa`` but not the string -``aa``. The other does the opposite -- it accepts the string ``aa`` -but not the string ``aaa``. The rule ``('a'|'aa')'a'`` does -not accept ``aaa`` because ``'a'|'aa'`` consumes the first ``a``, letting the -final ``a`` in the rule consume the second, and leaving out the third ``a``. -As the rule has succeeded, no attempt is ever made to go back and let -``'a'|'aa'`` try the second alternative. The expression ``('aa'|'a')'a'`` does -not accept ``aa`` because ``'aa'|'a'`` accepts all of ``aa``, leaving nothing -for the final ``a``. Again, the second alternative of ``'aa'|'a'`` is not -tried. - -.. caution:: - - The effects of ordered choice, such as the ones illustrated above, may be hidden by many levels of rules. - -For this reason, writing rules where an alternative is contained in the next one is in almost all cases a mistake, -for example: :: - - my_rule: - | 'if' expression 'then' block - | 'if' expression 'then' block 'else' block - -In this example, the second alternative will never be tried because the first one will -succeed first (even if the input string has an ``'else' block`` that follows). To correctly -write this rule you can simply alter the order: :: - - my_rule: - | 'if' expression 'then' block 'else' block - | 'if' expression 'then' block - -In this case, if the input string doesn't have an ``'else' block``, the first alternative -will fail and the second will be attempted without said part. - -Syntax -====== - -The grammar consists of a sequence of rules of the form: :: - - rule_name: expression - -Optionally, a type can be included right after the rule name, which -specifies the return type of the C or Python function corresponding to -the rule: :: - - rule_name[return_type]: expression - -If the return type is omitted, then a ``void *`` is returned in C and an -``Any`` in Python. - -Grammar expressions -------------------- - -``# comment`` -^^^^^^^^^^^^^ - -Python-style comments. - -``e1 e2`` -^^^^^^^^^ - -Match ``e1``, then match ``e2``. - -:: - - rule_name: first_rule second_rule - -``e1 | e2`` -^^^^^^^^^^^ - -Match ``e1`` or ``e2``. - -The first alternative can also appear on the line after the rule name -for formatting purposes. In that case, a \| must be used before the -first alternative, like so: - -:: - - rule_name[return_type]: - | first_alt - | second_alt - -``( e )`` -^^^^^^^^^ - -Match ``e``. - -:: - - rule_name: (e) - -A slightly more complex and useful example includes using the grouping -operator together with the repeat operators: - -:: - - rule_name: (e1 e2)* - -``[ e ] or e?`` -^^^^^^^^^^^^^^^ - -Optionally match ``e``. - -:: - - rule_name: [e] - -A more useful example includes defining that a trailing comma is -optional: - -:: - - rule_name: e (',' e)* [','] - -``e*`` -^^^^^^ - -Match zero or more occurrences of ``e``. - -:: - - rule_name: (e1 e2)* - -``e+`` -^^^^^^ - -Match one or more occurrences of ``e``. - -:: - - rule_name: (e1 e2)+ - -``s.e+`` -^^^^^^^^ - -Match one or more occurrences of ``e``, separated by ``s``. The generated parse -tree does not include the separator. This is otherwise identical to -``(e (s e)*)``. - -:: - - rule_name: ','.e+ - -``&e`` -^^^^^^ - -.. _peg-positive-lookahead: - -Succeed if ``e`` can be parsed, without consuming any input. - -``!e`` -^^^^^^ - -.. _peg-negative-lookahead: - -Fail if ``e`` can be parsed, without consuming any input. - -An example taken from the Python grammar specifies that a primary -consists of an atom, which is not followed by a ``.`` or a ``(`` or a -``[``: - -:: - - primary: atom !'.' !'(' !'[' - -``~`` -^^^^^ - -Commit to the current alternative, even if it fails to parse (this is called -the "cut"). - -:: - - rule_name: '(' ~ some_rule ')' | some_alt - -In this example, if a left parenthesis is parsed, then the other -alternative won’t be considered, even if some_rule or ``)`` fail to be -parsed. - -Left recursion --------------- - -PEG parsers normally do not support left recursion but CPython's parser -generator implements a technique similar to the one described in Medeiros et al. -[2]_ but using the memoization cache instead of static variables. This approach -is closer to the one described in Warth et al. [3]_. This allows us to write not -only simple left-recursive rules but also more complicated rules that involve -indirect left-recursion like:: - - rule1: rule2 | 'a' - rule2: rule3 | 'b' - rule3: rule1 | 'c' - -and "hidden left-recursion" like:: - - rule: 'optional'? rule '@' some_other_rule - -Variables in the grammar ------------------------- - -A sub-expression can be named by preceding it with an identifier and an -``=`` sign. The name can then be used in the action (see below), like this: :: - - rule_name[return_type]: '(' a=some_other_rule ')' { a } - -Grammar actions ---------------- - -.. _peg-grammar-actions: - -To avoid the intermediate steps that obscure the relationship between the -grammar and the AST generation the PEG parser allows directly generating AST -nodes for a rule via grammar actions. Grammar actions are language-specific -expressions that are evaluated when a grammar rule is successfully parsed. These -expressions can be written in Python or C depending on the desired output of the -parser generator. This means that if one would want to generate a parser in -Python and another in C, two grammar files should be written, each one with a -different set of actions, keeping everything else apart from said actions -identical in both files. As an example of a grammar with Python actions, the -piece of the parser generator that parses grammar files is bootstrapped from a -meta-grammar file with Python actions that generate the grammar tree as a result -of the parsing. - -In the specific case of the PEG grammar for Python, having actions allows -directly describing how the AST is composed in the grammar itself, making it -more clear and maintainable. This AST generation process is supported by the use -of some helper functions that factor out common AST object manipulations and -some other required operations that are not directly related to the grammar. - -To indicate these actions each alternative can be followed by the action code -inside curly-braces, which specifies the return value of the alternative:: - - rule_name[return_type]: - | first_alt1 first_alt2 { first_alt1 } - | second_alt1 second_alt2 { second_alt1 } - -If the action is omitted, a default action is generated: - -* If there's a single name in the rule, it gets returned. - -* If there is more than one name in the rule, a collection with all parsed - expressions gets returned (the type of the collection will be different - in C and Python). - -This default behaviour is primarily made for very simple situations and for -debugging purposes. - -.. warning:: - - It's important that the actions don't mutate any AST nodes that are passed - into them via variables referring to other rules. The reason for mutation - being not allowed is that the AST nodes are cached by memoization and could - potentially be reused in a different context, where the mutation would be - invalid. If an action needs to change an AST node, it should instead make a - new copy of the node and change that. - -The full meta-grammar for the grammars supported by the PEG generator is: - -:: - - start[Grammar]: grammar ENDMARKER { grammar } - - grammar[Grammar]: - | metas rules { Grammar(rules, metas) } - | rules { Grammar(rules, []) } - - metas[MetaList]: - | meta metas { [meta] + metas } - | meta { [meta] } - - meta[MetaTuple]: - | "@" NAME NEWLINE { (name.string, None) } - | "@" a=NAME b=NAME NEWLINE { (a.string, b.string) } - | "@" NAME STRING NEWLINE { (name.string, literal_eval(string.string)) } - - rules[RuleList]: - | rule rules { [rule] + rules } - | rule { [rule] } - - rule[Rule]: - | rulename ":" alts NEWLINE INDENT more_alts DEDENT { - Rule(rulename[0], rulename[1], Rhs(alts.alts + more_alts.alts)) } - | rulename ":" NEWLINE INDENT more_alts DEDENT { Rule(rulename[0], rulename[1], more_alts) } - | rulename ":" alts NEWLINE { Rule(rulename[0], rulename[1], alts) } - - rulename[RuleName]: - | NAME '[' type=NAME '*' ']' {(name.string, type.string+"*")} - | NAME '[' type=NAME ']' {(name.string, type.string)} - | NAME {(name.string, None)} - - alts[Rhs]: - | alt "|" alts { Rhs([alt] + alts.alts)} - | alt { Rhs([alt]) } - - more_alts[Rhs]: - | "|" alts NEWLINE more_alts { Rhs(alts.alts + more_alts.alts) } - | "|" alts NEWLINE { Rhs(alts.alts) } - - alt[Alt]: - | items '$' action { Alt(items + [NamedItem(None, NameLeaf('ENDMARKER'))], action=action) } - | items '$' { Alt(items + [NamedItem(None, NameLeaf('ENDMARKER'))], action=None) } - | items action { Alt(items, action=action) } - | items { Alt(items, action=None) } - - items[NamedItemList]: - | named_item items { [named_item] + items } - | named_item { [named_item] } - - named_item[NamedItem]: - | NAME '=' ~ item {NamedItem(name.string, item)} - | item {NamedItem(None, item)} - | it=lookahead {NamedItem(None, it)} - - lookahead[LookaheadOrCut]: - | '&' ~ atom {PositiveLookahead(atom)} - | '!' ~ atom {NegativeLookahead(atom)} - | '~' {Cut()} - - item[Item]: - | '[' ~ alts ']' {Opt(alts)} - | atom '?' {Opt(atom)} - | atom '*' {Repeat0(atom)} - | atom '+' {Repeat1(atom)} - | sep=atom '.' node=atom '+' {Gather(sep, node)} - | atom {atom} - - atom[Plain]: - | '(' ~ alts ')' {Group(alts)} - | NAME {NameLeaf(name.string) } - | STRING {StringLeaf(string.string)} - - # Mini-grammar for the actions - - action[str]: "{" ~ target_atoms "}" { target_atoms } - - target_atoms[str]: - | target_atom target_atoms { target_atom + " " + target_atoms } - | target_atom { target_atom } - - target_atom[str]: - | "{" ~ target_atoms "}" { "{" + target_atoms + "}" } - | NAME { name.string } - | NUMBER { number.string } - | STRING { string.string } - | "?" { "?" } - | ":" { ":" } - -As an illustrative example this simple grammar file allows directly -generating a full parser that can parse simple arithmetic expressions and that -returns a valid C-based Python AST: - -:: - - start[mod_ty]: a=expr_stmt* ENDMARKER { _PyAST_Module(a, NULL, p->arena) } - expr_stmt[stmt_ty]: a=expr NEWLINE { _PyAST_Expr(a, EXTRA) } - - expr[expr_ty]: - | l=expr '+' r=term { _PyAST_BinOp(l, Add, r, EXTRA) } - | l=expr '-' r=term { _PyAST_BinOp(l, Sub, r, EXTRA) } - | term - - term[expr_ty]: - | l=term '*' r=factor { _PyAST_BinOp(l, Mult, r, EXTRA) } - | l=term '/' r=factor { _PyAST_BinOp(l, Div, r, EXTRA) } - | factor - - factor[expr_ty]: - | '(' e=expr ')' { e } - | atom - - atom[expr_ty]: - | NAME - | NUMBER - -Here ``EXTRA`` is a macro that expands to ``start_lineno, start_col_offset, -end_lineno, end_col_offset, p->arena``, those being variables automatically -injected by the parser; ``p`` points to an object that holds on to all state -for the parser. - -A similar grammar written to target Python AST objects: - -:: - - start[ast.Module]: a=expr_stmt* ENDMARKER { ast.Module(body=a or [] } - expr_stmt: a=expr NEWLINE { ast.Expr(value=a, EXTRA) } - - expr: - | l=expr '+' r=term { ast.BinOp(left=l, op=ast.Add(), right=r, EXTRA) } - | l=expr '-' r=term { ast.BinOp(left=l, op=ast.Sub(), right=r, EXTRA) } - | term - - term: - | l=term '*' r=factor { ast.BinOp(left=l, op=ast.Mult(), right=r, EXTRA) } - | l=term '/' r=factor { ast.BinOp(left=l, op=ast.Div(), right=r, EXTRA) } - | factor - - factor: - | '(' e=expr ')' { e } - | atom - - atom: - | NAME - | NUMBER - - -Pegen -===== - -Pegen is the parser generator used in CPython to produce the final PEG parser used by the interpreter. It is the -program that can be used to read the python grammar located in :cpy-file:`Grammar/python.gram` and produce the final C -parser. It contains the following pieces: - -* A parser generator that can read a grammar file and produce a PEG parser written in Python or C that can parse - said grammar. The generator is located at :cpy-file:`Tools/peg_generator/pegen`. -* A PEG meta-grammar that automatically generates a Python parser that is used for the parser generator itself - (this means that there are no manually-written parsers). The meta-grammar is - located at :cpy-file:`Tools/peg_generator/pegen/metagrammar.gram`. -* A generated parser (using the parser generator) that can directly produce C and Python AST objects. - -The source code for Pegen lives at :cpy-file:`Tools/peg_generator/pegen` but normally all typical commands to interact -with the parser generator are executed from the main makefile. - -How to regenerate the parser ----------------------------- - -Once you have made the changes to the grammar files, to regenerate the ``C`` -parser (the one used by the interpreter) just execute: :: - - make regen-pegen - -using the ``Makefile`` in the main directory. If you are on Windows you can -use the Visual Studio project files to regenerate the parser or to execute: :: - - ./PCbuild/build.bat --regen - -The generated parser file is located at :cpy-file:`Parser/parser.c`. - -How to regenerate the meta-parser ---------------------------------- - -The meta-grammar (the grammar that describes the grammar for the grammar files -themselves) is located at :cpy-file:`Tools/peg_generator/pegen/metagrammar.gram`. -Although it is very unlikely that you will ever need to modify it, if you make any modifications -to this file (in order to implement new Pegen features) you will need to regenerate -the meta-parser (the parser that parses the grammar files). To do so just execute: :: - - make regen-pegen-metaparser - -If you are on Windows you can use the Visual Studio project files -to regenerate the parser or to execute: :: - - ./PCbuild/build.bat --regen - - -Grammatical elements and rules ------------------------------- - -Pegen has some special grammatical elements and rules: - -* Strings with single quotes (') (for example, ``'class'``) denote KEYWORDS. -* Strings with double quotes (") (for example, ``"match"``) denote SOFT KEYWORDS. -* Uppercase names (for example, ``NAME``) denote tokens in the :cpy-file:`Grammar/Tokens` file. -* Rule names starting with ``invalid_`` are used for specialized syntax errors. - - - These rules are NOT used in the first pass of the parser. - - Only if the first pass fails to parse, a second pass including the invalid - rules will be executed. - - If the parser fails in the second phase with a generic syntax error, the - location of the generic failure of the first pass will be used (this avoids - reporting incorrect locations due to the invalid rules). - - The order of the alternatives involving invalid rules matter - (like any rule in PEG). - -Tokenization ------------- - -It is common among PEG parser frameworks that the parser does both the parsing and the tokenization, -but this does not happen in Pegen. The reason is that the Python language needs a custom tokenizer -to handle things like indentation boundaries, some special keywords like ``ASYNC`` and ``AWAIT`` -(for compatibility purposes), backtracking errors (such as unclosed parenthesis), dealing with encoding, -interactive mode and much more. Some of these reasons are also there for historical purposes, and some -others are useful even today. - -The list of tokens (all uppercase names in the grammar) that you can use can be found in the :cpy-file:`Grammar/Tokens` -file. If you change this file to add new tokens, make sure to regenerate the files by executing: :: - - make regen-token - -If you are on Windows you can use the Visual Studio project files to regenerate the tokens or to execute: :: - - ./PCbuild/build.bat --regen - -How tokens are generated and the rules governing this are completely up to the tokenizer -(:cpy-file:`Parser/lexer/` and :cpy-file:`Parser/tokenizer/`); -the parser just receives tokens from it. - -Memoization ------------ - -As described previously, to avoid exponential time complexity in the parser, memoization is used. - -The C parser used by Python is highly optimized and memoization can be expensive both in memory and time. Although -the memory cost is obvious (the parser needs memory for storing previous results in the cache) the execution time -cost comes for continuously checking if the given rule has a cache hit or not. In many situations, just parsing it -again can be faster. Pegen **disables memoization by default** except for rules with the special marker ``memo`` after -the rule name (and type, if present): :: - - rule_name[typr] (memo): - ... - -By selectively turning on memoization for a handful of rules, the parser becomes faster and uses less memory. - -.. note:: - Left-recursive rules always use memoization, since the implementation of left-recursion depends on it. - -To know if a new rule needs memoization or not, benchmarking is required -(comparing execution times and memory usage of some considerably big files with -and without memoization). There is a very simple instrumentation API available -in the generated C parse code that allows to measure how much each rule uses -memoization (check the :cpy-file:`Parser/pegen.c` file for more information) but it -needs to be manually activated. - -Automatic variables -------------------- - -To make writing actions easier, Pegen injects some automatic variables in the namespace available -when writing actions. In the C parser, some of these automatic variable names are: - -* ``p``: The parser structure. -* ``EXTRA``: This is a macro that expands to ``(_start_lineno, _start_col_offset, _end_lineno, _end_col_offset, p->arena)``, - which is normally used to create AST nodes as almost all constructors need these attributes to be provided. All of the - location variables are taken from the location information of the current token. - -Hard and soft keywords ----------------------- - -.. note:: - In the grammar files, keywords are defined using **single quotes** (for example, ``'class'``) while soft - keywords are defined using **double quotes** (for example, ``"match"``). - -There are two kinds of keywords allowed in pegen grammars: *hard* and *soft* -keywords. The difference between hard and soft keywords is that hard keywords -are always reserved words, even in positions where they make no sense (for example, ``x = class + 1``), -while soft keywords only get a special meaning in context. Trying to use a hard -keyword as a variable will always fail: - -.. code-block:: - - >>> class = 3 - File "", line 1 - class = 3 - ^ - SyntaxError: invalid syntax - >>> foo(class=3) - File "", line 1 - foo(class=3) - ^^^^^ - SyntaxError: invalid syntax - -While soft keywords don't have this limitation if used in a context other the one where they -are defined as keywords: - -.. code-block:: python - - >>> match = 45 - >>> foo(match="Yeah!") - -The ``match`` and ``case`` keywords are soft keywords, so that they are recognized as -keywords at the beginning of a match statement or case block respectively, but are -allowed to be used in other places as variable or argument names. - -You can get a list of all keywords defined in the grammar from Python: - -.. code-block:: python - - >>> import keyword - >>> keyword.kwlist - ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', - 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', - 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', - 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield'] - -as well as soft keywords: - -.. code-block:: python - - >>> import keyword - >>> keyword.softkwlist - ['_', 'case', 'match'] - -.. caution:: - Soft keywords can be a bit challenging to manage as they can be accepted in - places you don't intend to, given how the order alternatives behave in PEG - parsers (see :ref:`consequences of ordered choice section - ` for some background on this). In general, - try to define them in places where there is not a lot of alternatives. - -Error handling --------------- - -When a pegen-generated parser detects that an exception is raised, it will -**automatically stop parsing**, no matter what the current state of the parser -is and it will unwind the stack and report the exception. This means that if a -:ref:`rule action ` raises an exception all parsing will -stop at that exact point. This is done to allow to correctly propagate any -exception set by calling Python's C API functions. This also includes :exc:`SyntaxError` -exceptions and this is the main mechanism the parser uses to report custom syntax -error messages. - -.. note:: - Tokenizer errors are normally reported by raising exceptions but some special - tokenizer errors such as unclosed parenthesis will be reported only after the - parser finishes without returning anything. - -How syntax errors are reported ------------------------------- - -As described previously in the :ref:`how PEG parsers work section -`, PEG parsers don't have a defined concept of where -errors happened in the grammar, because a rule failure doesn't imply a -parsing failure like in context free grammars. This means that some heuristic -has to be used to report generic errors unless something is explicitly declared -as an error in the grammar. - -To report generic syntax errors, pegen uses a common heuristic in PEG parsers: -the location of *generic* syntax errors is reported in the furthest token that -was attempted to be matched but failed. This is only done if parsing has failed -(the parser returns ``NULL`` in C or ``None`` in Python) but no exception has -been raised. - -.. caution:: - Positive and negative lookaheads will try to match a token so they will affect - the location of generic syntax errors. Use them carefully at boundaries - between rules. - -As the Python grammar was primordially written as an LL(1) grammar, this heuristic -has an extremely high success rate, but some PEG features can have small effects, -such as :ref:`positive lookaheads ` and -:ref:`negative lookaheads `. - -To generate more precise syntax errors, custom rules are used. This is a common practice -also in context free grammars: the parser will try to accept some construct that is known -to be incorrect just to report a specific syntax error for that construct. In pegen grammars, -these rules start with the ``invalid_`` prefix. This is because trying to match these rules -normally has a performance impact on parsing (and can also affect the 'correct' grammar itself -in some tricky cases, depending on the ordering of the rules) so the generated parser acts in -two phases: - -1. The first phase will try to parse the input stream without taking into account rules that - start with the ``invalid_`` prefix. If the parsing succeeds it will return the generated AST - and the second phase will not be attempted. - -2. If the first phase failed, a second parsing attempt is done including the rules that start - with an ``invalid_`` prefix. By design this attempt **cannot succeed** and is only executed - to give to the invalid rules a chance to detect specific situations where custom, more precise, - syntax errors can be raised. This also allows to trade a bit of performance for precision reporting - errors: given that we know that the input text is invalid, there is no need to be fast because - the interpreter is going to stop anyway. - -.. important:: - When defining invalid rules: - - * Make sure all custom invalid rules raise :exc:`SyntaxError` exceptions (or a subclass of it). - * Make sure **all** invalid rules start with the ``invalid_`` prefix to not - impact performance of parsing correct Python code. - * Make sure the parser doesn't behave differently for regular rules when you introduce invalid rules - (see the :ref:`how PEG parsers work section ` for more information). - -You can find a collection of macros to raise specialized syntax errors in the -:cpy-file:`Parser/pegen.h` header file. These macros allow also to report ranges for -the custom errors that will be highlighted in the tracebacks that will be -displayed when the error is reported. - -.. tip:: - A good way to test if an invalid rule will be triggered when you expect is to test if introducing - a syntax error **after** valid code triggers the rule or not. For example: :: - - $ 42 - - Should trigger the syntax error in the ``$`` character. If your rule is not correctly defined this - won't happen. For example, if you try to define a rule to match Python 2 style ``print`` statements - to make a better error message and you define it as: :: - - invalid_print: "print" expression - - This will **seem** to work because the parser will correctly parse ``print(something)`` because it is valid - code and the second phase will never execute but if you try to parse ``print(something) $ 3`` the first pass - of the parser will fail (because of the ``$``) and in the second phase, the rule will match the - ``print(something)`` as ``print`` followed by the variable ``something`` between parentheses and the error - will be reported there instead of the ``$`` character. - -Generating AST objects ----------------------- - -The output of the C parser used by CPython that is generated by the -:cpy-file:`Grammar/python.gram` grammar file is a Python AST object (using C -structures). This means that the actions in the grammar file generate AST objects -when they succeed. Constructing these objects can be quite cumbersome (see the -`AST compiler section `_ -for more information on how these objects are constructed and how they are used -by the compiler) so special helper functions are used. These functions are declared in the -:cpy-file:`Parser/pegen.h` header file and defined in the :cpy-file:`Parser/action_helpers.c` -file. These functions allow you to join AST sequences, get specific elements -from them or to do extra processing on the generated tree. - -.. caution:: - Actions must **never** be used to accept or reject rules. It may be tempting - in some situations to write a very generic rule and then check the generated - AST to decide if is valid or not but this will render the `official grammar - `_ partially incorrect - (because actions are not included) and will make it more difficult for other - Python implementations to adapt the grammar to their own needs. - -As a general rule, if an action spawns multiple lines or requires something more -complicated than a single expression of C code, is normally better to create a -custom helper in :cpy-file:`Parser/action_helpers.c` and expose it in the -:cpy-file:`Parser/pegen.h` header file so it can be used from the grammar. - -If the parsing succeeds, the parser **must** return a **valid** AST object. - -Testing -======= - -There are three files that contain tests for the grammar and the parser: - -* :cpy-file:`Lib/test/test_grammar.py` -* :cpy-file:`Lib/test/test_syntax.py` -* :cpy-file:`Lib/test/test_exceptions.py` - -Check the contents of these files to know which is the best place to place new tests depending -on the nature of the new feature you are adding. - -Tests for the parser generator itself can be found in the :cpy-file:`Lib/test/test_peg_generator` directory. - - -Debugging generated parsers -=========================== - -Making experiments ------------------- - -As the generated C parser is the one used by Python, this means that if something goes wrong when adding some -new rules to the grammar you cannot correctly compile and execute Python anymore. This makes it a bit challenging -to debug when something goes wrong, especially when making experiments. - -For this reason it is a good idea to experiment first by generating a Python parser. To do this, you can go to the -:cpy-file:`Tools/peg_generator/` directory on the CPython repository and manually call the parser generator by executing: - -.. code-block:: shell - - $ python -m pegen python - -This will generate a file called :file:`parse.py` in the same directory that you can use to parse some input: - -.. code-block:: shell - - $ python parse.py file_with_source_code_to_test.py - -As the generated :file:`parse.py` file is just Python code, you can modify it and add breakpoints to debug or -better understand some complex situations. - - -Verbose mode ------------- - -When Python is compiled in debug mode (by adding ``--with-pydebug`` when running the configure step in Linux or by -adding ``-d`` when calling the :cpy-file:`PCbuild/build.bat` script in Windows), it is possible to activate a **very** verbose -mode in the generated parser. This is very useful to debug the generated parser and to understand how it works, but it -can be a bit hard to understand at first. - -.. note:: - - When activating verbose mode in the Python parser, it is better to not use interactive mode as it can be much harder to - understand, because interactive mode involves some special steps compared to regular parsing. - -To activate verbose mode you can add the ``-d`` flag when executing Python: - -.. code-block:: shell - - $ python -d file_to_test.py - -This will print **a lot** of output to ``stderr`` so is probably better to dump it to a file for further analysis. The output -consists of trace lines with the following structure:: - - ('>'|'-'|'+'|'!') []: ... - -Every line is indented by a different amount (````) depending on how deep the call stack is. The next -character marks the type of the trace: - -* ``>`` indicates that a rule is going to be attempted to be parsed. -* ``-`` indicates that a rule has failed to be parsed. -* ``+`` indicates that a rule has been parsed correctly. -* ``!`` indicates that an exception or an error has been detected and the parser is unwinding. - -The ```` part indicates the current index in the token array, -the ```` part indicates what rule is being parsed and -the ```` part indicates what alternative within that rule -is being attempted. - - -References -========== - -.. [1] Ford, Bryan - https://pdos.csail.mit.edu/~baford/packrat/thesis/ - -.. [2] Medeiros et al. - https://arxiv.org/pdf/1207.0443 - -.. [3] Warth et al. - http://web.cs.ucla.edu/~todd/research/pepm08.pdf - - -.. admonition:: Document history - :class: note - - Pablo Galindo Salgado - Original author +This document is now part of the +`CPython Internals Docs `_. From 3743f23debbf9ee0ea1761a99350aea4e591e302 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Wed, 9 Oct 2024 13:34:30 -0500 Subject: [PATCH 379/538] Remove obsolete 'custom builders' section (#1435) --- testing/buildbots.rst | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/testing/buildbots.rst b/testing/buildbots.rst index 38e606364..22962faaf 100644 --- a/testing/buildbots.rst +++ b/testing/buildbots.rst @@ -223,37 +223,5 @@ and unpredictable, the issue should be reported on the bug tracker; even better if it can be diagnosed and suppressed by fixing the test's implementation, or by making its parameters - such as a timeout - more robust. - -Custom builders -=============== - -.. highlight:: console - -When working on a platform-specific issue, you may want to test your changes on -the buildbot fleet rather than just on GitHub Actions and Azure Pipelines. To do so, you can -make use of the `custom builders -`_. -These builders track the ``buildbot-custom`` short-lived branch of the -``python/cpython`` repository, which is only accessible to core developers. - -To start a build on the custom builders, push the commit you want to test to -the ``buildbot-custom`` branch:: - - $ git push upstream :buildbot-custom - -You may run into conflicts if another developer is currently using the custom -builders or forgot to delete the branch when they finished. In that case, make -sure the other developer is finished and either delete the branch or force-push -(add the ``-f`` option) over it. - -When you have gotten the results of your tests, delete the branch:: - - $ git push upstream :buildbot-custom # or use the GitHub UI - -If you are interested in the results of a specific test file only, we -recommend you change (temporarily, of course) the contents of the -``buildbottest`` clause in ``Makefile.pre.in``; or, for Windows builders, -the ``Tools/buildbot/test.bat`` script. - .. seealso:: :ref:`buildworker` From 356fea2853505515f5da8899e2f8c1c4a988f665 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Wed, 9 Oct 2024 13:56:47 -0500 Subject: [PATCH 380/538] Restore support for Python 3.10 to build (#1436) `/usr/bin/python3` is still 3.10 in some widely-used distros and the support requirement is not onerous, needing only to use a longer-lived alias for the same object (`assert datetime.UTC is datetime.timezone.utc` holds where both exist). --- .ruff.toml | 2 +- _tools/generate_release_cycle.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ruff.toml b/.ruff.toml index 550f27e61..af448e5b6 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -1,4 +1,4 @@ -target-version = "py311" +target-version = "py310" fix = true output-format = "full" line-length = 88 diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index ed27424dd..3a8fefec0 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -45,7 +45,7 @@ def __init__(self) -> None: def write_csv(self) -> None: """Output CSV files.""" - now_str = str(dt.datetime.now(dt.UTC)) + now_str = str(dt.datetime.now(dt.timezone.utc)) versions_by_category = {"branches": {}, "end-of-life": {}} headers = None From 97ad6943bb33b082b175f819c9c84b540d5e4354 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:47:42 +0300 Subject: [PATCH 381/538] Remove mentions of EOL Python 3.8 (#1434) --- developer-workflow/development-cycle.rst | 24 +++++++++++------------- getting-started/setup-building.rst | 8 ++++---- internals/garbage-collector.rst | 2 +- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 9c156abbd..c7cf6a8b2 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -37,7 +37,7 @@ Branches -------- There is a branch for each *feature version*, whether released or not (for -example, 3.7, 3.8). +example, 3.12, 3.13). .. _indevbranch: @@ -51,13 +51,11 @@ changes, performance improvements, bug fixes. At some point during the life-cycle of a release, a new :ref:`maintenance branch ` is created to host all bug fixing -activity for further micro versions in a feature version (3.8.1, 3.8.2, etc.). +activity for further micro versions in a feature version (3.12.1, 3.12.2, and so +on). -For versions 3.4 and before, this was conventionally done when the final -release was cut (for example, 3.4.0 final). - -Starting with the 3.5 release, we create the release maintenance branch -(``3.5``) at the time we enter beta (3.5.0 beta 1). This allows +We create the release maintenance branch +(``3.14``) at the time we enter beta (3.14.0 beta 1). This allows feature development for the release 3.n+1 to occur within the main branch alongside the beta and release candidate stabilization periods for release 3.n. @@ -79,7 +77,7 @@ releases; the terms are used interchangeably. These releases have a The only changes allowed to occur in a maintenance branch without debate are bug fixes, test improvements, and edits to the documentation. Also, a general rule for maintenance branches is that compatibility -must not be broken at any point between sibling micro releases (3.5.1, 3.5.2, +must not be broken at any point between sibling micro releases (3.12.1, 3.12.2, etc.). For both rules, only rare exceptions are accepted and **must** be discussed first. @@ -97,9 +95,9 @@ that maintenance branch. Sometime following the final release (3.x.0), the maintenance branch for the previous minor version will go into :ref:`security mode `, usually after at least one more bugfix release at the discretion of the -release manager. For example, the 3.4 maintenance branch was put into -:ref:`security mode ` after the 3.4.4 bugfix release -which followed the release of 3.5.1. +release manager. For example, the 3.11 maintenance branch was put into +:ref:`security mode ` after the 3.11.9 bugfix release +which followed the release of 3.12.2. .. _secbranch: @@ -131,7 +129,7 @@ End-of-life branches The code base for a release cycle which has reached end-of-life status is frozen and no longer has a branch in the repo. The final state of the end-of-lifed branch is recorded as a tag with the same name as the -former branch, for example, ``3.3`` or ``2.6``. +former branch, for example, ``3.8`` or ``2.7``. The :ref:`versions` page contains list of active and end-of-life branches. @@ -347,7 +345,7 @@ Current administrators | Pablo Galindo | Python 3.10 and 3.11 Release Manager, | pablogsal | | | Maintainer of buildbot.python.org | | +-------------------+----------------------------------------------------------+-----------------+ -| Łukasz Langa | Python 3.8 and 3.9 Release Manager, | ambv | +| Łukasz Langa | Python 3.9 Release Manager, | ambv | | | PSF CPython Developer in Residence 2021-present | | +-------------------+----------------------------------------------------------+-----------------+ | Brett Cannon | | brettcannon | diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 4f7478dbc..dc5634c2f 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -116,8 +116,8 @@ in the ``cpython`` directory and two remotes that refer to your own GitHub fork If you want a working copy of an already-released version of Python, that is, a version in :ref:`maintenance mode `, you can checkout -a release branch. For instance, to checkout a working copy of Python 3.8, -do ``git switch 3.8``. +a release branch. For instance, to checkout a working copy of Python 3.13, +do ``git switch 3.13``. You will need to re-compile CPython when you do such an update. @@ -730,9 +730,9 @@ some of CPython's modules (for example, ``zlib``). ./configure --with-pydebug \ --with-openssl="$(brew --prefix openssl@3)" - .. tab:: Python 3.8-3.10 + .. tab:: Python 3.9-3.10 - For Python 3.8, 3.9, and 3.10:: + For Python 3.9 and 3.10:: $ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \ diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index 5b220bfe5..e84a53c22 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -167,7 +167,7 @@ C APIs Specific APIs are offered to allocate, deallocate, initialize, track, and untrack objects with GC support. These APIs can be found in the `Garbage Collector C API -documentation `_. +documentation `_. Apart from this object structure, the type object for objects supporting garbage collection must include the ``Py_TPFLAGS_HAVE_GC`` in its ``tp_flags`` slot and From e661e33bfe2fcdf39f81a9d93cd6e1fabb00cd5b Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Thu, 10 Oct 2024 03:46:22 -0500 Subject: [PATCH 382/538] Fix linkcheck issues (#1437) * Update linkcheck configuration for unavoidable link issues * Update the home of the python-checkins webhook * Fix broken extlink usage (The extlink extension does not handle the `!` prefix.) * Fix renamed PEP-0 section link * Update redirected links * Fix links to labels with spaces * Remove dead link --- conf.py | 17 +++++++++++------ core-developers/motivations.rst | 2 +- developer-workflow/communication-channels.rst | 4 ++-- developer-workflow/extension-modules.rst | 2 +- developer-workflow/lang-changes.rst | 2 +- getting-started/git-boot-camp.rst | 2 +- getting-started/setup-building.rst | 2 +- triage/issue-tracker.rst | 2 +- triage/labels.rst | 5 +++-- 9 files changed, 22 insertions(+), 16 deletions(-) diff --git a/conf.py b/conf.py index 64d7c68b9..aed6592c3 100644 --- a/conf.py +++ b/conf.py @@ -67,6 +67,7 @@ # Login page r"https://github.com/python/buildmaster-config/issues/new.*": r"https://github.com/login.*", # noqa: E501 r"https://github.com/python/core-workflow/issues/new.*": r"https://github.com/login.*", # noqa: E501 + r"https://github.com/orgs/python/teams.*": r"https://github.com/login.*", # noqa: E501 # Archive redirect r"https://github.com/python/cpython/archive/main.zip": r"https://codeload.github.com/python/cpython/zip/refs/heads/main", # noqa: E501 # Blob to tree @@ -89,6 +90,13 @@ r'\/.*', ] +# Check the link itself, but ignore anchors that are added by JS +# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-linkcheck_anchors_ignore_for_url +linkcheck_anchors_ignore_for_url = [ + # GitHub + r'https://github.com/.*', +] + linkcheck_ignore = [ # The voters repo is private and appears as a 404 'https://github.com/python/voters', @@ -98,17 +106,14 @@ 'https://discuss.python.org/groups/staff', 'https://discuss.python.org/groups/moderators', 'https://discuss.python.org/groups/admins', - # The crawler gets "Anchor not found" for GitHub anchors - r'https://github.com.+?#L\d+', - r'https://github.com/cli/cli#installation', - r'https://github.com/github/renaming#renaming-existing-branches', - r'https://github.com/python/bedevere/#pr-state-machine', # "Anchor not found": r'https://packaging.python.org/.*#', # "-rate limited-", causing a timeout r'https://stackoverflow.com/.*', # Discord doesn't allow robot crawlers: "403 Client Error: Forbidden" - 'https://support.discord.com/hc/en-us/articles/219070107-Server-Nicknames', + r'https://support.discord.com/hc/en-us/articles/219070107-Server-Nicknames', + # Patreon also gives 403 to the GHA linkcheck runner + r'https://www.patreon.com/.*', ] rediraffe_redirects = { diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index dfe41d5ae..b805a7c67 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -261,7 +261,7 @@ participating in the CPython core development process: .. topic:: Carol Willing (United States) - * Noteable: ``__ (VP Engineering) + * Noteable (VP Engineering) * Personal site: `Willing Consulting `_ * `Extended bio `__ * Project Jupyter (Software Council, Core Team for JupyterHub/Binder) diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 60ba90339..499ca9b96 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -263,7 +263,7 @@ Other core workflow tools are: * `blurb_it`_ * `miss-islington`_ * `cla-bot`_ -* `cpython-emailer-webhook`_ +* `webhook-mailer`_ Python `Performance Benchmark`_ project is intended to be an authoritative source of benchmarks for all Python implementations. @@ -274,5 +274,5 @@ source of benchmarks for all Python implementations. .. _blurb_it: https://github.com/python/blurb_it .. _miss-islington: https://github.com/python/miss-islington .. _cla-bot: https://github.com/ambv/cla-bot -.. _cpython-emailer-webhook: https://github.com/berkerpeksag/cpython-emailer-webhook +.. _webhook-mailer: https://github.com/python/webhook-mailer .. _Performance Benchmark: https://github.com/python/pyperformance diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index 118fe02d2..6150bb7c4 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -75,7 +75,7 @@ with the following :func:`!foo.greet` function: Instead of using the Python implementation of :func:`!foo.greet`, we want to use its corresponding C extension implementation exposed in the :mod:`!_foo` -module. Ideally, we want to modify :cpy-file:`!Lib/foo.py` as follows: +module. Ideally, we want to modify ``Lib/foo.py`` as follows: .. code-block:: python :caption: Lib/foo.py diff --git a/developer-workflow/lang-changes.rst b/developer-workflow/lang-changes.rst index 70ecd679d..52aabb15d 100644 --- a/developer-workflow/lang-changes.rst +++ b/developer-workflow/lang-changes.rst @@ -45,7 +45,7 @@ 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#abandoned-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. diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index f28ebefbc..15952d6bd 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -341,7 +341,7 @@ example, backports to other branches), so this features is only useful if you know for sure that a single PR is enough to address and close the issue. .. _bedevere: https://github.com/python/bedevere -.. _special keywords: https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword +.. _special keywords: https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword Updating your CPython fork -------------------------- diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index dc5634c2f..8c55bc625 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -47,7 +47,7 @@ itself. Git is easily available for all common operating systems. 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 `_. + `GitHub Desktop `_. - **Configure** diff --git a/triage/issue-tracker.rst b/triage/issue-tracker.rst index a38e8d9e0..63076e7a1 100644 --- a/triage/issue-tracker.rst +++ b/triage/issue-tracker.rst @@ -159,6 +159,6 @@ reason either as ``complete`` or ``not planned``. .. _Python Discourse: https://discuss.python.org/ .. _autolinks: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/autolinked-references-and-urls .. _checklists: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/about-task-lists -.. _duplicates: https://docs.github.com/en/issues/tracking-your-work-with-issues/marking-issues-or-pull-requests-as-a-duplicate +.. _duplicates: https://docs.github.com/en/issues/tracking-your-work-with-issues/administering-issues/marking-issues-or-pull-requests-as-a-duplicate .. _Core Development Discourse category: https://discuss.python.org/c/core-dev/23 .. _old bug tracker: https://bugs.python.org/ diff --git a/triage/labels.rst b/triage/labels.rst index b75f75721..c2981f666 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -147,9 +147,10 @@ to trigger specific bot behaviors. by these labels. See also :ref:`the status of the Python branches ` for a list of branches and the type of PRs that can be backported to them. -* :gh-label:`skip issue`: for trivial changes (such as typo fixes, comment +* :gh-label:`skip issue `: for trivial changes (such as + typo fixes, comment changes, and section rephrases) that don't require a corresponding issue. -* :gh-label:`skip news`: for PRs that don't need a NEWS entry. +* :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 From 64b5b0e30870a7e1cfa8aac62dbaf3093558b926 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Thu, 10 Oct 2024 10:43:13 -0500 Subject: [PATCH 383/538] Fix reference warnings caused by removal of __file__ from cpython docs (#1438) --- developer-workflow/extension-modules.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index 6150bb7c4..7e32283c2 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -31,7 +31,7 @@ Extension modules can be classified into two categories: * A *built-in* extension module is a module built and shipped with the Python interpreter. A built-in module is *statically* linked - into the interpreter, thereby lacking a :attr:`__file__` attribute. + into the interpreter, thereby lacking a :attr:`!__file__` attribute. .. seealso:: :data:`sys.builtin_module_names` --- names of built-in modules. @@ -41,7 +41,7 @@ Extension modules can be classified into two categories: * A *shared* (or *dynamic*) extension module is built as a shared library (``.so`` or ``.dll`` file) and is *dynamically* linked into the interpreter. - In particular, the module's :attr:`__file__` attribute contains the path + In particular, the module's :attr:`!__file__` attribute contains the path to the ``.so`` or ``.dll`` file. Shared modules are built with the :c:macro:`!Py_BUILD_CORE_MODULE` From 9c777785ee1c47dff8606f1be7f07f31fe4576e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 10 Oct 2024 20:03:55 +0200 Subject: [PATCH 384/538] Add Matt Page to core developers (#1439) --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 3808e76c9..52bbf00dd 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Matt Page,mpage,2024-10-10,, Kirill Podoprigora,Eclips4,2024-09-20,, Ned Batchelder,nedbat,2024-07-16,, Tian Gao,gaogaotiantian,2024-06-06,, From 8ec03f998290751ba7414de4580dc59232a3104f Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Thu, 10 Oct 2024 14:42:48 -0500 Subject: [PATCH 385/538] Infra: Use GitHub issue forms (#1414) Co-authored-by: Ezio Melotti Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.md | 25 -------------- .github/ISSUE_TEMPLATE/bug_report.yml | 39 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 14 ++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 22 ------------ .github/ISSUE_TEMPLATE/feature_request.yml | 39 ++++++++++++++++++++++ 5 files changed, 92 insertions(+), 47 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 78aa34d6b..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -> Note: This repo is for the Python devguide. If you are requesting an -enhancement for the Python language or CPython interpreter, -then the CPython issue tracker is better -suited for this report: https://github.com/python/cpython/issues - -**Describe the bug** -A clear and concise description of what the bug is. - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000..b160c6ea1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,39 @@ +name: "Bug report" +description: Create a report to help us improve the Python devguide +title: "Bug: " +labels: ["bug"] +assignees: [] + +body: + - type: markdown + attributes: + value: | + > [!NOTE] + > This repo is for the [Python developer's guide](https://devguide.python.org/). + > If you are reporting a bug for the Python language or + > CPython interpreter, then use the + > [CPython issue tracker](https://github.com/python/cpython/issues) instead. + + - type: textarea + id: bug_description + attributes: + label: "Describe the bug" + description: A clear and concise description of what the bug is and, optionally, what you expected to happen. + validations: + required: true + + - type: textarea + id: screenshots + attributes: + label: "Screenshots" + description: If applicable, add screenshots to help explain your problem. + validations: + required: false + + - type: textarea + id: additional_context + attributes: + label: "Additional context" + description: Add any other context about the problem here. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..cd8c31d2a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +blank_issues_enabled: false +contact_links: + - name: CPython Documentation + url: https://docs.python.org/ + about: Official CPython documentation - please check here before opening an issue. + - name: Python Website + url: https://python.org/ + about: For all things Python + - name: PyPI Issues / Support + url: https://github.com/pypi/support + about: For issues with PyPI itself, PyPI accounts, or with packages hosted on PyPI. + - name: CPython Issues + url: https://github.com/python/cpython/issues + about: For issues with the CPython interpreter itself. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index eff8cb8f7..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -> Note: This repo is for the Python devguide. If you are requesting an -enhancement for the Python language or CPython interpreter, -then the CPython issue tracker is better -suited for this report: https://github.com/python/cpython/issues - -**Describe the enhancement or feature you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000..a4413c137 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,39 @@ +name: "Feature request" +description: Suggest an idea for the Python devguide +title: "Feature: <title>" +labels: ["enhancement"] +assignees: [] + +body: + - type: markdown + attributes: + value: | + > [!NOTE] + > This repo is for the [Python developer's guide](https://devguide.python.org/). + > If you are requesting an enhancement for the Python language or + > CPython interpreter, then use the + > [CPython issue tracker](https://github.com/python/cpython/issues) instead. + + - type: textarea + id: feature_description + attributes: + label: "Describe the enhancement or feature you would like" + description: A clear and concise description of what you want to happen. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: "Describe alternatives you have considered" + description: A clear and concise description of any alternative solutions or features you have considered. + validations: + required: false + + - type: textarea + id: additional_context + attributes: + label: "Additional context" + description: Add any other context or screenshots about the feature request here. + validations: + required: false From 375c964f2d6f58857134714a592cb03343cbee26 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev <skirpichev@gmail.com> Date: Sat, 12 Oct 2024 00:14:42 +0300 Subject: [PATCH 386/538] Cleanup "Reporting an issue" section (#1407) * Cleanup "Reporting an issue" section Now this lists only few examples from actually available options. Closes #1403 * + restore back security item with current wording --- triage/issue-tracker.rst | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/triage/issue-tracker.rst b/triage/issue-tracker.rst index 63076e7a1..b311a51a7 100644 --- a/triage/issue-tracker.rst +++ b/triage/issue-tracker.rst @@ -55,18 +55,12 @@ box above the list of bugs. If you're not already signed in to GitHub, it will ask you to do so now. First you need to select what kind of problem you want to report. The -available choices are: - -* **Bug report**: an existing feature isn't working as expected; -* **Documentation**: there is missing, invalid, or misleading documentation; -* **Enhancement**: suggest a new feature for Python; -* **Performance**: something should work faster; -* **Security**: there is a specific kind of weakness open to exploitation - through the points of vulnerability; -* **Tests**: something is wrong with CPython's suite of regression tests; -* **Discuss**: you'd like to learn more about Python, discuss ideas for - possible changes to future Python versions, track core development - discussions, or join a specific special-interest group. +available choices include, for example: + + * **Bug report**: an existing feature isn't working as expected. + * **Documentation**: there is missing, invalid, or misleading documentation. + * **Feature or enhancement**: suggest a new feature for Python. + * **Report a security vulnerability**: privately report a security vulnerability. Depending on your choice, a dedicated form template will appear. In particular, you'll notice that the last button actually takes you to From 6a2a0227e1681ae3510c05b351664e3f64767624 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Fri, 11 Oct 2024 22:16:13 +0100 Subject: [PATCH 387/538] gh-119786: Move GC doc from devguide to InternalDocs (#1440) --- internals/garbage-collector.rst | 596 +------------------------------- 1 file changed, 2 insertions(+), 594 deletions(-) diff --git a/internals/garbage-collector.rst b/internals/garbage-collector.rst index e84a53c22..acbcedf0e 100644 --- a/internals/garbage-collector.rst +++ b/internals/garbage-collector.rst @@ -8,597 +8,5 @@ Garbage collector design .. highlight:: none -Abstract -======== - -The main garbage collection algorithm used by CPython is reference counting. The basic idea is -that CPython counts how many different places there are that have a reference to an -object. Such a place could be another object, or a global (or static) C variable, or -a local variable in some C function. When an object’s reference count becomes zero, -the object is deallocated. If it contains references to other objects, their -reference counts are decremented. Those other objects may be deallocated in turn, if -this decrement makes their reference count become zero, and so on. The reference -count field can be examined using the ``sys.getrefcount`` function (notice that the -value returned by this function is always 1 more as the function also has a reference -to the object when called): - -.. code-block:: python - - >>> x = object() - >>> sys.getrefcount(x) - 2 - >>> y = x - >>> sys.getrefcount(x) - 3 - >>> del y - >>> sys.getrefcount(x) - 2 - -The main problem with the reference counting scheme is that it does not handle reference -cycles. For instance, consider this code: - -.. code-block:: python - - >>> container = [] - >>> container.append(container) - >>> sys.getrefcount(container) - 3 - >>> del container - -In this example, ``container`` holds a reference to itself, so even when we remove -our reference to it (the variable "container") the reference count never falls to 0 -because it still has its own internal reference. Therefore it would never be -cleaned just by simple reference counting. For this reason some additional machinery -is needed to clean these reference cycles between objects once they become -unreachable. This is the cyclic garbage collector, usually called just Garbage -Collector (GC), even though reference counting is also a form of garbage collection. - -Starting in version 3.13, CPython contains two GC implementations: - -* The default build implementation relies on the :term:`global interpreter - lock` for thread safety. -* The free-threaded build implementation pauses other executing threads when - performing a collection for thread safety. - -Both implementations use the same basic algorithms, but operate on different -data structures. The :ref:`gc-differences` section summarizes the -differences between the two GC implementations. - - -Memory layout and object structure -================================== - -The garbage collector requires additional fields in Python objects to support -garbage collection. These extra fields are different in the default and the -free-threaded builds. - - -GC for the default build ------------------------- - -Normally the C structure supporting a regular Python object looks as follows: - -.. code-block:: none - - object -----> +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ \ - | ob_refcnt | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PyObject_HEAD - | *ob_type | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / - | ... | - - -In order to support the garbage collector, the memory layout of objects is altered -to accommodate extra information **before** the normal layout: - -.. code-block:: none - - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ \ - | *_gc_next | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PyGC_Head - | *_gc_prev | | - object -----> +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / - | ob_refcnt | \ - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PyObject_HEAD - | *ob_type | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / - | ... | - - -In this way the object can be treated as a normal python object and when the extra -information associated to the GC is needed the previous fields can be accessed by a -simple type cast from the original object: :code:`((PyGC_Head *)(the_object)-1)`. - -As is explained later in the `Optimization: reusing fields to save memory`_ section, -these two extra fields are normally used to keep doubly linked lists of all the -objects tracked by the garbage collector (these lists are the GC generations, more on -that in the `Optimization: generations`_ section), but they are also -reused to fulfill other purposes when the full doubly linked list structure is not -needed as a memory optimization. - -Doubly linked lists are used because they efficiently support most frequently required operations. In -general, the collection of all objects tracked by GC are partitioned into disjoint sets, each in its own -doubly linked list. Between collections, objects are partitioned into "generations", reflecting how -often they've survived collection attempts. During collections, the generation(s) being collected -are further partitioned into, for example, sets of reachable and unreachable objects. Doubly linked lists -support moving an object from one partition to another, adding a new object, removing an object -entirely (objects tracked by GC are most often reclaimed by the refcounting system when GC -isn't running at all!), and merging partitions, all with a small constant number of pointer updates. -With care, they also support iterating over a partition while objects are being added to - and -removed from - it, which is frequently required while GC is running. - -GC for the free-threaded build ------------------------------- - -In the free-threaded build, Python objects contain a 1-byte field -``ob_gc_bits`` that is used to track garbage collection related state. The -field exists in all objects, including ones that do not support cyclic -garbage collection. The field is used to identify objects that are tracked -by the collector, ensure that finalizers are called only once per object, -and, during garbage collection, differentiate reachable vs. unreachable objects. - -.. code-block:: none - - object -----> +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ \ - | ob_tid | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | - | pad | ob_mutex | ob_gc_bits | ob_ref_local | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PyObject_HEAD - | ob_ref_shared | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | - | *ob_type | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / - | ... | - - -Note that not all fields are to scale. ``pad`` is two bytes, ``ob_mutex`` and -``ob_gc_bits`` are each one byte, and ``ob_ref_local`` is four bytes. The -other fields, ``ob_tid``, ``ob_ref_shared``, and ``ob_type``, are all -pointer-sized (that is, eight bytes on a 64-bit platform). - - -The garbage collector also temporarily repurposes the ``ob_tid`` (thread ID) -and ``ob_ref_local`` (local reference count) fields for other purposes during -collections. - - -C APIs ------- - -Specific APIs are offered to allocate, deallocate, initialize, track, and untrack -objects with GC support. These APIs can be found in the `Garbage Collector C API -documentation <https://docs.python.org/3/c-api/gcsupport.html>`_. - -Apart from this object structure, the type object for objects supporting garbage -collection must include the ``Py_TPFLAGS_HAVE_GC`` in its ``tp_flags`` slot and -provide an implementation of the ``tp_traverse`` handler. Unless it can be proven -that the objects cannot form reference cycles with only objects of its type or unless -the type is immutable, a ``tp_clear`` implementation must also be provided. - - -Identifying reference cycles -============================ - -The algorithm that CPython uses to detect those reference cycles is -implemented in the ``gc`` module. The garbage collector **only focuses** -on cleaning container objects (that is, objects that can contain a reference -to one or more objects). These can be arrays, dictionaries, lists, custom -class instances, classes in extension modules, etc. One could think that -cycles are uncommon but the truth is that many internal references needed by -the interpreter create cycles everywhere. Some notable examples: - -* Exceptions contain traceback objects that contain a list of frames that - contain the exception itself. -* Module-level functions reference the module's dict (which is needed to resolve globals), - which in turn contains entries for the module-level functions. -* Instances have references to their class which itself references its module, and the module - contains references to everything that is inside (and maybe other modules) - and this can lead back to the original instance. -* When representing data structures like graphs, it is very typical for them to - have internal links to themselves. - -To correctly dispose of these objects once they become unreachable, they need -to be identified first. To understand how the algorithm works, let’s take -the case of a circular linked list which has one link referenced by a -variable ``A``, and one self-referencing object which is completely -unreachable: - -.. code-block:: python - - >>> import gc - - >>> class Link: - ... def __init__(self, next_link=None): - ... self.next_link = next_link - - >>> link_3 = Link() - >>> link_2 = Link(link_3) - >>> link_1 = Link(link_2) - >>> link_3.next_link = link_1 - >>> A = link_1 - >>> del link_1, link_2, link_3 - - >>> link_4 = Link() - >>> link_4.next_link = link_4 - >>> del link_4 - - # Collect the unreachable Link object (and its .__dict__ dict). - >>> gc.collect() - 2 - -The GC starts with a set of candidate objects it wants to scan. In the -default build, these "objects to scan" might be all container objects or a -smaller subset (or "generation"). In the free-threaded build, the collector -always scans all container objects. - -The objective is to identify all the unreachable objects. The collector does -this by identifying reachable objects; the remaining objects must be -unreachable. The first step is to identify all of the "to scan" objects that -are **directly** reachable from outside the set of candidate objects. These -objects have a refcount larger than the number of incoming references from -within the candidate set. - -Every object that supports garbage collection will have an extra reference -count field initialized to the reference count (``gc_ref`` in the figures) -of that object when the algorithm starts. This is because the algorithm needs -to modify the reference count to do the computations and in this way the -interpreter will not modify the real reference count field. - -.. figure:: /_static/python-cyclic-gc-1-new-page.png - -The GC then iterates over all containers in the first list and decrements by one the -``gc_ref`` field of any other object that container is referencing. Doing -this makes use of the ``tp_traverse`` slot in the container class (implemented -using the C API or inherited by a superclass) to know what objects are referenced by -each container. After all the objects have been scanned, only the objects that have -references from outside the “objects to scan” list will have ``gc_ref > 0``. - -.. figure:: /_static/python-cyclic-gc-2-new-page.png - -Notice that having ``gc_ref == 0`` does not imply that the object is unreachable. -This is because another object that is reachable from the outside (``gc_ref > 0``) -can still have references to it. For instance, the ``link_2`` object in our example -ended having ``gc_ref == 0`` but is referenced still by the ``link_1`` object that -is reachable from the outside. To obtain the set of objects that are really -unreachable, the garbage collector re-scans the container objects using the -``tp_traverse`` slot; this time with a different traverse function that marks objects with -``gc_ref == 0`` as "tentatively unreachable" and then moves them to the -tentatively unreachable list. The following image depicts the state of the lists in a -moment when the GC processed the ``link_3`` and ``link_4`` objects but has not -processed ``link_1`` and ``link_2`` yet. - -.. figure:: /_static/python-cyclic-gc-3-new-page.png - -Then the GC scans the next ``link_1`` object. Because it has ``gc_ref == 1``, -the gc does not do anything special because it knows it has to be reachable (and is -already in what will become the reachable list): - -.. figure:: /_static/python-cyclic-gc-4-new-page.png - -When the GC encounters an object which is reachable (``gc_ref > 0``), it traverses -its references using the ``tp_traverse`` slot to find all the objects that are -reachable from it, moving them to the end of the list of reachable objects (where -they started originally) and setting its ``gc_ref`` field to 1. This is what happens -to ``link_2`` and ``link_3`` below as they are reachable from ``link_1``. From the -state in the previous image and after examining the objects referred to by ``link_1`` -the GC knows that ``link_3`` is reachable after all, so it is moved back to the -original list and its ``gc_ref`` field is set to 1 so that if the GC visits it again, -it will know that it's reachable. To avoid visiting an object twice, the GC marks all -objects that have already been visited once (by unsetting the ``PREV_MASK_COLLECTING`` -flag) so that if an object that has already been processed is referenced by some other -object, the GC does not process it twice. - -.. figure:: /_static/python-cyclic-gc-5-new-page.png - -Notice that an object that was marked as "tentatively unreachable" and was later -moved back to the reachable list will be visited again by the garbage collector -as now all the references that that object has need to be processed as well. This -process is really a breadth first search over the object graph. Once all the objects -are scanned, the GC knows that all container objects in the tentatively unreachable -list are really unreachable and can thus be garbage collected. - -Pragmatically, it's important to note that no recursion is required by any of this, -and neither does it in any other way require additional memory proportional to the -number of objects, number of pointers, or the lengths of pointer chains. Apart from -``O(1)`` storage for internal C needs, the objects themselves contain all the storage -the GC algorithms require. - -Why moving unreachable objects is better ----------------------------------------- - -It sounds logical to move the unreachable objects under the premise that most objects -are usually reachable, until you think about it: the reason it pays isn't actually -obvious. - -Suppose we create objects A, B, C in that order. They appear in the young generation -in the same order. If B points to A, and C to B, and C is reachable from outside, -then the adjusted refcounts after the first step of the algorithm runs will be 0, 0, -and 1 respectively because the only reachable object from the outside is C. - -When the next step of the algorithm finds A, A is moved to the unreachable list. The -same for B when it's first encountered. Then C is traversed, B is moved *back* to -the reachable list. B is eventually traversed, and then A is moved back to the reachable -list. - -So instead of not moving at all, the reachable objects B and A are each moved twice. -Why is this a win? A straightforward algorithm to move the reachable objects instead -would move A, B, and C once each. The key is that this dance leaves the objects in -order C, B, A - it's reversed from the original order. On all *subsequent* scans, -none of them will move. Since most objects aren't in cycles, this can save an -unbounded number of moves across an unbounded number of later collections. The only -time the cost can be higher is the first time the chain is scanned. - -Destroying unreachable objects -============================== - -Once the GC knows the list of unreachable objects, a very delicate process starts -with the objective of completely destroying these objects. Roughly, the process -follows these steps in order: - -1. Handle and clear weak references (if any). Weak references to unreachable objects - are set to ``None``. If the weak reference has an associated callback, the callback - is enqueued to be called once the clearing of weak references is finished. We only - invoke callbacks for weak references that are themselves reachable. If both the weak - reference and the pointed-to object are unreachable we do not execute the callback. - This is partly for historical reasons: the callback could resurrect an unreachable - object and support for weak references predates support for object resurrection. - Ignoring the weak reference's callback is fine because both the object and the weakref - are going away, so it's legitimate to say the weak reference is going away first. -2. If an object has legacy finalizers (``tp_del`` slot) move it to the - ``gc.garbage`` list. -3. Call the finalizers (``tp_finalize`` slot) and mark the objects as already - finalized to avoid calling finalizers twice if the objects are resurrected or - if other finalizers have removed the object first. -4. Deal with resurrected objects. If some objects have been resurrected, the GC - finds the new subset of objects that are still unreachable by running the cycle - detection algorithm again and continues with them. -5. Call the ``tp_clear`` slot of every object so all internal links are broken and - the reference counts fall to 0, triggering the destruction of all unreachable - objects. - -Optimization: generations -========================= - -In order to limit the time each garbage collection takes, the GC -implementation for the default build uses a popular optimization: -generations. The main idea behind this concept is the assumption that most -objects have a very short lifespan and can thus be collected soon after their -creation. This has proven to be very close to the reality of many Python -programs as many temporary objects are created and destroyed very quickly. - -To take advantage of this fact, all container objects are segregated into -three spaces/generations. Every new -object starts in the first generation (generation 0). The previous algorithm is -executed only over the objects of a particular generation and if an object -survives a collection of its generation it will be moved to the next one -(generation 1), where it will be surveyed for collection less often. If -the same object survives another GC round in this new generation (generation 1) -it will be moved to the last generation (generation 2) where it will be -surveyed the least often. - -The GC implementation for the free-threaded build does not use multiple -generations. Every collection operates on the entire heap. - -In order to decide when to run, the collector keeps track of the number of object -allocations and deallocations since the last collection. When the number of -allocations minus the number of deallocations exceeds ``threshold_0``, -collection starts. Initially only generation 0 is examined. If generation 0 has -been examined more than ``threshold_1`` times since generation 1 has been -examined, then generation 1 is examined as well. With generation 2, -things are a bit more complicated; see :ref:`gc-oldest-generation` for -more information. These thresholds can be examined using the -:func:`gc.get_threshold` function: - -.. code-block:: python - - >>> import gc - >>> gc.get_threshold() - (700, 10, 10) - - -The content of these generations can be examined using the -``gc.get_objects(generation=NUM)`` function and collections can be triggered -specifically in a generation by calling ``gc.collect(generation=NUM)``. - -.. code-block:: python - - >>> import gc - >>> class MyObj: - ... pass - ... - - # Move everything to the last generation so it's easier to inspect - # the younger generations. - - >>> gc.collect() - 0 - - # Create a reference cycle. - - >>> x = MyObj() - >>> x.self = x - - # Initially the object is in the youngest generation. - - >>> gc.get_objects(generation=0) - [..., <__main__.MyObj object at 0x7fbcc12a3400>, ...] - - # After a collection of the youngest generation the object - # moves to the next generation. - - >>> gc.collect(generation=0) - 0 - >>> gc.get_objects(generation=0) - [] - >>> gc.get_objects(generation=1) - [..., <__main__.MyObj object at 0x7fbcc12a3400>, ...] - - -.. _gc-oldest-generation: - -Collecting the oldest generation --------------------------------- - -In addition to the various configurable thresholds, the GC only triggers a full -collection of the oldest generation if the ratio ``long_lived_pending / long_lived_total`` -is above a given value (hardwired to 25%). The reason is that, while "non-full" -collections (that is, collections of the young and middle generations) will always -examine roughly the same number of objects (determined by the aforementioned -thresholds) the cost of a full collection is proportional to the total -number of long-lived objects, which is virtually unbounded. Indeed, it has -been remarked that doing a full collection every <constant number> of object -creations entails a dramatic performance degradation in workloads which consist -of creating and storing lots of long-lived objects (for example, building a large list -of GC-tracked objects would show quadratic performance, instead of linear as -expected). Using the above ratio, instead, yields amortized linear performance -in the total number of objects (the effect of which can be summarized thusly: -"each full garbage collection is more and more costly as the number of objects -grows, but we do fewer and fewer of them"). - -Optimization: reusing fields to save memory -=========================================== - -In order to save memory, the two linked list pointers in every object with GC -support are reused for several purposes. This is a common optimization known -as "fat pointers" or "tagged pointers": pointers that carry additional data, -"folded" into the pointer, meaning stored inline in the data representing the -address, taking advantage of certain properties of memory addressing. This is -possible as most architectures align certain types of data -to the size of the data, often a word or multiple thereof. This discrepancy -leaves a few of the least significant bits of the pointer unused, which can be -used for tags or to keep other information – most often as a bit field (each -bit a separate tag) – as long as code that uses the pointer masks out these -bits before accessing memory. For example, on a 32-bit architecture (for both -addresses and word size), a word is 32 bits = 4 bytes, so word-aligned -addresses are always a multiple of 4, hence end in ``00``, leaving the last 2 bits -available; while on a 64-bit architecture, a word is 64 bits = 8 bytes, so -word-aligned addresses end in ``000``, leaving the last 3 bits available. - -The CPython GC makes use of two fat pointers that correspond to the extra fields -of ``PyGC_Head`` discussed in the `Memory layout and object structure`_ section: - -.. warning:: - - Because the presence of extra information, "tagged" or "fat" pointers cannot be - dereferenced directly and the extra information must be stripped off before - obtaining the real memory address. Special care needs to be taken with - functions that directly manipulate the linked lists, as these functions - normally assume the pointers inside the lists are in a consistent state. - - -* The ``_gc_prev`` field is normally used as the "previous" pointer to maintain the - doubly linked list but its lowest two bits are used to keep the flags - ``PREV_MASK_COLLECTING`` and ``_PyGC_PREV_MASK_FINALIZED``. Between collections, - the only flag that can be present is ``_PyGC_PREV_MASK_FINALIZED`` that indicates - if an object has been already finalized. During collections ``_gc_prev`` is - temporarily used for storing a copy of the reference count (``gc_ref``), in - addition to two flags, and the GC linked list becomes a singly linked list until - ``_gc_prev`` is restored. - -* The ``_gc_next`` field is used as the "next" pointer to maintain the doubly linked - list but during collection its lowest bit is used to keep the - ``NEXT_MASK_UNREACHABLE`` flag that indicates if an object is tentatively - unreachable during the cycle detection algorithm. This is a drawback to using only - doubly linked lists to implement partitions: while most needed operations are - constant-time, there is no efficient way to determine which partition an object is - currently in. Instead, when that's needed, ad hoc tricks (like the - ``NEXT_MASK_UNREACHABLE`` flag) are employed. - -Optimization: delay tracking containers -======================================= - -Certain types of containers cannot participate in a reference cycle, and so do -not need to be tracked by the garbage collector. Untracking these objects -reduces the cost of garbage collection. However, determining which objects may -be untracked is not free, and the costs must be weighed against the benefits -for garbage collection. There are two possible strategies for when to untrack -a container: - -1. When the container is created. -2. When the container is examined by the garbage collector. - -As a general rule, instances of atomic types aren't tracked and instances of -non-atomic types (containers, user-defined objects...) are. However, some -type-specific optimizations can be present in order to suppress the garbage -collector footprint of simple instances. Some examples of native types that -benefit from delayed tracking: - -* Tuples containing only immutable objects (integers, strings etc, - and recursively, tuples of immutable objects) do not need to be tracked. The - interpreter creates a large number of tuples, many of which will not survive - until garbage collection. It is therefore not worthwhile to untrack eligible - tuples at creation time. Instead, all tuples except the empty tuple are tracked - when created. During garbage collection it is determined whether any surviving - tuples can be untracked. A tuple can be untracked if all of its contents are - already not tracked. Tuples are examined for untracking in all garbage collection - cycles. It may take more than one cycle to untrack a tuple. - -* Dictionaries containing only immutable objects also do not need to be tracked. - Dictionaries are untracked when created. If a tracked item is inserted into a - dictionary (either as a key or value), the dictionary becomes tracked. During a - full garbage collection (all generations), the collector will untrack any dictionaries - whose contents are not tracked. - -The garbage collector module provides the Python function ``is_tracked(obj)``, which returns -the current tracking status of the object. Subsequent garbage collections may change the -tracking status of the object. - -.. code-block:: python - - >>> gc.is_tracked(0) - False - >>> gc.is_tracked("a") - False - >>> gc.is_tracked([]) - True - >>> gc.is_tracked({}) - False - >>> gc.is_tracked({"a": 1}) - False - >>> gc.is_tracked({"a": []}) - True - - -.. _gc-differences: - -Differences between GC implementations -====================================== - -This section summarizes the differences between the GC implementation in the -default build and the implementation in the free-threaded build. - -The default build implementation makes extensive use of the ``PyGC_Head`` data -structure, while the free-threaded build implementation does not use that -data structure. - -* The default build implementation stores all tracked objects in a doubly - linked list using ``PyGC_Head``. The free-threaded build implementation - instead relies on the embedded mimalloc memory allocator to scan the heap - for tracked objects. -* The default build implementation uses ``PyGC_Head`` for the unreachable - object list. The free-threaded build implementation repurposes the - ``ob_tid`` field to store a unreachable objects linked list. -* The default build implementation stores flags in the ``_gc_prev`` field of - ``PyGC_Head``. The free-threaded build implementation stores these flags - in ``ob_gc_bits``. - - -The default build implementation relies on the :term:`global interpreter lock` -for thread safety. The free-threaded build implementation has two "stop the -world" pauses, in which all other executing threads are temporarily paused so -that the GC can safely access reference counts and object attributes. - -The default build implementation is a generational collector. The -free-threaded build is non-generational; each collection scans the entire -heap. - -* Keeping track of object generations is simple and inexpensive in the default - build. The free-threaded build relies on mimalloc for finding tracked - objects; identifying "young" objects without scanning the entire heap would - be more difficult. - - -.. admonition:: Document History - :class: note - - Pablo Galindo Salgado - Original Author +This document is now part of the +`CPython Internals Docs <https://github.com/python/cpython/blob/main/InternalDocs/garbage_collector.md>`_. From 5028ad3ba8ace33843bf963f44227f835fce9ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 14 Oct 2024 19:57:11 +0200 Subject: [PATCH 388/538] Recomend `podman` instead of `docker` and remove mentions to Docker images (#1442) * use GHCR images instead of Docker images * Address Ezio and Hugo's reviews * Address Ezio's review (round 2) --- _extensions/ubuntu_version.py | 28 --------------- conf.py | 8 ----- developer-workflow/extension-modules.rst | 43 +++++++++--------------- 3 files changed, 15 insertions(+), 64 deletions(-) delete mode 100644 _extensions/ubuntu_version.py diff --git a/_extensions/ubuntu_version.py b/_extensions/ubuntu_version.py deleted file mode 100644 index 1298f35d9..000000000 --- a/_extensions/ubuntu_version.py +++ /dev/null @@ -1,28 +0,0 @@ -"""Sphinx extension to update the required Ubuntu version. - -The required Ubuntu version should be specified in conf.py by:: - - configure_ubuntu_version = "MAJOR.MINOR" # e.g., "22.04" - -The version must match the one used to regenerate the configure script in -https://github.com/python/cpython/blob/main/Tools/build/regen-configure.sh. -""" - -from sphinx.errors import ExtensionError - - -def replace_ubuntu_version(app, docname, source): - """Replace all occurrences of $CONFIGURE_UBUNTU_VERSION$. - - This is needed since RST replacement via ``|...|`` is not supported - in code-blocks directives. - """ - if (ubuntu_version := app.config.configure_ubuntu_version) is None: - raise ExtensionError("configure_ubuntu_version is not set in conf.py") - source[0] = source[0].replace("$CONFIGURE_UBUNTU_VERSION$", ubuntu_version) - - -def setup(app): - app.add_config_value("configure_ubuntu_version", None, "env", types=(str,)) - app.connect("source-read", replace_ubuntu_version) - return {"parallel_read_safe": True, "parallel_write_safe": True} diff --git a/conf.py b/conf.py index aed6592c3..842bf1b0c 100644 --- a/conf.py +++ b/conf.py @@ -1,10 +1,6 @@ -import sys import time -sys.path.insert(0, '_extensions') - extensions = [ - 'ubuntu_version', 'notfound.extension', 'sphinx.ext.extlinks', 'sphinx.ext.intersphinx', @@ -203,7 +199,3 @@ copybutton_prompt_text = "$ " # https://sphinx-copybutton.readthedocs.io/en/latest/use.html#honor-line-continuation-characters-when-copying-multline-snippets copybutton_line_continuation_character = "\\" - -# Must be synchronized with the Ubuntu image version in -# https://github.com/python/cpython/blob/main/Tools/build/regen-configure.sh -configure_ubuntu_version = "22.04" diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index 7e32283c2..61c1ff08a 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -552,6 +552,17 @@ 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. + + .. tip:: + + We recommend installing `Podman <https://podman.io/docs/installation>`_ + 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 <clinic>`. Execute this rule if you do not know which files should be updated. @@ -590,37 +601,13 @@ by executing :cpy-file:`Tools/build/regen-configure.sh`: ./Tools/build/regen-configure.sh # create an up-to-date 'configure' ./configure # create an up-to-date 'Makefile' -``make regen-configure`` and missing permissions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Since this rule requires `Docker <https://docs.docker.com/desktop>`_ to be -running, the following can be done on Linux platforms (``systemctl``-based): - -.. code-block:: shell - - systemctl status docker # is the Docker service running? - sudo systemctl start docker # start it if it is not - sudo systemctl restart docker # or restart it if the issue persists +``make regen-configure`` and missing permissions with Docker +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If Docker complains about missing permissions, this Stack Overflow post could be useful in solving the issue: `How to fix docker: permission denied -<https://stackoverflow.com/q/48957195/9579194>`_. - -Once the Docker service is running, check that you have an `Ubuntu -$CONFIGURE_UBUNTU_VERSION$ image <https://hub.docker.com/_/ubuntu>`_, -or pull it if it is not case: - -.. code-block:: shell - - # check for the Docker image presence - docker images ubuntu:$CONFIGURE_UBUNTU_VERSION$ - # pull the Docker image if needed - docker image pull ubuntu:$CONFIGURE_UBUNTU_VERSION$ - -.. tip:: - - If the issue persists, you may try `podman <https://podman.io/>`_. - The commands for listing or pulling an image are the same as ``docker``. +<https://stackoverflow.com/q/48957195/9579194>`_. Alternatively, you may try +using `Podman <https://podman.io/docs/installation>`_. Missing ``Py_BUILD_CORE`` define when using internal headers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 293785f2deb687c7c024852f92621db002ac282e Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Wed, 16 Oct 2024 06:35:14 -0400 Subject: [PATCH 389/538] Flesh out the Contributor's Guide (#1426) A start on the new organization turning the devguide into a Contributor's Guide. Co-authored-by: Carol Willing <carolcode@willingconsulting.com> --- Makefile | 7 ++- conf.py | 20 ++++++++ contrib/code/index.rst | 18 +++++++ contrib/contrib-plan.rst | 47 +++++++++++++++++++ contrib/doc/index.rst | 18 +++++++ contrib/get-started/index.rst | 13 +++++ contrib/index.rst | 36 ++++++++++++++ contrib/intro/index.rst | 34 ++++++++++++++ contrib/outreach.rst | 12 +++++ contrib/project/channels.rst | 16 +++++++ contrib/project/conduct.rst | 16 +++++++ contrib/project/core-team/committing.rst | 11 +++++ contrib/project/core-team/developer-log.rst | 11 +++++ contrib/project/core-team/experts.rst | 11 +++++ contrib/project/core-team/index.rst | 23 +++++++++ contrib/project/core-team/join-team.rst | 16 +++++++ contrib/project/core-team/motivations.rst | 11 +++++ .../project/core-team/responsibilities.rst | 11 +++++ contrib/project/github.rst | 15 ++++++ contrib/project/governance.rst | 25 ++++++++++ contrib/project/index.rst | 25 ++++++++++ contrib/project/roles.rst | 17 +++++++ contrib/security.rst | 13 +++++ contrib/triage/index.rst | 12 +++++ contrib/triage/issue-tracker.rst | 9 ++++ contrib/triage/labels.rst | 9 ++++ contrib/triage/reviewing.rst | 13 +++++ contrib/triage/triage-team.rst | 9 ++++ contrib/triage/triaging.rst | 9 ++++ contrib/user-success.rst | 14 ++++++ core-developers/index.rst | 2 + index.rst | 1 + 32 files changed, 503 insertions(+), 1 deletion(-) create mode 100644 contrib/code/index.rst create mode 100644 contrib/contrib-plan.rst create mode 100644 contrib/doc/index.rst create mode 100644 contrib/get-started/index.rst create mode 100644 contrib/index.rst create mode 100644 contrib/intro/index.rst create mode 100644 contrib/outreach.rst create mode 100644 contrib/project/channels.rst create mode 100644 contrib/project/conduct.rst create mode 100644 contrib/project/core-team/committing.rst create mode 100644 contrib/project/core-team/developer-log.rst create mode 100644 contrib/project/core-team/experts.rst create mode 100644 contrib/project/core-team/index.rst create mode 100644 contrib/project/core-team/join-team.rst create mode 100644 contrib/project/core-team/motivations.rst create mode 100644 contrib/project/core-team/responsibilities.rst create mode 100644 contrib/project/github.rst create mode 100644 contrib/project/governance.rst create mode 100644 contrib/project/index.rst create mode 100644 contrib/project/roles.rst create mode 100644 contrib/security.rst create mode 100644 contrib/triage/index.rst create mode 100644 contrib/triage/issue-tracker.rst create mode 100644 contrib/triage/labels.rst create mode 100644 contrib/triage/reviewing.rst create mode 100644 contrib/triage/triage-team.rst create mode 100644 contrib/triage/triaging.rst create mode 100644 contrib/user-success.rst diff --git a/Makefile b/Makefile index 5f9e96546..ab38ffc88 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,12 @@ PYTHON = python3 VENVDIR = ./venv UV = uv SPHINXBUILD = $(VENVDIR)/bin/sphinx-build -SPHINXOPTS = --fail-on-warning --keep-going +# Temporary: while we are using ..include:: to show the reorganization, +# there are duplicate labels. These cause warnings, which prevent the +# build from finishing. Turn off --fail-on-warning so we can see the +# finished results. +#SPHINXOPTS = --fail-on-warning --keep-going +SPHINXOPTS = --keep-going BUILDDIR = _build BUILDER = html JOBS = auto diff --git a/conf.py b/conf.py index 842bf1b0c..74137e8b5 100644 --- a/conf.py +++ b/conf.py @@ -171,6 +171,26 @@ # sphinx-notfound-page notfound_urls_prefix = "/" +# prolog and epilogs +rst_prolog = """ +.. |draft| replace:: + This is part of a **Draft** of the Python Contributor's Guide. + Text in square brackets are notes about content to fill in. + Currently, the devguide and this new Contributor's Guide co-exist in the + repo. We are using Sphinx include directives to demonstrate the re-organization. + The final Contributor's Guide will replace the devguide with content in only one + place. + We welcome help with this! + +.. |purpose| replace:: + The :ref:`contrib-plan` page has more details about the current state of this draft + and **how you can help**. See more info about the Contributor Guide in the + discussion forum: `Refactoring the DevGuide`_. + +.. _Refactoring the DevGuide: https://discuss.python.org/t/refactoring-the-devguide-into-a-contribution-guide/63409 + +""" + # sphinx.ext.extlinks # This config is a dictionary of external sites, # mapping unique short aliases to a base URL and a prefix. diff --git a/contrib/code/index.rst b/contrib/code/index.rst new file mode 100644 index 000000000..6c23c3a87 --- /dev/null +++ b/contrib/code/index.rst @@ -0,0 +1,18 @@ +================== +Code contributions +================== + +.. important:: + + |draft| + + |purpose| + +* Code setup and building (more complex stuff, delta from basic setup above) +* More git bootcamp (patches, etc) +* Lifecycle of a code pull request +* Development workflow (from devguide) +* Testing and buildbots (from devguide) +* Development tools (from devguide) +* CPython’s internals (from devguide) +* Code style guide diff --git a/contrib/contrib-plan.rst b/contrib/contrib-plan.rst new file mode 100644 index 000000000..be35c1a8d --- /dev/null +++ b/contrib/contrib-plan.rst @@ -0,0 +1,47 @@ +.. _contrib-plan: + +================================ +Plan for the Contributor's Guide +================================ + +.. important:: + + |draft| + + |purpose| + +We are in the process of updating and refactoring the devguide to be a +Contributor's Guide. It will highlight the different kinds of contribution +possible, and how to succeed at each kind. + +Currently, the Contibutor's Guide is a draft in this new last section of the +devguide. We welcome feedback, but please understand that some of the current +content is moving or skeletal. + +Repo structure +============== + +While the reorganization is happening, we are keeping the old devguide as it +is. The new Contributor's Guide is represented in this last section, but will +eventually be the only content in the guide. To avoid copying content, we're +using Sphinx include directives to display existing devguide content in its new +Contributor's Guide location. That is not how the eventual Guide will be +built. Once we are ready to make the Contributor's Guide real, we will +rearrange content into its new location. + +How to help +=========== + +To help, you can: + +- `Write an issue`_ detailing a change you'd like to see here. +- `Make a pull request`_ in this repo to add content. +- Join us in the `Python Docs Discord`_ to collaborate with other docs-minded + community members. +- Get in touch with the `Docs Editorial Board`_ to discuss larger documentation + concerns. + +.. _Write an issue: https://github.com/python/devguide/issues +.. _Make a pull request: https://github.com/python/devguide/pulls +.. _Python Docs Discord: https://discord.gg/NeGgyhUZ +.. _Docs Editorial Board: https://python.github.io/editorial-board/ diff --git a/contrib/doc/index.rst b/contrib/doc/index.rst new file mode 100644 index 000000000..e5d60e42f --- /dev/null +++ b/contrib/doc/index.rst @@ -0,0 +1,18 @@ +=========================== +Documentation contributions +=========================== + +.. important:: + + |draft| + + |purpose| + + +* Lifecycle of a docs pull request +* (pull in Documentation sections from devguide) +* Rst/Sphinx bootcamp +* Editorial Style Guide +* Translation + - How to add a new language + - Tools and workflow diff --git a/contrib/get-started/index.rst b/contrib/get-started/index.rst new file mode 100644 index 000000000..84c5afd70 --- /dev/null +++ b/contrib/get-started/index.rst @@ -0,0 +1,13 @@ +=============== +Getting started +=============== + +.. important:: + + |draft| + + |purpose| + + +* Basic setup +* Git bootcamp (simplified for everyone to use) diff --git a/contrib/index.rst b/contrib/index.rst new file mode 100644 index 000000000..1c169ffbe --- /dev/null +++ b/contrib/index.rst @@ -0,0 +1,36 @@ +================================== +Python Contributor's Guide (draft) +================================== + +.. important:: + + |draft| + + |purpose| + + +This guide is a comprehensive resource for contributing to Python. + +.. note:: + This is a draft of a new organization for the devguide, turning it into a + Contributor's Guide. + +[Much of the devguide home page will be here. The Quick Start will be updated +to distinguish code vs documentation contributions, and moved to those +sections. Other changes will be made to explain the different types of +contribution and how to navigate the guide for your own type.] + + +.. toctree:: + :maxdepth: 2 + + contrib-plan + intro/index + project/index + get-started/index + triage/index + code/index + doc/index + user-success + security + outreach diff --git a/contrib/intro/index.rst b/contrib/intro/index.rst new file mode 100644 index 000000000..0a733adaa --- /dev/null +++ b/contrib/intro/index.rst @@ -0,0 +1,34 @@ +============ +Introduction +============ + +.. important:: + + |draft| + + |purpose| + + + + +Welcome! + +Healthy Collaboration +===================== + +[Importance of healthy inclusive collaboration] + +[While code is a large part of the project's success, project management, documentation, governance, sprint outreach, etc. matter.] + +[We respect the individual skills people bring to the project and strive to create and maintain a culture of inclusion.] + +About this Guide +================ + +Types of Contribution +===================== + +[Pathways for contributors] + +Helping with this Guide +======================= diff --git a/contrib/outreach.rst b/contrib/outreach.rst new file mode 100644 index 000000000..d43aa8e9d --- /dev/null +++ b/contrib/outreach.rst @@ -0,0 +1,12 @@ +======== +Outreach +======== + +.. important:: + + |draft| + + |purpose| + + +* Sprints diff --git a/contrib/project/channels.rst b/contrib/project/channels.rst new file mode 100644 index 000000000..711dbe587 --- /dev/null +++ b/contrib/project/channels.rst @@ -0,0 +1,16 @@ +.. important:: + + |draft| + + |purpose| + + +====================== +Communication channels +====================== + +* Repos +* Discourse +* Discord +* Mailing lists (deprioritize) +* Where to get help diff --git a/contrib/project/conduct.rst b/contrib/project/conduct.rst new file mode 100644 index 000000000..37fe3bbfa --- /dev/null +++ b/contrib/project/conduct.rst @@ -0,0 +1,16 @@ +=============== +Code of Conduct +=============== + +.. important:: + + |draft| + + |purpose| + + +[Brief summary of the code of conduct, with links to official source.] + +* Standard for communication +* How to report +* Enforcement details diff --git a/contrib/project/core-team/committing.rst b/contrib/project/core-team/committing.rst new file mode 100644 index 000000000..569f6e27d --- /dev/null +++ b/contrib/project/core-team/committing.rst @@ -0,0 +1,11 @@ +.. important:: + + |draft| + + |purpose| + + +[This is the existing core developers :ref:`committing` page from the devguide. We'll +adjust "core developer" to "core team" where appropriate.] + +.. include:: ../../../core-developers/committing.rst diff --git a/contrib/project/core-team/developer-log.rst b/contrib/project/core-team/developer-log.rst new file mode 100644 index 000000000..00d780303 --- /dev/null +++ b/contrib/project/core-team/developer-log.rst @@ -0,0 +1,11 @@ +.. 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/project/core-team/experts.rst b/contrib/project/core-team/experts.rst new file mode 100644 index 000000000..358fdd17f --- /dev/null +++ b/contrib/project/core-team/experts.rst @@ -0,0 +1,11 @@ +.. important:: + + |draft| + + |purpose| + + +[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 diff --git a/contrib/project/core-team/index.rst b/contrib/project/core-team/index.rst new file mode 100644 index 000000000..281ed0f47 --- /dev/null +++ b/contrib/project/core-team/index.rst @@ -0,0 +1,23 @@ +.. important:: + + |draft| + + |purpose| + + +========= +Core team +========= + +[This is mostly re-organized from the :ref:`core-dev` section of the devguide, +but with "core developer" language changed to "core team" where possible.] + +.. toctree:: + :maxdepth: 5 + + responsibilities + committing + experts + developer-log + motivations + join-team diff --git a/contrib/project/core-team/join-team.rst b/contrib/project/core-team/join-team.rst new file mode 100644 index 000000000..1905c92a9 --- /dev/null +++ b/contrib/project/core-team/join-team.rst @@ -0,0 +1,16 @@ +.. important:: + + |draft| + + |purpose| + + +[This is the existing core developers :ref:`become-core-developer` page from the devguide with the title changed. 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 diff --git a/contrib/project/core-team/motivations.rst b/contrib/project/core-team/motivations.rst new file mode 100644 index 000000000..79af3ccfd --- /dev/null +++ b/contrib/project/core-team/motivations.rst @@ -0,0 +1,11 @@ +.. important:: + + |draft| + + |purpose| + + +[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 diff --git a/contrib/project/core-team/responsibilities.rst b/contrib/project/core-team/responsibilities.rst new file mode 100644 index 000000000..ca974b35c --- /dev/null +++ b/contrib/project/core-team/responsibilities.rst @@ -0,0 +1,11 @@ +.. important:: + + |draft| + + |purpose| + + +[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 diff --git a/contrib/project/github.rst b/contrib/project/github.rst new file mode 100644 index 000000000..fe45c6b8b --- /dev/null +++ b/contrib/project/github.rst @@ -0,0 +1,15 @@ +.. important:: + + |draft| + + |purpose| + +====== +GitHub +====== + +[Where are the actual artifacts?] + +* Main CPython repos +* Core workflow repos +* Infrastructure repos diff --git a/contrib/project/governance.rst b/contrib/project/governance.rst new file mode 100644 index 000000000..a4bc66ff1 --- /dev/null +++ b/contrib/project/governance.rst @@ -0,0 +1,25 @@ +.. important:: + + |draft| + + |purpose| + + +========== +Governance +========== + +[How decisions are made, who is involved, how to participate.] + +Steering Council +================ + +Documentation Editorial Board +============================= + +Typing Council +============== + + +Others? +======= diff --git a/contrib/project/index.rst b/contrib/project/index.rst new file mode 100644 index 000000000..082be327e --- /dev/null +++ b/contrib/project/index.rst @@ -0,0 +1,25 @@ +=================== +The CPython project +=================== + +.. important:: + + |draft| + + |purpose| + + +[Give the reader an understanding of the project as a whole. What are the +moving parts, who is involved, how do they interact?] + +* Structure + +.. toctree:: + :maxdepth: 5 + + conduct + roles + core-team/index + governance + github + channels diff --git a/contrib/project/roles.rst b/contrib/project/roles.rst new file mode 100644 index 000000000..8336fe465 --- /dev/null +++ b/contrib/project/roles.rst @@ -0,0 +1,17 @@ +===== +Roles +===== + +.. important:: + + |draft| + + |purpose| + + +[Quick overview of the roles people play. Core team has its own section.] + +* Core team +* Triager +* Contributors + * types of contributions diff --git a/contrib/security.rst b/contrib/security.rst new file mode 100644 index 000000000..db40b4a16 --- /dev/null +++ b/contrib/security.rst @@ -0,0 +1,13 @@ +========================================= +Security and infrastructure contributions +========================================= + +.. important:: + + |draft| + + |purpose| + +* Security +* Infrastructure +* Core workflow diff --git a/contrib/triage/index.rst b/contrib/triage/index.rst new file mode 100644 index 000000000..9257978a6 --- /dev/null +++ b/contrib/triage/index.rst @@ -0,0 +1,12 @@ +=================== +Issues and triaging +=================== + +.. toctree:: + :maxdepth: 5 + + issue-tracker + triaging + labels + reviewing + triage-team diff --git a/contrib/triage/issue-tracker.rst b/contrib/triage/issue-tracker.rst new file mode 100644 index 000000000..a5777bc81 --- /dev/null +++ b/contrib/triage/issue-tracker.rst @@ -0,0 +1,9 @@ +.. important:: + + |draft| + + |purpose| + +[This is the existing :ref:`issue-tracker` page from the devguide] + +.. include:: ../../triage/issue-tracker.rst diff --git a/contrib/triage/labels.rst b/contrib/triage/labels.rst new file mode 100644 index 000000000..c36481733 --- /dev/null +++ b/contrib/triage/labels.rst @@ -0,0 +1,9 @@ +.. important:: + + |draft| + + |purpose| + +[This is the existing :ref:`labels` page from the devguide] + +.. include:: ../../triage/labels.rst diff --git a/contrib/triage/reviewing.rst b/contrib/triage/reviewing.rst new file mode 100644 index 000000000..060f6b78d --- /dev/null +++ b/contrib/triage/reviewing.rst @@ -0,0 +1,13 @@ +.. important:: + + |draft| + + |purpose| + + +========= +Reviewing +========= + +* How? Etiquette? +* How to request a review? diff --git a/contrib/triage/triage-team.rst b/contrib/triage/triage-team.rst new file mode 100644 index 000000000..a9b59056a --- /dev/null +++ b/contrib/triage/triage-team.rst @@ -0,0 +1,9 @@ +.. important:: + + |draft| + + |purpose| + +[This is the existing :ref:`triage-team` page from the devguide] + +.. include:: ../../triage/triage-team.rst diff --git a/contrib/triage/triaging.rst b/contrib/triage/triaging.rst new file mode 100644 index 000000000..22e1ccc65 --- /dev/null +++ b/contrib/triage/triaging.rst @@ -0,0 +1,9 @@ +.. important:: + + |draft| + + |purpose| + +[This is the existing :ref:`triaging` page from the devguide] + +.. include:: ../../triage/triaging.rst diff --git a/contrib/user-success.rst b/contrib/user-success.rst new file mode 100644 index 000000000..2a9ef5d4e --- /dev/null +++ b/contrib/user-success.rst @@ -0,0 +1,14 @@ +======================================= +Accessibility, design, and user success +======================================= + +.. important:: + + |draft| + + |purpose| + + +* Accessibility +* Design +* User success diff --git a/core-developers/index.rst b/core-developers/index.rst index 2b3ac7b79..8555943a0 100644 --- a/core-developers/index.rst +++ b/core-developers/index.rst @@ -1,3 +1,5 @@ +.. _core-dev: + =============== Core developers =============== diff --git a/index.rst b/index.rst index b385b1ee1..c10736a47 100644 --- a/index.rst +++ b/index.rst @@ -315,6 +315,7 @@ Full table of contents core-developers/index internals/index versions + contrib/index .. _Buildbot status: https://www.python.org/dev/buildbot/ .. _Misc directory: https://github.com/python/cpython/tree/main/Misc From 0ad84cdd913dfd58df1fe4862eb7bf06cc8f4882 Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Wed, 16 Oct 2024 20:55:04 -0400 Subject: [PATCH 390/538] More uniform terminology: patch and changeset #1443 (#1446) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com> --- contrib/code/index.rst | 2 +- core-developers/become-core-developer.rst | 2 +- core-developers/committing.rst | 12 ++++++------ core-developers/motivations.rst | 6 +++--- core-developers/responsibilities.rst | 6 +++--- developer-workflow/development-cycle.rst | 6 +++--- developer-workflow/psrt.rst | 14 +++++++------- developer-workflow/stdlib.rst | 6 +++--- getting-started/fixing-issues.rst | 6 +++--- getting-started/git-boot-camp.rst | 8 ++++---- getting-started/pull-request-lifecycle.rst | 10 +++++----- getting-started/setup-building.rst | 4 ++-- index.rst | 2 +- testing/buildbots.rst | 10 +++++----- triage/triaging.rst | 2 +- 15 files changed, 48 insertions(+), 48 deletions(-) diff --git a/contrib/code/index.rst b/contrib/code/index.rst index 6c23c3a87..e7969406f 100644 --- a/contrib/code/index.rst +++ b/contrib/code/index.rst @@ -9,7 +9,7 @@ Code contributions |purpose| * Code setup and building (more complex stuff, delta from basic setup above) -* More git bootcamp (patches, etc) +* More Git bootcamp (pull requests, etc) * Lifecycle of a code pull request * Development workflow (from devguide) * Testing and buildbots (from devguide) diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index a9460b377..40cedeb51 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -8,7 +8,7 @@ How to become a core developer What it takes ============= -When you have consistently contributed patches which meet quality standards +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) diff --git a/core-developers/committing.rst b/core-developers/committing.rst index cf859ab9f..326578c0b 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -31,11 +31,11 @@ to enter the public source tree. Ask yourself the following questions: * **Do the checks on the pull request show that the test suite passes?** Make sure that all of the status checks are passing. -* **Is the patch in a good state?** - Check :ref:`patch` and :ref:`helptriage` to review what is expected of - a patch. +* **Is the pull request in a good state?** + Check :ref:`pull-request-lifecycle` and :ref:`helptriage` to review what + is expected of a pull request. -* **Does the patch break backwards-compatibility without a strong reason?** +* **Does the change break backwards-compatibility without a strong reason?** :ref:`Run the entire test suite <runtests>` to make sure that everything still passes. If there is a change to the semantics, then there needs to be a strong reason, because it will cause some peoples' code to break. @@ -165,7 +165,7 @@ number since it is part of the file name. You can use entry:: Fix warning message when :func:`os.chdir` fails inside - :func:`test.support.temp_cwd`. Patch by Chris Jerdonek. + :func:`test.support.temp_cwd`. Contributed by Chris Jerdonek. The inline Sphinx roles like ``:func:`` can be used help readers find more information. You can build HTML and verify that the @@ -182,7 +182,7 @@ As a core developer, you have the ability to push changes to the official Python repositories, so you need to be careful with your workflow: * **You should not push new branches to the main repository.** You can - still use them in the fork that you use for the development of patches. + still use them in the fork that you use for your own development. You can also push these branches to a separate public repository for maintenance work before it is integrated into the main repository. diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index b805a7c67..24f1ad2c8 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -279,11 +279,11 @@ Goals of this page The `issue metrics`_ automatically collected by the CPython issue tracker strongly suggest that the current core development process is bottlenecked on -core developer time - this is most clearly indicated in the first metrics graph, -which shows both the number of open issues and the number of patches awaiting +core developer time. This is most clearly indicated in the first metrics graph, +which shows both the number of open issues and the number of pull requests awaiting review growing steadily over time, despite CPython being one of the most active open source projects in the world. This bottleneck then impacts not only -resolving open issues and applying submitted patches, but also the process of +resolving open issues and accepting submitted pull requests, but also the process of identifying, nominating and mentoring new core developers. The core commit statistics monitored by sites like `OpenHub`_ provide a good diff --git a/core-developers/responsibilities.rst b/core-developers/responsibilities.rst index 1ea1a0994..5cd5ed7bd 100644 --- a/core-developers/responsibilities.rst +++ b/core-developers/responsibilities.rst @@ -7,8 +7,8 @@ Responsibilities As contributors to the CPython project, our shared responsibility is to collaborate constructively with other contributors, including core developers. This responsibility covers all forms of contribution, whether that's submitting -patches to the implementation or documentation, reviewing other peoples' -patches, triaging issues on the issue tracker, or discussing design and +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 <communication-channels>`. @@ -68,7 +68,7 @@ the ability to license your code means it can be put under the PSF license so it can be legally distributed with Python. This is a very important step! Hopefully you have already submitted a -contributor agreement if you have been submitting patches. But if you have not +contributor agreement if you have been submitting pull requests. But if you have not done this yet, it is best to do this ASAP, probably before you even do your first commit so as to not forget. Also do not forget to enter your GitHub username into your details on the issue tracker. diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index c7cf6a8b2..6d5b04a2a 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -118,7 +118,7 @@ Commits to security branches are to be coordinated with the release manager for the corresponding feature version, as listed in the :ref:`branchstatus`. Merging of pull requests to security branches is restricted to release managers. Any release made from a security branch is source-only and done only when actual -security patches have been applied to the branch. These releases have a +security fixes have been applied to the branch. These releases have a **micro version** number greater than the last **bugfix** release. .. _eolbranch: @@ -151,8 +151,8 @@ Pre-alpha The branch is in this stage when no official release has been done since the latest final release. There are no special restrictions placed on -commits, although the usual advice applies (getting patches reviewed, avoiding -breaking the buildbots). +commits, although the usual advice applies (getting pull requests reviewed, +avoiding breaking the buildbots). .. _alpha: diff --git a/developer-workflow/psrt.rst b/developer-workflow/psrt.rst index 9347a9a81..f469f68d1 100644 --- a/developer-workflow/psrt.rst +++ b/developer-workflow/psrt.rst @@ -68,24 +68,24 @@ severity, advisory text, and fixes. * Affected components and APIs. The module, function, class, or method must be specified so users can search their codebase for usage. For issues affecting the entire project, this can be omitted. - * Mitigations for the vulnerability beyond upgrading to a patched version, if applicable. + * Mitigations for the vulnerability beyond upgrading to a fixed version, if applicable. This can all be done within the GitHub Security Advisory UI for easier collaboration between reporter and coordinator. -* The coordinator determines the fix approach and who will provide a patch. - Some reporters are willing to provide or collaborate to create a patch, +* 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 the coordinator. * For **Low** and **Medium** severity vulnerabilities it is acceptable - to develop a patch in public. + to develop a fix in public. The pull request must be marked with the ``security`` and ``release-blocker`` - labels so that a release is not created without including the patch. + labels so that a release is not created without including the fix. - * For **High** and **Critical** severity vulnerabilities the patch must be + * 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" - to work on the fix together. Once a patch is approved privately and tested, + 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 732ee8f45..1e841d8b2 100644 --- a/developer-workflow/stdlib.rst +++ b/developer-workflow/stdlib.rst @@ -36,7 +36,7 @@ You have a several options for this: If you have found general acceptance and usefulness for your code from people, you can open an issue on the `issue tracker`_ with the code attached as a -:ref:`pull request <patch>`. If possible, also submit a +:ref:`pull request <pullrequest>`. If possible, also submit a :ref:`contributor agreement <contributor_agreement>`. If a core developer decides that your code would be useful to the general @@ -91,7 +91,7 @@ In order for a module to even be considered for inclusion into the stdlib, a couple of requirements must be met. The most basic is that the code must meet -:ref:`standard patch requirements <patch>`. For code that has +:ref:`standard pull request requirements <pullrequest>`. For code that has been developed outside the stdlib typically this means making sure the coding style guides are followed and that the proper tests have been written. @@ -112,7 +112,7 @@ infrastructure (that is, the module is no longer directly maintained outside of Python). This prevents a divergence between the code that is included in the stdlib and that which is released outside the stdlib (typically done to provide the module to older versions of Python). It also removes the burden of forcing -core developers to have to redirect bug reports or patches to an external issue +core developers 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 diff --git a/getting-started/fixing-issues.rst b/getting-started/fixing-issues.rst index 6b752d79d..f277cbf60 100644 --- a/getting-started/fixing-issues.rst +++ b/getting-started/fixing-issues.rst @@ -6,7 +6,7 @@ Fixing "easy" issues (and beyond) ================================= When you feel comfortable enough to want to help tackle issues by trying to -create a patch to fix an issue, you can start by looking at the `"easy" +create a pull request to fix an issue, you can start by looking at the `"easy" issues`_. These issues *should* be ones where it should take no longer than a day or weekend to fix. But because the "easy" classification is typically done at triage time it can turn out to be inaccurate, so do feel free to leave a @@ -17,8 +17,8 @@ are not considered easy and try to fix those. It must be warned, though, that it is quite possible that a bug that has been left open has been left into that state because of the difficulty compared to the benefit of the fix. It could also still be open because no consensus has been reached on how to fix the -issue (although having a patch that proposes a fix can turn the tides of the -discussion to help bring it to a close). Regardless of why the issue is open, +issue, although having a pull request that proposes a fix can turn the tides of the +discussion to help bring it to a close. Regardless of why the issue is open, you can also always provide useful comments if you do attempt a fix, successful or not. diff --git a/getting-started/git-boot-camp.rst b/getting-started/git-boot-camp.rst index 15952d6bd..87177840c 100644 --- a/getting-started/git-boot-camp.rst +++ b/getting-started/git-boot-camp.rst @@ -132,7 +132,7 @@ Enabling ``autocrlf`` on Windows The ``autocrlf`` option will fix automatically any Windows-specific line endings. This should be enabled on Windows, since the public repository has a hook which -will reject all changesets having the wrong line endings:: +will reject all commits having the wrong line endings:: $ git config --global core.autocrlf input @@ -356,7 +356,7 @@ Scenario: the upstream CPython repository. Please do not try to solve this by creating a pull request from -``python:main`` to ``<username>:main`` as the authors of the patches will +``python:main`` to ``<username>:main`` as the authors of the pull requests will get notified unnecessarily. Solution:: @@ -435,8 +435,8 @@ Solution: .. _git_pr: -Downloading other's patches ---------------------------- +Checking out others' pull requests +---------------------------------- Scenario: diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index cd037789f..5728cb9da 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -243,8 +243,8 @@ should do to help ensure that your pull request is accepted. ``patchcheck`` ============== -``patchcheck`` is a simple automated patch checklist that guides a developer -through the common patch generation checks. To run ``patchcheck``: +``patchcheck`` is a simple automated checklist for changes in progress that +guides a developer through common checks. To run ``patchcheck``: On *Unix* (including macOS):: @@ -256,7 +256,7 @@ On *Windows* (after any successful build): .\python.bat Tools\patchcheck\patchcheck.py -The automated patch checklist runs through: +The automated checklist runs through: * Are there any whitespace problems in Python files? (using :cpy-file:`Tools/patchcheck/reindent.py`) @@ -271,10 +271,10 @@ The automated patch checklist runs through: * Has ``configure`` been regenerated, if necessary? * Has ``pyconfig.h.in`` been regenerated, if necessary? -The automated patch check doesn't actually *answer* all of these +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 patch. +making a complete pull request. .. _good-commits: diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 8c55bc625..03b2777b8 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -127,7 +127,7 @@ changes to Python code will be picked up by the interpreter for immediate use and testing. (If you change C code, you will need to recompile the affected files as described below.) -Patches for the documentation can be made from the same repository; see +Changes for the documentation can be made from the same repository; see :ref:`documenting`. .. _install-pre-commit: @@ -1033,7 +1033,7 @@ you'd prefer to use that directly. Create a CPython codespace -------------------------- -Here are the basic steps needed to contribute a patch using Codespaces. +Here are the basic steps needed to contribute a pull request using Codespaces. You first need to navigate to the `CPython repo <https://github.com/python/cpython>`_ hosted on GitHub. diff --git a/index.rst b/index.rst index c10736a47..ec07d41f9 100644 --- a/index.rst +++ b/index.rst @@ -22,7 +22,7 @@ community that maintains Python. We welcome your contributions to Python! Quick reference --------------- -Here are the basic steps needed to get set up and contribute a patch. +Here are the basic steps needed to get set up and contribute a pull request. This is meant as a checklist, once you know the basics. For complete instructions please see the :ref:`setup guide <setup>`. diff --git a/testing/buildbots.rst b/testing/buildbots.rst index 22962faaf..97856f713 100644 --- a/testing/buildbots.rst +++ b/testing/buildbots.rst @@ -16,7 +16,7 @@ will schedule a new build to be run as soon as possible. The build steps run by the buildbots are the following: -* Check out the source tree for the changeset which triggered the build +* Check out the source tree for the change which triggered the build * Compile Python * Run the test suite using :ref:`strenuous settings <strenuous_testing>` * Clean up the build tree @@ -56,7 +56,7 @@ There are three ways of visualizing recent build results: * The Web interface for each branch at https://www.python.org/dev/buildbot/, where the so-called "waterfall" view presents a vertical rundown of recent builds for each builder. When interested in one build, you'll have to - click on it to know which changesets it corresponds to. Note that + click on it to know which commits it corresponds to. Note that the buildbot web pages are often slow to load, be patient. * The command-line ``bbreport.py`` client, which you can get from @@ -78,16 +78,16 @@ There are three ways of visualizing recent build results: If you like IRC, having an IRC client open to the #python-dev-notifs channel on irc.libera.chat is useful. Any time a builder changes state (last build passed and this one didn't, or vice versa), a message is posted to the channel. -Keeping an eye on the channel after pushing a changeset is a simple way to get +Keeping an eye on the channel after pushing a commits is a simple way to get notified that there is something you should look in to. Some buildbots are much faster than others. Over time, you will learn which ones produce the quickest results after a build, and which ones take the longest time. -Also, when several changesets are pushed in a quick succession in the same +Also, when several commits are pushed in a quick succession in the same branch, it often happens that a single build is scheduled for all these -changesets. +commits. Stability ========= diff --git a/triage/triaging.rst b/triage/triaging.rst index d313ef70e..c560d8c1d 100644 --- a/triage/triaging.rst +++ b/triage/triaging.rst @@ -92,7 +92,7 @@ you can help by making sure the pull request: * includes proper tests * includes proper documentation changes * includes a :ref:`NEWS entry <news-entry>` (if needed) -* includes the author in ``Misc/ACKS``, either already or the patch adds them +* 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 <keeping-ci-green>` From d20061fa0b612c5274c71c08d6b3d7eb3275d475 Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Sat, 19 Oct 2024 07:17:12 -0400 Subject: [PATCH 391/538] contrib guide: populate the Code section (#1450) There is a warning about a duplicate target, but it doesn't seem to cause issues in the built project. Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- contrib/code/developer-workflow.rst | 25 +++++++++++++++++++++++++ contrib/code/development-tools.rst | 19 +++++++++++++++++++ contrib/code/git.rst | 11 +++++++++++ contrib/code/index.rst | 25 +++++++++++++++++-------- contrib/code/setup.rst | 12 ++++++++++++ contrib/code/testing.rst | 20 ++++++++++++++++++++ developer-workflow/index.rst | 2 ++ development-tools/index.rst | 2 ++ getting-started/index.rst | 2 ++ index.rst | 2 ++ testing/index.rst | 2 ++ 11 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 contrib/code/developer-workflow.rst create mode 100644 contrib/code/development-tools.rst create mode 100644 contrib/code/git.rst create mode 100644 contrib/code/setup.rst create mode 100644 contrib/code/testing.rst diff --git a/contrib/code/developer-workflow.rst b/contrib/code/developer-workflow.rst new file mode 100644 index 000000000..416ca2c02 --- /dev/null +++ b/contrib/code/developer-workflow.rst @@ -0,0 +1,25 @@ +==================== +Development workflow +==================== + +.. important:: + + |draft| + + |purpose| + +[This is the existing :ref:`dev-workflow` page from the devguide] + +.. toctree:: + :maxdepth: 5 + + ../../developer-workflow/communication-channels + ../../developer-workflow/development-cycle + ../../developer-workflow/stdlib + ../../developer-workflow/extension-modules + ../../developer-workflow/c-api + ../../developer-workflow/lang-changes + ../../developer-workflow/grammar + ../../developer-workflow/porting + ../../developer-workflow/sbom + ../../developer-workflow/psrt diff --git a/contrib/code/development-tools.rst b/contrib/code/development-tools.rst new file mode 100644 index 000000000..348ceb95a --- /dev/null +++ b/contrib/code/development-tools.rst @@ -0,0 +1,19 @@ +================= +Development tools +================= + +.. important:: + + |draft| + + |purpose| + +[This is the existing :ref:`development-tools` page from the devguide.] + +.. toctree:: + :maxdepth: 5 + + ../../development-tools/clinic + ../../development-tools/gdb + ../../development-tools/clang + ../../development-tools/warnings diff --git a/contrib/code/git.rst b/contrib/code/git.rst new file mode 100644 index 000000000..7c7aaa57b --- /dev/null +++ b/contrib/code/git.rst @@ -0,0 +1,11 @@ +======== +Git tips +======== + +.. important:: + + |draft| + + |purpose| + +[More git help for advanced things needed by code contributors.] diff --git a/contrib/code/index.rst b/contrib/code/index.rst index e7969406f..4839d1bf0 100644 --- a/contrib/code/index.rst +++ b/contrib/code/index.rst @@ -8,11 +8,20 @@ Code contributions |purpose| -* Code setup and building (more complex stuff, delta from basic setup above) -* More Git bootcamp (pull requests, etc) -* Lifecycle of a code pull request -* Development workflow (from devguide) -* Testing and buildbots (from devguide) -* Development tools (from devguide) -* CPython’s internals (from devguide) -* Code style guide +[The main page for code contributors.] + +[We'll include code-focused content from the :ref:`main devguide page <devguide-main>`: Quick +reference, Quick links, Proposing changes, and so on.] + +[The existing "CPython's internals" section of the devguide will be fully +migrated into the Python repo.] + + +.. toctree:: + :maxdepth: 5 + + setup + git + developer-workflow + testing + development-tools diff --git a/contrib/code/setup.rst b/contrib/code/setup.rst new file mode 100644 index 000000000..2d14bb0d9 --- /dev/null +++ b/contrib/code/setup.rst @@ -0,0 +1,12 @@ +================== +Setup and building +================== + +.. important:: + + |draft| + + |purpose| + +[More setup and build instructions specifically for code contributors, building +on the basics from the :ref:`Getting Started <getting-started>` section.] diff --git a/contrib/code/testing.rst b/contrib/code/testing.rst new file mode 100644 index 000000000..575d1477a --- /dev/null +++ b/contrib/code/testing.rst @@ -0,0 +1,20 @@ +===================== +Testing and buildbots +===================== + +.. important:: + + |draft| + + |purpose| + +[This is the existing :ref:`testing` page from the devguide.] + +.. toctree:: + :maxdepth: 5 + + ../../testing/run-write-tests + ../../testing/silence-warnings + ../../testing/coverage + ../../testing/buildbots + ../../testing/new-buildbot-worker diff --git a/developer-workflow/index.rst b/developer-workflow/index.rst index ca39a7275..e73927f1d 100644 --- a/developer-workflow/index.rst +++ b/developer-workflow/index.rst @@ -1,3 +1,5 @@ +.. _dev-workflow: + ==================== Development workflow ==================== diff --git a/development-tools/index.rst b/development-tools/index.rst index 610d8d8ea..5031227a1 100644 --- a/development-tools/index.rst +++ b/development-tools/index.rst @@ -1,3 +1,5 @@ +.. _development-tools: + ================= Development tools ================= diff --git a/getting-started/index.rst b/getting-started/index.rst index 18f7d5cd5..61eb1d9ab 100644 --- a/getting-started/index.rst +++ b/getting-started/index.rst @@ -1,3 +1,5 @@ +.. _getting-started: + =============== Getting started =============== diff --git a/index.rst b/index.rst index ec07d41f9..9dbc06908 100644 --- a/index.rst +++ b/index.rst @@ -1,3 +1,5 @@ +.. _devguide-main: + ======================== Python Developer's Guide ======================== diff --git a/testing/index.rst b/testing/index.rst index 770c25800..55bdd3d08 100644 --- a/testing/index.rst +++ b/testing/index.rst @@ -1,3 +1,5 @@ +.. _testing: + ===================== Testing and buildbots ===================== From 1ffa42a43a2afe531ddcb11f4b989606e8b3d9ce Mon Sep 17 00:00:00 2001 From: Carol Willing <carolcode@willingconsulting.com> Date: Tue, 22 Oct 2024 00:10:37 -0700 Subject: [PATCH 392/538] Add a brief page on Generative AI usage (#1451) * Add a brief page on Generative AI usage * Apply suggestions from code review from Jelle and Hugo Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com> * Add suggested wording from jelle --------- Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com> --- getting-started/generative-ai.rst | 26 ++++++++++++++++++++++++++ getting-started/index.rst | 1 + 2 files changed, 27 insertions(+) create mode 100644 getting-started/generative-ai.rst diff --git a/getting-started/generative-ai.rst b/getting-started/generative-ai.rst new file mode 100644 index 000000000..90fe020f3 --- /dev/null +++ b/getting-started/generative-ai.rst @@ -0,0 +1,26 @@ +.. _generative-ai: + +============= +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. + +Acceptable uses +=============== + +Some of the acceptable uses of generative AI include: + +- Assistance with writing comments, especially in a non-native language +- Gaining understanding of existing code +- Supplementing contributor knowledge for code, tests, and documentation + +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. diff --git a/getting-started/index.rst b/getting-started/index.rst index 61eb1d9ab..05ee67a3b 100644 --- a/getting-started/index.rst +++ b/getting-started/index.rst @@ -12,3 +12,4 @@ Getting started git-boot-camp pull-request-lifecycle getting-help + generative-ai From 0dd2b95cd1f613b56c26e3090a8020bc78588156 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:39:51 +0100 Subject: [PATCH 393/538] gh-119786: move interpreter doc from devguide to InternalDocs (#1452) --- internals/interpreter.rst | 330 +------------------------------------- 1 file changed, 4 insertions(+), 326 deletions(-) diff --git a/internals/interpreter.rst b/internals/interpreter.rst index 477a688d9..68273d8ec 100644 --- a/internals/interpreter.rst +++ b/internals/interpreter.rst @@ -1,330 +1,8 @@ .. _interpreter: -=============================== -The bytecode interpreter (3.11) -=============================== - -.. highlight:: c - -Preface -======= - -The CPython 3.11 bytecode interpreter (a.k.a. virtual machine) has a number of improvements over 3.10. -We describe the inner workings of the 3.11 interpreter here, with an emphasis on understanding not just the code but its design. -While the interpreter is forever evolving, and the 3.12 design will undoubtedly be different again, knowing the 3.11 design will help you understand future improvements to the interpreter. - -Other sources -------------- - -* Brandt Bucher's talk about the specializing interpreter at PyCon US 2023. - `Slides <https://github.com/brandtbucher/brandtbucher/blob/master/2023/04/21/inside_cpython_311s_new_specializing_adaptive_interpreter.pdf>`_ - `Video <https://www.youtube.com/watch?v=PGZPSWZSkJI&t=1470s>`_ - -Introduction -============ - -The job of the bytecode interpreter, in :cpy-file:`Python/ceval.c`, is to execute Python code. -Its main input is a code object, although this is not a direct argument to the interpreter. -The interpreter is structured as a (recursive) function taking a thread state (``tstate``) and a stack frame (``frame``). -The function also takes an integer ``throwflag``, which is used by the implementation of ``generator.throw``. -It returns a new reference to a Python object (``PyObject *``) or an error indicator, ``NULL``. -Per :pep:`523`, this function is configurable by setting ``interp->eval_frame``; we describe only the default function, ``_PyEval_EvalFrameDefault()``. -(This function's signature has evolved and no longer matches what PEP 523 specifies; the thread state argument is added and the stack frame argument is no longer an object.) - -The interpreter finds the code object by looking in the stack frame (``frame->f_code``). -Various other items needed by the interpreter (for example, globals and builtins) are also accessed via the stack frame. -The thread state stores exception information and a variety of other information, such as the recursion depth. -The thread state is also used to access per-interpreter state (``tstate->interp``) and per-runtime (that is, truly global) state (``tstate->interp->runtime``). - -Note the slightly confusing terminology here. -"Interpreter" refers to the bytecode interpreter, a recursive function. -"Interpreter state" refers to state shared by threads, each of which may be running its own bytecode interpreter. -A single process may even host multiple interpreters, each with their own interpreter state, but sharing runtime state. -The topic of multiple interpreters is covered by several PEPs, notably :pep:`684`, :pep:`630`, and :pep:`554` (with more coming). -The current document focuses on the bytecode interpreter. - -Code objects -============ - -The interpreter uses a code object (``frame->f_code``) as its starting point. -Code objects contain many fields used by the interpreter, as well as some for use by debuggers and other tools. -In 3.11, the final field of a code object is an array of indeterminate length containing the bytecode, ``code->co_code_adaptive``. -(In previous versions the code object was a :class:`bytes` object, ``code->co_code``; it was changed to save an allocation and to allow it to be mutated.) - -Code objects are typically produced by the bytecode :ref:`compiler <compiler>`, although they are often written to disk by one process and read back in by another. -The disk version of a code object is serialized using the :mod:`marshal` protocol. -Some code objects are pre-loaded into the interpreter using ``Tools/scripts/deepfreeze.py``, which writes ``Python/deepfreeze/deepfreeze.c``. - -Code objects are nominally immutable. -Some fields (including ``co_code_adaptive``) are mutable, but mutable fields are not included when code objects are hashed or compared. - -Instruction decoding -==================== - -The first task of the interpreter is to decode the bytecode instructions. -Bytecode is stored as an array of 16-bit code units (``_Py_CODEUNIT``). -Each code unit contains an 8-bit ``opcode`` and an 8-bit argument (``oparg``), both unsigned. -In order to make the bytecode format independent of the machine byte order when stored on disk, ``opcode`` is always the first byte and ``oparg`` is always the second byte. -Macros are used to extract the ``opcode`` and ``oparg`` from a code unit (``_Py_OPCODE(word)`` and ``_Py_OPARG(word)``). -Some instructions (for example, ``NOP`` or ``POP_TOP``) have no argument -- in this case we ignore ``oparg``. - -A simple instruction decoding loop would look like this: - -.. code-block:: c - - _Py_CODEUNIT *first_instr = code->co_code_adaptive; - _Py_CODEUNIT *next_instr = first_instr; - while (1) { - _Py_CODEUNIT word = *next_instr++; - unsigned char opcode = _Py_OPCODE(word); - unsigned int oparg = _Py_OPARG(word); - switch (opcode) { - // ... A case for each opcode ... - } - } - -This format supports 256 different opcodes, which is sufficient. -However, it also limits ``oparg`` to 8-bit values, which is not. -To overcome this, the ``EXTENDED_ARG`` opcode allows us to prefix any instruction with one or more additional data bytes. -For example, this sequence of code units:: - - EXTENDED_ARG 1 - EXTENDED_ARG 0 - LOAD_CONST 2 - -would set ``opcode`` to ``LOAD_CONST`` and ``oparg`` to ``65538`` (that is, ``0x1_00_02``). -The compiler should limit itself to at most three ``EXTENDED_ARG`` prefixes, to allow the resulting ``oparg`` to fit in 32 bits, but the interpreter does not check this. -A series of code units starting with zero to three ``EXTENDED_ARG`` opcodes followed by a primary opcode is called a complete instruction, to distinguish it from a single code unit, which is always two bytes. -The following loop, to be inserted just above the ``switch`` statement, will make the above snippet decode a complete instruction: - -.. code-block:: c - - while (opcode == EXTENDED_ARG) { - word = *next_instr++; - opcode = _Py_OPCODE(word); - oparg = (oparg << 8) | _Py_OPARG(word); - } - -For various reasons we'll get to later (mostly efficiency, given that ``EXTENDED_ARG`` is rare) the actual code is different. - -Jumps -===== - -Note that when the ``switch`` statement is reached, ``next_instr`` (the "instruction offset") already points to the next instruction. -Thus, jump instructions can be implemented by manipulating ``next_instr``: - -- An absolute jump (``JUMP_ABSOLUTE``) sets ``next_instr = first_instr + oparg``. -- A relative jump forward (``JUMP_FORWARD``) sets ``next_instr += oparg``. -- A relative jump backward sets ``next_instr -= oparg``. - -A relative jump whose ``oparg`` is zero is a no-op. - -Inline cache entries -==================== - -Some (specialized or specializable) instructions have an associated "inline cache". -The inline cache consists of one or more two-byte entries included in the bytecode array as additional words following the ``opcode`` /``oparg`` pair. -The size of the inline cache for a particular instruction is fixed by its ``opcode`` alone. -Moreover, the inline cache size for a family of specialized/specializable instructions (for example, ``LOAD_ATTR``, ``LOAD_ATTR_SLOT``, ``LOAD_ATTR_MODULE``) must all be the same. -Cache entries are reserved by the compiler and initialized with zeros. -If an instruction has an inline cache, the layout of its cache can be described by a ``struct`` definition and the address of the cache is given by casting ``next_instr`` to a pointer to the cache ``struct``. -The size of such a ``struct`` must be independent of the machine architecture, word size and alignment requirements. -For 32-bit fields, the ``struct`` should use ``_Py_CODEUNIT field[2]``. -Even though inline cache entries are represented by code units, they do not have to conform to the ``opcode`` / ``oparg`` format. - -The instruction implementation is responsible for advancing ``next_instr`` past the inline cache. -For example, if an instruction's inline cache is four bytes (that is, two code units) in size, the code for the instruction must contain ``next_instr += 2;``. -This is equivalent to a relative forward jump by that many code units. -(The proper way to code this is ``JUMPBY(n)``, where ``n`` is the number of code units to jump, typically given as a named constant.) - -Serializing non-zero cache entries would present a problem because the serialization (:mod:`marshal`) format must be independent of the machine byte order. - -More information about the use of inline caches :pep:`can be found in PEP 659 <659#ancillary-data>`. - -The evaluation stack -==================== - -Apart from unconditional jumps, almost all instructions read or write some data in the form of object references (``PyObject *``). -The CPython 3.11 bytecode interpreter is a stack machine, meaning that it operates by pushing data onto and popping it off the stack. -The stack is a pre-allocated array of object references. -For example, the "add" instruction (which used to be called ``BINARY_ADD`` in 3.10 but is now ``BINARY_OP 0``) pops two objects off the stack and pushes the result back onto the stack. -An interesting property of the CPython bytecode interpreter is that the stack size required to evaluate a given function is known in advance. -The stack size is computed by the bytecode compiler and is stored in ``code->co_stacksize``. -The interpreter uses this information to allocate stack. - -The stack grows up in memory; the operation ``PUSH(x)`` is equivalent to ``*stack_pointer++ = x``, whereas ``x = POP()`` means ``x = *--stack_pointer``. -There is no overflow or underflow check (except when compiled in debug mode) -- it would be too expensive, so we really trust the compiler. - -At any point during execution, the stack level is knowable based on the instruction pointer alone, and some properties of each item on the stack are also known. -In particular, only a few instructions may push a ``NULL`` onto the stack, and the positions that may be ``NULL`` are known. -A few other instructions (``GET_ITER``, ``FOR_ITER``) push or pop an object that is known to be an iterator. - -Instruction sequences that do not allow statically knowing the stack depth are deemed illegal. -The bytecode compiler never generates such sequences. -For example, the following sequence is illegal, because it keeps pushing items on the stack:: - - LOAD_FAST 0 - JUMP_BACKWARD 2 - -Do not confuse the evaluation stack with the call stack, which is used to implement calling and returning from functions. - -Error handling -============== - -See the `internals documentation -<https://github.com/python/cpython/blob/main/InternalDocs/exception_handling.md>`_. - -The locations table -------------------- - -Whenever an exception is raised, we add a traceback entry to the exception. -The ``tb_lineno`` field of a traceback entry is (lazily) set to the line number of the instruction that raised it. -This field is computed from the locations table, ``co_linetable`` (this name is an understatement), using :c:func:`PyCode_Addr2Line`. -This table has an entry for every instruction rather than for every ``try`` block, so a compact format is very important. - -The full design of the 3.11 locations table is written up in :cpy-file:`InternalDocs/locations.md`. -While there are rumors that this file is slightly out of date, it is still the best reference we have. -Don't be confused by :cpy-file:`Objects/lnotab_notes.txt`, which describes the 3.10 format. -For backwards compatibility this format is still supported by the ``co_lnotab`` property. - -The 3.11 location table format is different because it stores not just the starting line number for each instruction, but also the end line number, *and* the start and end column numbers. -Note that traceback objects don't store all this information -- they store the start line number, for backward compatibility, and the "last instruction" value. -The rest can be computed from the last instruction (``tb_lasti``) with the help of the locations table. -For Python code, a convenient method exists, :meth:`~codeobject.co_positions`, which returns an iterator of :samp:`({line}, {endline}, {column}, {endcolumn})` tuples, one per instruction. -There is also ``co_lines()`` which returns an iterator of :samp:`({start}, {end}, {line})` tuples, where :samp:`{start}` and :samp:`{end}` are bytecode offsets. -The latter is described by :pep:`626`; it is more compact, but doesn't return end line numbers or column offsets. -From C code, you have to call :c:func:`PyCode_Addr2Location`. - -Fortunately, the locations table is only consulted by exception handling (to set ``tb_lineno``) and by tracing (to pass the line number to the tracing function). -In order to reduce the overhead during tracing, the mapping from instruction offset to line number is cached in the ``_co_linearray`` field. - -Python-to-Python calls -====================== - -The ``_PyEval_EvalFrameDefault()`` function is recursive, because sometimes the interpreter calls some C function that calls back into the interpreter. -In 3.10 and before, this was the case even when a Python function called another Python function: -The ``CALL`` instruction would call the ``tp_call`` dispatch function of the callee, which would extract the code object, create a new frame for the call stack, and then call back into the interpreter. -This approach is very general but consumes several C stack frames for each nested Python call, thereby increasing the risk of an (unrecoverable) C stack overflow. - -In 3.11, the ``CALL`` instruction special-cases function objects to "inline" the call. -When a call gets inlined, a new frame gets pushed onto the call stack and the interpreter "jumps" to the start of the callee's bytecode. -When an inlined callee executes a ``RETURN_VALUE`` instruction, the frame is popped off the call stack and the interpreter returns to its caller, -by popping a frame off the call stack and "jumping" to the return address. -There is a flag in the frame (``frame->is_entry``) that indicates whether the frame was inlined (set if it wasn't). -If ``RETURN_VALUE`` finds this flag set, it performs the usual cleanup and returns from ``_PyEval_EvalFrameDefault()`` altogether, to a C caller. - -A similar check is performed when an unhandled exception occurs. - -The call stack -============== - -Up through 3.10, the call stack used to be implemented as a singly-linked list of :c:type:`PyFrameObject` objects. -This was expensive because each call would require a heap allocation for the stack frame. -(There was some optimization using a free list, but this was not always effective, because frames are variable length.) - -In 3.11, frames are no longer fully-fledged objects. -Instead, a leaner internal ``_PyInterpreterFrame`` structure is used, which is allocated using a custom allocator, ``_PyThreadState_BumpFramePointer()``. -Usually a frame allocation is just a pointer bump, which improves memory locality. -The function ``_PyEvalFramePushAndInit()`` allocates and initializes a frame structure. - -Sometimes an actual ``PyFrameObject`` is needed, usually because some Python code calls :func:`sys._getframe` or an extension module calls :c:func:`PyEval_GetFrame`. -In this case we allocate a proper ``PyFrameObject`` and initialize it from the ``_PyInterpreterFrame``. -This is a pessimization, but fortunately happens rarely (as introspecting frames is not a common operation). - -Things get more complicated when generators are involved, since those don't follow the push/pop model. -(The same applies to async functions, which are implemented using the same infrastructure.) -A generator object has space for a ``_PyInterpreterFrame`` structure, including the variable-size part (used for locals and eval stack). -When a generator (or async) function is first called, a special opcode ``RETURN_GENERATOR`` is executed, which is responsible for creating the generator object. -The generator object's ``_PyInterpreterFrame`` is initialized with a copy of the current stack frame. -The current stack frame is then popped off the stack and the generator object is returned. -(Details differ depending on the ``is_entry`` flag.) -When the generator is resumed, the interpreter pushes the ``_PyInterpreterFrame`` onto the stack and resumes execution. -(There is more hairiness for generators and their ilk; we'll discuss these in a later section in more detail.) - -(TODO: Also frame layout and use, and "locals plus".) - -All sorts of variables -====================== - -The bytecode compiler determines the scope in which each variable name is defined, and generates instructions accordingly. -For example, loading a local variable onto the stack is done using ``LOAD_FAST``, while loading a global is done using ``LOAD_GLOBAL``. -The key types of variables are: - -- fast locals: used in functions -- (slow or regular) locals: used in classes and at the top level -- globals and builtins: the compiler does not distinguish between globals and builtins (though the specializing interpreter does) -- cells: used for nonlocal references - -(TODO: Write the rest of this section. Alas, the author got distracted and won't have time to continue this for a while.) - -Other topics -============ - -(TODO: Each of the following probably deserves its own section.) - -- co_consts, co_names, co_varnames, and their ilk -- How calls work (how args are transferred, return, exceptions) -- Generators, async functions, async generators, and ``yield from`` (next, send, throw, close; and await; and how this code breaks the interpreter abstraction) -- Eval breaker (interrupts, GIL) -- Tracing -- Setting the current lineno (debugger-induced jumps) -- Specialization, inline caches etc. - - -Introducing new bytecode +======================== +The bytecode interpreter ======================== -.. note:: - - This section is relevant if you are adding a new bytecode to the interpreter. - - -Sometimes a new feature requires a new opcode. But adding new bytecode is -not as simple as just suddenly introducing new bytecode in the AST -> -bytecode step of the compiler. Several pieces of code throughout Python depend -on having correct information about what bytecode exists. - -First, you must choose a name, implement the bytecode in -:cpy-file:`Python/bytecodes.c`, and add a documentation entry in -:cpy-file:`Doc/library/dis.rst`. Then run ``make regen-cases`` to -assign a number for it (see :cpy-file:`Include/opcode_ids.h`) and -regenerate a number of files with the actual implementation of the -bytecodes (:cpy-file:`Python/generated_cases.c.h`) and additional -files with metadata about them. - -With a new bytecode you must also change what is called the magic number for -.pyc files. The variable ``MAGIC_NUMBER`` in -:cpy-file:`Lib/importlib/_bootstrap_external.py` contains the number. -Changing this number will lead to all .pyc files with the old ``MAGIC_NUMBER`` -to be recompiled by the interpreter on import. Whenever ``MAGIC_NUMBER`` is -changed, the ranges in the ``magic_values`` array in :cpy-file:`PC/launcher.c` -must also be updated. Changes to :cpy-file:`Lib/importlib/_bootstrap_external.py` -will take effect only after running ``make regen-importlib``. Running this -command before adding the new bytecode target to :cpy-file:`Python/bytecodes.c` -(followed by ``make regen-cases``) will result in an error. You should only run -``make regen-importlib`` after the new bytecode target has been added. - -.. note:: On Windows, running the ``./build.bat`` script will automatically - regenerate the required files without requiring additional arguments. - -Finally, you need to introduce the use of the new bytecode. Altering -:cpy-file:`Python/compile.c`, :cpy-file:`Python/bytecodes.c` will be the -primary places to change. Optimizations in :cpy-file:`Python/flowgraph.c` -may also need to be updated. -If the new opcode affects a control flow or the block stack, you may have -to update the ``frame_setlineno()`` function in :cpy-file:`Objects/frameobject.c`. -:cpy-file:`Lib/dis.py` may need an update if the new opcode interprets its -argument in a special way (like ``FORMAT_VALUE`` or ``MAKE_FUNCTION``). - -If you make a change here that can affect the output of bytecode that -is already in existence and you do not change the magic number constantly, make -sure to delete your old .py(c|o) files! Even though you will end up changing -the magic number if you change the bytecode, while you are debugging your work -you will be changing the bytecode output without constantly bumping up the -magic number. This means you end up with stale .pyc files that will not be -recreated. -Running ``find . -name '*.py[co]' -exec rm -f '{}' +`` should delete all .pyc -files you have, forcing new ones to be created and thus allow you test out your -new bytecode properly. Run ``make regen-importlib`` for updating the -bytecode of frozen importlib files. You have to run ``make`` again after this -for recompiling generated C files. +This document is now part of the +`CPython Internals Docs <https://github.com/python/cpython/blob/main/InternalDocs/compiler.md>`_. From d666cba85a750fa02e7a8d05b7e9c580aa4996ff Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:49:27 +0100 Subject: [PATCH 394/538] gh-119786: move 'changing grammar' checklist from devguide to InternalDocs (#1455) --- developer-workflow/grammar.rst | 70 +--------------------------------- 1 file changed, 2 insertions(+), 68 deletions(-) diff --git a/developer-workflow/grammar.rst b/developer-workflow/grammar.rst index ee6bdbaa4..7b510d25c 100644 --- a/developer-workflow/grammar.rst +++ b/developer-workflow/grammar.rst @@ -1,70 +1,4 @@ .. _grammar: -========================== -Changing CPython's grammar -========================== - -Abstract -======== - -There's more to changing Python's grammar than editing -:cpy-file:`Grammar/python.gram`. Here's a checklist. - -.. note:: - These instructions are for Python 3.9 and beyond. Earlier - versions use a different parser technology. You probably shouldn't - try to change the grammar of earlier Python versions, but if you - really want to, use GitHub to track down the earlier version of this - file in the devguide. - -For more information on how to use the new parser, check the -:ref:`section on how to use CPython's parser <parser>`. - -Checklist -========= - -Note: sometimes things mysteriously don't work. Before giving up, try ``make clean``. - -* :cpy-file:`Grammar/python.gram`: The grammar, with actions that build AST nodes. - After changing it, run ``make regen-pegen`` (or ``build.bat --regen`` on Windows), - to regenerate :cpy-file:`Parser/parser.c`. - (This runs Python's parser generator, :cpy-file:`Tools/peg_generator`). - -* :cpy-file:`Grammar/Tokens` is a place for adding new token types. After - changing it, run ``make regen-token`` to regenerate - :cpy-file:`Include/internal/pycore_token.h`, :cpy-file:`Parser/token.c`, - :cpy-file:`Lib/token.py` and :cpy-file:`Doc/library/token-list.inc`. - If you change both ``python.gram`` and ``Tokens``, - run ``make regen-token`` before ``make regen-pegen``. - On Windows, ``build.bat --regen`` will regenerate both at the same time. - -* :cpy-file:`Parser/Python.asdl` may need changes to match the grammar. - Then run ``make regen-ast`` to regenerate - :cpy-file:`Include/internal/pycore_ast.h` and :cpy-file:`Python/Python-ast.c`. - -* :cpy-file:`Parser/lexer/` contains the tokenization code. - This is where you would add a new type of comment or string literal, for example. - -* :cpy-file:`Python/ast.c` will need changes to validate AST objects - involved with the grammar change. - -* :cpy-file:`Python/ast_unparse.c` will need changes to unparse AST - involved with the grammar change ("unparsing" is used to turn annotations - into strings per :pep:`563`). - -* The :ref:`compiler` has its own page. - -* ``_Unparser`` in the :cpy-file:`Lib/ast.py` file may need changes - to accommodate any modifications in the AST nodes. - -* :cpy-file:`Doc/library/ast.rst` may need to be updated to reflect changes - to AST nodes. - -* Add some usage of your new syntax to ``test_grammar.py``. - -* Certain changes may require tweaks to the library module :mod:`pyclbr`. - -* :cpy-file:`Lib/tokenize.py` needs changes to match changes to the tokenizer. - -* Documentation must be written! Specifically, one or more of the pages in - :cpy-file:`Doc/reference/` will need to be updated. +This document is now part of the +`CPython Internals Docs <https://github.com/python/cpython/blob/main/InternalDocs/changing_grammar.md>`_. From facd6f83e63de3ad0e51e04219ed526ca79d5a25 Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Wed, 23 Oct 2024 15:32:23 -0400 Subject: [PATCH 395/538] Populate the docs section of the new contrib structure (#1454) * mark the plan page as an aside to the reviewer * link to the internals section from the contrib mention of it * contrib: populate the docs section Also added a pull-request-lifecycle page to the Code section. --- contrib/code/index.rst | 3 ++- contrib/code/pull-request-lifecycle.rst | 21 +++++++++++++++++++++ contrib/contrib-plan.rst | 6 +++--- contrib/doc/devguide.rst | 12 ++++++++++++ contrib/doc/help-documenting.rst | 12 ++++++++++++ contrib/doc/index.rst | 23 ++++++++++++++++------- contrib/doc/markup.rst | 12 ++++++++++++ contrib/doc/pull-request-lifecycle.rst | 21 +++++++++++++++++++++ contrib/doc/start-documenting.rst | 12 ++++++++++++ contrib/doc/style-guide.rst | 12 ++++++++++++ contrib/doc/translating.rst | 12 ++++++++++++ internals/index.rst | 2 ++ 12 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 contrib/code/pull-request-lifecycle.rst create mode 100644 contrib/doc/devguide.rst create mode 100644 contrib/doc/help-documenting.rst create mode 100644 contrib/doc/markup.rst create mode 100644 contrib/doc/pull-request-lifecycle.rst create mode 100644 contrib/doc/start-documenting.rst create mode 100644 contrib/doc/style-guide.rst create mode 100644 contrib/doc/translating.rst diff --git a/contrib/code/index.rst b/contrib/code/index.rst index 4839d1bf0..5f1e4c0f6 100644 --- a/contrib/code/index.rst +++ b/contrib/code/index.rst @@ -13,7 +13,7 @@ Code contributions [We'll include code-focused content from the :ref:`main devguide page <devguide-main>`: Quick reference, Quick links, Proposing changes, and so on.] -[The existing "CPython's internals" section of the devguide will be fully +[The existing :ref:`internals` section of the devguide will be fully migrated into the Python repo.] @@ -22,6 +22,7 @@ migrated into the Python repo.] setup git + pull-request-lifecycle developer-workflow testing development-tools diff --git a/contrib/code/pull-request-lifecycle.rst b/contrib/code/pull-request-lifecycle.rst new file mode 100644 index 000000000..30c0fd590 --- /dev/null +++ b/contrib/code/pull-request-lifecycle.rst @@ -0,0 +1,21 @@ +.. _code-pull-request-lifecycle: + +====================== +Pull request lifecycle +====================== + +.. important:: + + |draft| + + |purpose| + + +[Details of pull requests for code contributions. The existing +:ref:`pull-request-lifecycle` page is long and includes many details. +Some only apply to code contributions, but many are common to all +contributions. Should we keep a common page, with extra steps here, or +should this page have all of the details even if they are duplicated +elsewhere?] + +[See :ref:`docs-pull-request-lifecycle` for the documentation half of this conundrum.] diff --git a/contrib/contrib-plan.rst b/contrib/contrib-plan.rst index be35c1a8d..36a171bf1 100644 --- a/contrib/contrib-plan.rst +++ b/contrib/contrib-plan.rst @@ -1,8 +1,8 @@ .. _contrib-plan: -================================ -Plan for the Contributor's Guide -================================ +================================== +[Plan for the Contributor's Guide] +================================== .. important:: diff --git a/contrib/doc/devguide.rst b/contrib/doc/devguide.rst new file mode 100644 index 000000000..2c83e5200 --- /dev/null +++ b/contrib/doc/devguide.rst @@ -0,0 +1,12 @@ +================================== +Helping with the Developer's Guide +================================== + +.. important:: + + |draft| + + |purpose| + + +[This is the existing :ref:`devguide` page from the devguide.] diff --git a/contrib/doc/help-documenting.rst b/contrib/doc/help-documenting.rst new file mode 100644 index 000000000..befb4b246 --- /dev/null +++ b/contrib/doc/help-documenting.rst @@ -0,0 +1,12 @@ +========================== +Helping with documentation +========================== + +.. important:: + + |draft| + + |purpose| + + +[This is the existing :ref:`help-documenting` page from the devguide.] diff --git a/contrib/doc/index.rst b/contrib/doc/index.rst index e5d60e42f..224469d2c 100644 --- a/contrib/doc/index.rst +++ b/contrib/doc/index.rst @@ -9,10 +9,19 @@ Documentation contributions |purpose| -* Lifecycle of a docs pull request -* (pull in Documentation sections from devguide) -* Rst/Sphinx bootcamp -* Editorial Style Guide -* Translation - - How to add a new language - - Tools and workflow +[The main page for documentation contributors.] + +[We'll include docs-focused content from the :ref:`main devguide page <devguide-main>`: Quick +reference, Quick links, and so on.] + + +.. toctree:: + :maxdepth: 5 + + start-documenting + help-documenting + style-guide + markup + pull-request-lifecycle + translating + devguide diff --git a/contrib/doc/markup.rst b/contrib/doc/markup.rst new file mode 100644 index 000000000..96b9faad5 --- /dev/null +++ b/contrib/doc/markup.rst @@ -0,0 +1,12 @@ +======================= +reStructuredText markup +======================= + +.. important:: + + |draft| + + |purpose| + + +[This is the existing :ref:`markup` page from the devguide.] diff --git a/contrib/doc/pull-request-lifecycle.rst b/contrib/doc/pull-request-lifecycle.rst new file mode 100644 index 000000000..a62e63728 --- /dev/null +++ b/contrib/doc/pull-request-lifecycle.rst @@ -0,0 +1,21 @@ +.. _docs-pull-request-lifecycle: + +====================== +Pull request lifecycle +====================== + +.. important:: + + |draft| + + |purpose| + + +[Details of pull requests for documentation contributions. The existing +:ref:`pull-request-lifecycle` page is long and includes many details. +Some only apply to code contributions, but many are common to all +contributions. Should we keep a common page, with documentation tweaks here, or +should this page have only the documentation details even if they are duplicated +elsewhere?] + +[See :ref:`code-pull-request-lifecycle` for the code half of this conundrum.] diff --git a/contrib/doc/start-documenting.rst b/contrib/doc/start-documenting.rst new file mode 100644 index 000000000..c5cf96161 --- /dev/null +++ b/contrib/doc/start-documenting.rst @@ -0,0 +1,12 @@ +=============== +Getting started +=============== + +.. important:: + + |draft| + + |purpose| + + +[This is the existing documentation :ref:`start-documenting` page from the devguide.] diff --git a/contrib/doc/style-guide.rst b/contrib/doc/style-guide.rst new file mode 100644 index 000000000..87762f3e0 --- /dev/null +++ b/contrib/doc/style-guide.rst @@ -0,0 +1,12 @@ +=========== +Style guide +=========== + +.. important:: + + |draft| + + |purpose| + + +[This is the existing documentation :ref:`style-guide` page from the devguide.] diff --git a/contrib/doc/translating.rst b/contrib/doc/translating.rst new file mode 100644 index 000000000..baface2f0 --- /dev/null +++ b/contrib/doc/translating.rst @@ -0,0 +1,12 @@ +=========== +Translating +=========== + +.. important:: + + |draft| + + |purpose| + + +[This is the existing :ref:`translating` page from the devguide.] diff --git a/internals/index.rst b/internals/index.rst index 999e427b2..05723f482 100644 --- a/internals/index.rst +++ b/internals/index.rst @@ -1,3 +1,5 @@ +.. _internals: + =================== CPython's internals =================== From 1260d960af37b5f8b3dd00e4661af443c85b840e Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Sat, 26 Oct 2024 15:17:51 -0400 Subject: [PATCH 396/538] add a title to fix a warning (#1457) --- developer-workflow/grammar.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/developer-workflow/grammar.rst b/developer-workflow/grammar.rst index 7b510d25c..d574dfed7 100644 --- a/developer-workflow/grammar.rst +++ b/developer-workflow/grammar.rst @@ -1,4 +1,8 @@ .. _grammar: +========================== +Changing CPython's grammar +========================== + This document is now part of the `CPython Internals Docs <https://github.com/python/cpython/blob/main/InternalDocs/changing_grammar.md>`_. From 1ec58407217f57a01bb894ab92cb59a3d35ba864 Mon Sep 17 00:00:00 2001 From: ndunnett <46371520+ndunnett@users.noreply.github.com> Date: Mon, 28 Oct 2024 19:31:08 +1000 Subject: [PATCH 397/538] Fix link in interpreter.rst (#1458) Link to internal docs currently points to compiler.md, changed it to point to interpreter.md --- internals/interpreter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internals/interpreter.rst b/internals/interpreter.rst index 68273d8ec..a7ae39c12 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 <https://github.com/python/cpython/blob/main/InternalDocs/compiler.md>`_. +`CPython Internals Docs <https://github.com/python/cpython/blob/main/InternalDocs/interpreter.md>`_. From 900fb1b79c9dfc50ab320e85563f2a94d0639f85 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan <ncoghlan@gmail.com> Date: Thu, 31 Oct 2024 20:58:03 +1000 Subject: [PATCH 398/538] Affiliation update for Alyssa Coghlan (#1460) --- core-developers/motivations.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index 24f1ad2c8..7a9889f69 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -106,9 +106,11 @@ participating in the CPython core development process: * Personal site: `Curious Efficiency <https://www.curiousefficiency.org/>`_ * `Extended bio <https://www.curiousefficiency.org/pages/about>`__ * Python Software Foundation (Fellow, Packaging Working Group) + * Element Labs/LM Studio (Python deployment engineer) Alyssa began using Python as a testing and prototyping language while working - for Boeing Defence Australia, and continues to use it for that purpose today. + 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 continued suitability for educational, testing and data analysis use cases, From 1d6cc2f578b1c782a554cb5690ad519a99ce3437 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 01:58:54 +0000 Subject: [PATCH 399/538] Upgrade Sphinx to 8.1 (#1462) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ea5fdb74d..fe0a5348f 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.0.2 +Sphinx~=8.1.3 From e0bc90a595cac8dc7de762e1c2f3d4ab28eeaf48 Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Sun, 3 Nov 2024 08:18:30 -0500 Subject: [PATCH 400/538] Contrib guide: more restructuring (#1461) * contrib guide: more restructuring * review comment fixes * table tweaks --- _static/devguide_overrides.css | 6 ++ contrib/code/index.rst | 2 + .../{project => }/core-team/committing.rst | 2 +- .../{project => }/core-team/developer-log.rst | 2 +- contrib/{project => }/core-team/experts.rst | 2 +- contrib/{project => }/core-team/index.rst | 0 contrib/{project => }/core-team/join-team.rst | 2 +- .../{project => }/core-team/motivations.rst | 2 +- .../core-team/responsibilities.rst | 2 +- contrib/doc/index.rst | 2 + contrib/get-started/index.rst | 2 + contrib/index.rst | 100 ++++++++++++++++-- contrib/intro/index.rst | 27 ++++- contrib/project/generative-ai.rst | 10 ++ contrib/project/index.rst | 5 +- contrib/{ => project}/outreach.rst | 0 contrib/triage/index.rst | 2 + 17 files changed, 147 insertions(+), 21 deletions(-) rename contrib/{project => }/core-team/committing.rst (78%) rename contrib/{project => }/core-team/developer-log.rst (77%) rename contrib/{project => }/core-team/experts.rst (78%) rename contrib/{project => }/core-team/index.rst (100%) rename contrib/{project => }/core-team/join-team.rst (83%) rename contrib/{project => }/core-team/motivations.rst (77%) rename contrib/{project => }/core-team/responsibilities.rst (76%) create mode 100644 contrib/project/generative-ai.rst rename contrib/{ => project}/outreach.rst (100%) diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css index 9237445d2..8e2c7c6fc 100644 --- a/_static/devguide_overrides.css +++ b/_static/devguide_overrides.css @@ -94,3 +94,9 @@ font-size: var(--font-size--small--2); padding: .1em .2em; } + +/* Table cells should always top-align */ + +table.docutils td { + vertical-align: top; +} diff --git a/contrib/code/index.rst b/contrib/code/index.rst index 5f1e4c0f6..768095066 100644 --- a/contrib/code/index.rst +++ b/contrib/code/index.rst @@ -1,3 +1,5 @@ +.. _c_code: + ================== Code contributions ================== diff --git a/contrib/project/core-team/committing.rst b/contrib/core-team/committing.rst similarity index 78% rename from contrib/project/core-team/committing.rst rename to contrib/core-team/committing.rst index 569f6e27d..59cf7c1af 100644 --- a/contrib/project/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-developers/committing.rst diff --git a/contrib/project/core-team/developer-log.rst b/contrib/core-team/developer-log.rst similarity index 77% rename from contrib/project/core-team/developer-log.rst rename to contrib/core-team/developer-log.rst index 00d780303..473cd3c6c 100644 --- a/contrib/project/core-team/developer-log.rst +++ b/contrib/core-team/developer-log.rst @@ -8,4 +8,4 @@ [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 +.. include:: ../../core-developers/developer-log.rst diff --git a/contrib/project/core-team/experts.rst b/contrib/core-team/experts.rst similarity index 78% rename from contrib/project/core-team/experts.rst rename to contrib/core-team/experts.rst index 358fdd17f..7f2a103cd 100644 --- a/contrib/project/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-developers/experts.rst diff --git a/contrib/project/core-team/index.rst b/contrib/core-team/index.rst similarity index 100% rename from contrib/project/core-team/index.rst rename to contrib/core-team/index.rst diff --git a/contrib/project/core-team/join-team.rst b/contrib/core-team/join-team.rst similarity index 83% rename from contrib/project/core-team/join-team.rst rename to contrib/core-team/join-team.rst index 1905c92a9..0c893ae08 100644 --- a/contrib/project/core-team/join-team.rst +++ b/contrib/core-team/join-team.rst @@ -12,5 +12,5 @@ adjust "core developer" to "core team" where appropriate.] How to join the core team ========================= -.. include:: ../../../core-developers/become-core-developer.rst +.. include:: ../../core-developers/become-core-developer.rst :start-line: 7 diff --git a/contrib/project/core-team/motivations.rst b/contrib/core-team/motivations.rst similarity index 77% rename from contrib/project/core-team/motivations.rst rename to contrib/core-team/motivations.rst index 79af3ccfd..c9e0281b6 100644 --- a/contrib/project/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-developers/motivations.rst diff --git a/contrib/project/core-team/responsibilities.rst b/contrib/core-team/responsibilities.rst similarity index 76% rename from contrib/project/core-team/responsibilities.rst rename to contrib/core-team/responsibilities.rst index ca974b35c..a3de32956 100644 --- a/contrib/project/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-developers/responsibilities.rst diff --git a/contrib/doc/index.rst b/contrib/doc/index.rst index 224469d2c..dc8ec9307 100644 --- a/contrib/doc/index.rst +++ b/contrib/doc/index.rst @@ -1,3 +1,5 @@ +.. _c_docs: + =========================== Documentation contributions =========================== diff --git a/contrib/get-started/index.rst b/contrib/get-started/index.rst index 84c5afd70..70e61b1b1 100644 --- a/contrib/get-started/index.rst +++ b/contrib/get-started/index.rst @@ -1,3 +1,5 @@ +.. _c_gettingstarted: + =============== Getting started =============== diff --git a/contrib/index.rst b/contrib/index.rst index 1c169ffbe..b3ef0d992 100644 --- a/contrib/index.rst +++ b/contrib/index.rst @@ -1,7 +1,18 @@ +.. _c_root: + ================================== Python Contributor's Guide (draft) ================================== +.. raw:: html + + <script> + document.addEventListener('DOMContentLoaded', function() { + activateTab(getOS()); + }); + </script> + + .. important:: |draft| @@ -9,20 +20,85 @@ Python Contributor's Guide (draft) |purpose| -This guide is a comprehensive resource for contributing to Python. +[Open question: how to divide content between this Introduction and the +:ref:`introduction <c_intro>`?] + +This guide is a comprehensive resource for :ref:`contributing <contributing>` +to Python_ -- for both new and experienced contributors. It is :ref:`maintained +<devguide>` by the same community that maintains Python. We welcome your +contributions to Python! + +We encourage everyone to contribute to Python. This guide should have +everything you need to get started and be productive. If you still have +questions after reviewing the material in this guide, the `Core Python +Mentorship`_ group is available to help you through the process. + +There are a number of ways to contribute including code, documentation, and +triaging issues. We've organized this guide to provide specifics based on the +type of activity you'll be engaged in. + + +Using this guide +================ -.. note:: - This is a draft of a new organization for the devguide, turning it into a - Contributor's Guide. +We recommend reading this guide as needed. You can stop where you feel +comfortable and begin contributing immediately without reading and +understanding everything. If you do choose to skip around this guide, be aware +that it is written assuming preceding sections have been read so you may need +to backtrack to fill in missing concepts and terminology. -[Much of the devguide home page will be here. The Quick Start will be updated -to distinguish code vs documentation contributions, and moved to those -sections. Other changes will be made to explain the different types of -contribution and how to navigate the guide for your own type.] +No matter what kind of contribution you'll be making, you should start with +these common sections: + +* :ref:`c_intro` +* :ref:`c_project` +* :ref:`c_gettingstarted` + +Then choose a path based on your type of activity: + +*[The original table on the devguide home had a fourth column for Core +Developers. That made the table wider and more confusing. I don't think core +team members need a quick intro path since they will have been through the +devguide before.]* + +*[I haven't adjusted the links in the table yet other than to add a link to the +major section at the top of each column.]* + +.. list-table:: + :widths: 10 10 10 + :header-rows: 1 + + * - :ref:`Triaging <c_triage>` + - :ref:`Documentation <c_docs>` + - :ref:`Code <c_code>` + * - + * :ref:`tracker` + * :ref:`triaging` + * :ref:`helptriage` + * :ref:`experts` + * :ref:`labels` + * :ref:`gh-faq` + * :ref:`triage-team` + - + * :ref:`docquality` + * :ref:`documenting` + * :ref:`style-guide` + * :ref:`rst-primer` + * :ref:`translating` + * :ref:`devguide` + - + * :ref:`setup` + * :ref:`help` + * :ref:`pullrequest` + * :ref:`runtests` + * :ref:`fixingissues` + * :ref:`communication` + * :ref:`gitbootcamp` + * :ref:`devcycle` .. toctree:: - :maxdepth: 2 + :maxdepth: 3 contrib-plan intro/index @@ -31,6 +107,10 @@ contribution and how to navigate the guide for your own type.] triage/index code/index doc/index + core-team/index user-success security - outreach + + +.. _Python: https://www.python.org/ +.. _Core Python Mentorship: https://www.python.org/dev/core-mentorship/ diff --git a/contrib/intro/index.rst b/contrib/intro/index.rst index 0a733adaa..c5ba303df 100644 --- a/contrib/intro/index.rst +++ b/contrib/intro/index.rst @@ -1,3 +1,5 @@ +.. _c_intro: + ============ Introduction ============ @@ -10,10 +12,27 @@ Introduction +[Open question: how to divide content between this Introduction and the +:ref:`home page <c_root>`?] Welcome! -Healthy Collaboration +New to open source? +=================== + +Python is an open source project, with culture and techniques from the broader +open source world. You might find it helpful to read about open source in +general. A number of individuals from the Python community have contributed to +a series of excellent guides at `Open Source Guides +<https://opensource.guide/>`_. + +Anyone will find the following guides useful: + +* `How to Contribute to Open Source <https://opensource.guide/how-to-contribute/>`_ +* `Building Welcoming Communities <https://opensource.guide/building-community/>`_ + + +Healthy collaboration ===================== [Importance of healthy inclusive collaboration] @@ -22,13 +41,13 @@ Healthy Collaboration [We respect the individual skills people bring to the project and strive to create and maintain a culture of inclusion.] -About this Guide +About this guide ================ -Types of Contribution +Types of contribution ===================== [Pathways for contributors] -Helping with this Guide +Helping with this guide ======================= diff --git a/contrib/project/generative-ai.rst b/contrib/project/generative-ai.rst new file mode 100644 index 000000000..6cb5b62ff --- /dev/null +++ b/contrib/project/generative-ai.rst @@ -0,0 +1,10 @@ +.. important:: + + |draft| + + |purpose| + + +[This is the existing :ref:`generative-ai` page from the devguide.] + +.. include:: ../../getting-started/generative-ai.rst diff --git a/contrib/project/index.rst b/contrib/project/index.rst index 082be327e..5d26b15aa 100644 --- a/contrib/project/index.rst +++ b/contrib/project/index.rst @@ -1,3 +1,5 @@ +.. _c_project: + =================== The CPython project =================== @@ -19,7 +21,8 @@ moving parts, who is involved, how do they interact?] conduct roles - core-team/index governance + generative-ai.rst github channels + outreach diff --git a/contrib/outreach.rst b/contrib/project/outreach.rst similarity index 100% rename from contrib/outreach.rst rename to contrib/project/outreach.rst diff --git a/contrib/triage/index.rst b/contrib/triage/index.rst index 9257978a6..0a547d9d7 100644 --- a/contrib/triage/index.rst +++ b/contrib/triage/index.rst @@ -1,3 +1,5 @@ +.. _c_triage: + =================== Issues and triaging =================== From b37e0072d47772d0cd88ce12a1249873b83ff48f Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski <savannahostrowski@gmail.com> Date: Sun, 3 Nov 2024 14:26:35 -0800 Subject: [PATCH 401/538] Fix table (#1464) --- developer-workflow/development-cycle.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 6d5b04a2a..d7031597e 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -355,7 +355,7 @@ Current administrators | 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 f204a49dab5da7a352a39c2a32c9954ce5fdc918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Wed, 13 Nov 2024 22:40:17 +0100 Subject: [PATCH 402/538] Add Savannah Ostrowski (#1471) --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 52bbf00dd..bb235ee94 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +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 32c6b360ad70aef11da941ba9dca77297b62e46d Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski <savannahostrowski@gmail.com> Date: Wed, 13 Nov 2024 15:46:00 -0800 Subject: [PATCH 403/538] Add Savannah to Experts Index (#1472) --- 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 10f6b5727..8e5a0bf5a 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -56,7 +56,7 @@ __future__ __main__ gvanrossum, ncoghlan _thread abc -argparse +argparse savannahostrowski* array ast benjaminp, pablogsal, isidentical, JelleZijlstra, eclips4 asyncio 1st1, asvetlov, gvanrossum, graingert, kumaraditya303, willingc @@ -335,7 +335,7 @@ GUI i18n malemburg, merwok import machinery brettcannon, ncoghlan, ericsnowcurrently io benjaminp, stutzbach^, gpshead -JIT brandtbucher* +JIT brandtbucher*, savannahostrowski* locale malemburg mathematics malemburg, stutzbach^, rhettinger memory management tim-one, malemburg, Yhg1s From 6b8a1ea31da04b17091b46c183ce83eedcba59d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns=20=F0=9F=87=B5=F0=9F=87=B8?= <filipe.lains@gmail.com> Date: Tue, 19 Nov 2024 09:41:57 +0000 Subject: [PATCH 404/538] experts: add myself to initialization, venvs, and import machinery (#1473) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * experts: add myself to initialization, venvs, and import machinery Signed-off-by: Filipe Laíns <lains@riseup.net> * Update core-developers/experts.rst Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --------- Signed-off-by: Filipe Laíns <lains@riseup.net> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- core-developers/experts.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 8e5a0bf5a..415dd315d 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -109,6 +109,7 @@ ftplib giampaolo* functools rhettinger* gc pitrou, pablogsal getopt +getpath FFY00 getpass gettext glob @@ -234,7 +235,7 @@ unittest.mock voidspace* urllib orsenthil uu uuid -venv vsajip +venv vsajip, FFY00 warnings wave weakref freddrake @@ -333,7 +334,8 @@ frozen modules ericsnowcurrently, gvanrossum, kumaraditya303 f-strings ericvsmith* GUI i18n malemburg, merwok -import machinery brettcannon, ncoghlan, ericsnowcurrently +import machinery brettcannon, ncoghlan, ericsnowcurrently, FFY00 +initialization FFY00 io benjaminp, stutzbach^, gpshead JIT brandtbucher*, savannahostrowski* locale malemburg From a84443d7230e22d3e8b4e2f273da9244ef99c874 Mon Sep 17 00:00:00 2001 From: stratakis <cstratak@redhat.com> Date: Wed, 20 Nov 2024 23:22:29 +0100 Subject: [PATCH 405/538] Add bulidbot setup info for systemd based distros (#583) Provide examples for managing the buildbot-worker service through systemd unit files for systemd based distributions. --- testing/new-buildbot-worker.rst | 69 +++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/testing/new-buildbot-worker.rst b/testing/new-buildbot-worker.rst index 5da61b937..cac7bb63d 100644 --- a/testing/new-buildbot-worker.rst +++ b/testing/new-buildbot-worker.rst @@ -72,8 +72,8 @@ For Linux: * If your package manager provides the buildbot worker software, that is probably the best way to install it; it may create the buildbot user for - you, in which case you can skip that step. Otherwise, do ``pip install - buildbot-worker``. + you, in which case you can skip the next step. Otherwise, do ``pip install + buildbot-worker`` or ``pip3 install buildbot-worker``. * Create a ``buildbot`` user (using, eg: ``useradd``) if necessary. * Log in as the buildbot user. @@ -125,7 +125,70 @@ machine reboots: For Linux: -* Add the following line to ``/etc/crontab``:: +* For systemd based distributions, you can create a systemd unit file in order + to manage the service. Create the unit file named ``buildbot-worker.service`` + under ``/home/buildbot/.config/systemd/user/`` and change the paths according to where the + buildbot-worker binary resides. You can verify its location by running + ``which buildbot-worker``. + If you installed the buildbot-worker through + your package manager it would be:: + + [Unit] + Description=Buildbot Worker + Wants=network-online.target + After=network-online.target local-fs.target + + [Service] + Type=forking + PIDFile=/home/buildbot/buildarea/twistd.pid + WorkingDirectory=/home/buildbot/buildarea + ExecStart=/usr/bin/buildbot-worker start + ExecReload=/usr/bin/buildbot-worker restart + ExecStop=/usr/bin/buildbot-worker stop + Restart=always + User=buildbot + + [Install] + WantedBy=multi-user.target + + + If you installed the buildbot-worker through pip, the systemd unit + file should look like this:: + + [Unit] + Description=Buildbot Worker + Wants=network-online.target + After=network-online.target local-fs.target + + [Service] + Type=forking + PIDFile=/home/buildbot/buildarea/twistd.pid + WorkingDirectory=/home/buildbot/buildarea + ExecStart=/usr/local/bin/buildbot-worker start + ExecReload=/usr/local/bin/buildbot-worker restart + ExecStop=/usr/local/bin/buildbot-worker stop + Restart=always + User=buildbot + + [Install] + WantedBy=multi-user.target + + + Then enable lingering for the buildbot user via the + ``loginctl enable-linger buildbot`` command and you can start + the service through a login shell of the buildbot user + via the ``systemctl --user enable --now buildbot-worker.service`` + command. + + Note that using a systemd unit file, might produce some selinux warnings on systems + where the enforcing mode is enabled, usually related to the twistd.pid file. + If the service fails to start, you should check the output of + ``systemctl status buildbot-worker.service`` as well as the + ``/var/log/audit/audit.log`` file (e.g. through + ``sealert -a /var/log/audit/audit.log``) for potential issues and remedies. + + +* Alternatively you can create a cronjob. Add the following line to ``/etc/crontab``:: @reboot buildbot-worker restart /path/to/buildarea From 33ce74b387ae84b6f91efd9e0398334744062796 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 21 Nov 2024 22:41:34 +0200 Subject: [PATCH 406/538] Add advice on copyright notices and PRs (#1470) --- conf.py | 4 +--- getting-started/pull-request-lifecycle.rst | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/conf.py b/conf.py index 74137e8b5..f64e415d1 100644 --- a/conf.py +++ b/conf.py @@ -1,5 +1,3 @@ -import time - extensions = [ 'notfound.extension', 'sphinx.ext.extlinks', @@ -16,7 +14,7 @@ # General information about the project. project = "Python Developer's Guide" -copyright = f'2011-{time.strftime("%Y")}, Python Software Foundation' +copyright = '2011 Python Software Foundation' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 5728cb9da..59242f13f 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -238,6 +238,25 @@ should do to help ensure that your pull request is accepted. #. Proper :ref:`documentation <documenting>` additions/changes should be included. +Copyrights +========== + +Copyright notices are optional and informational, as international treaties +have abolished the requirement for them to protect copyrights. +However, they still serve an informative role. + +According to the US Copyright Office, valid copyright notices include the year +of first publication of the work. For example: + + Copyright (C) 2001 Python Software Foundation. + +Updating notices to add subsequent years is unnecessary and such PRs will be +closed. + +See also `python/cpython#126133 +<https://github.com/python/cpython/issues/126133#issuecomment-2460824052>`__. + + .. _patchcheck: ``patchcheck`` From d0661a5c777c309c3e454cde62e6b49e1d09f8be Mon Sep 17 00:00:00 2001 From: Barry Warsaw <barry@python.org> Date: Tue, 10 Dec 2024 15:27:19 -0800 Subject: [PATCH 407/538] Update Barry's affiliations (#1480) --- core-developers/motivations.rst | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index 7a9889f69..71e2cee3d 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -223,25 +223,23 @@ participating in the CPython core development process: .. topic:: Barry Warsaw (United States) - * `LinkedIn: <https://www.linkedin.com/in/barry-warsaw/>`_ (Senior Staff - Software Engineer - Python Foundation team) + * NVIDIA, Principal System Software Engineer, Open Source Python Ecosystem * Personal site: `barry.warsaw.us <https://barry.warsaw.us/>`_ * Blog: `We Fear Change <https://www.wefearchange.org/>`_ + * `LinkedIn <https://www.linkedin.com/in/barry-warsaw/>`_ + * `Bluesky <https://bsky.app/profile/pumpichank.bsky.social>`_ * Email address: barry@python.org * Python Software Foundation (Fellow) Barry has been working in, with, and on Python since 1994. He attended the - first Python workshop at NBS (now `NIST <https://www.nist.gov/>`_) 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 - <http://cnri.reston.va.us/>`_. From 2007 until 2017, Barry worked for - `Canonical <https://canonical.com/>`_, corporate sponsor of `Ubuntu - <https://ubuntu.com/>`_ Linux, primarily on the Python ecosystem, and - is both an Ubuntu and a `Debian <https://www.debian.org/>`_ uploading - developer. Barry has served as Python's postmaster, webmaster, release - manager, Language Summit co-chair, `Jython <https://www.jython.org/>`_ - project leader, `GNU Mailman <https://www.list.org/>`_ project leader, and - probably lots of other things he shouldn't admit to. + first Python workshop at `NIST <https://www.nist.gov/>`_ 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 + <http://cnri.reston.va.us/>`_. Barry has served as Python's postmaster, + webmaster, release manager, Language Summit co-chair, `Jython + <https://www.jython.org/>`_ project leader, `GNU Mailman + <https://www.list.org/>`_ project leader, and Python Steering Council + member in 2019, 2020, 2021, 2024, and 2025. .. topic:: Eric Snow (United States) From 0b9001fbcbc6e46a4520e978b7ec0c955c916981 Mon Sep 17 00:00:00 2001 From: Lincoln <71312724+Lincoln-developer@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:49:34 +0300 Subject: [PATCH 408/538] gh-1463: testing: Expand refleak checker section (GH-1468) --- testing/run-write-tests.rst | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/testing/run-write-tests.rst b/testing/run-write-tests.rst index 719591d79..83a4a2861 100644 --- a/testing/run-write-tests.rst +++ b/testing/run-write-tests.rst @@ -200,10 +200,21 @@ if the failures are transient or consistent. The ``-uall`` flag allows the use of all available resources so as to not skip tests requiring, for example, Internet access. -To check for reference leaks (only needed if you modified C code), use the -``-R`` flag. For example, ``-R 3:2`` will first run the test 3 times to settle -down the reference count, and then run it 2 more times to verify if there are -any leaks. +To check for reference leaks (only needed if you modified C code), +you can enable reference leak checking during testing using the ``-R`` flag. +For example, using the command:: + + python -m test <test_name> -R : + +This default setting performs a few initial warm-up runs to stabilize the reference count, +followed by additional runs to check for leaks. + +If you want more control over the number of runs, you can specify ``warmups`` and ``repeats`` explicitly:: + + python -m test <test_name> -R <warmups>:<repeats> + +For instance, ``-R 3:2`` will first run the test 3 times to settle down the +reference count, and then run it 2 more times to check for leaks. You can also execute the ``Tools/scripts/run_tests.py`` script as found in a CPython checkout. The script tries to balance speed with thoroughness. But if From 491dd992651645378fd19c1b57e2bfa277e5988d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 15 Dec 2024 18:28:55 +0200 Subject: [PATCH 409/538] Remove link to decommissioned Python Cookbook (#1481) --- developer-workflow/stdlib.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/developer-workflow/stdlib.rst b/developer-workflow/stdlib.rst index 1e841d8b2..60112d6d3 100644 --- a/developer-workflow/stdlib.rst +++ b/developer-workflow/stdlib.rst @@ -30,9 +30,6 @@ You have a several options for this: * Open a new thread in the `Ideas Discourse category`_ to gather feedback directly from the Python core developers and community. * Write a blog post about the code, which may also help gather useful feedback. -* Post it to the `Python Cookbook`_. - Based on feedback and reviews of the recipe, - you can see if others find the functionality as useful as you do. If you have found general acceptance and usefulness for your code from people, you can open an issue on the `issue tracker`_ with the code attached as a @@ -47,7 +44,6 @@ for it you at least can know that others will come across it who may find it useful. .. _Ideas Discourse category: https://discuss.python.org/c/ideas/6 -.. _Python Cookbook: https://code.activestate.com/recipes/langs/python/ Adding a new module From 5649d763a0a62b2ad8a4a2a0c5c1812b15db322b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 10 Jan 2025 19:53:29 +0200 Subject: [PATCH 410/538] Document the PyPI org policy (#1484) --- conf.py | 1 + developer-workflow/development-cycle.rst | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/conf.py b/conf.py index f64e415d1..0319de4dd 100644 --- a/conf.py +++ b/conf.py @@ -200,6 +200,7 @@ "github": ("https://github.com/%s", "%s"), "github-user": ("https://github.com/%s", "@%s"), "pypi": ("https://pypi.org/project/%s/", "%s"), + "pypi-org": ("https://pypi.org/org/%s/", "%s"), } # sphinxext-opengraph config diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index d7031597e..9beb8cb04 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -370,6 +370,30 @@ administrators) to merge changes to that branch. Multi-Factor Authentication must be enabled by the user in order to retain access as a Release Manager of the branch. +PyPI organization policy +^^^^^^^^^^^^^^^^^^^^^^^^ + +The Python core team owns the :pypi-org:`cpython` and :pypi-org:`python` +organizations on PyPI for publishing packages. +The main benefits of adding packages to these organizations: + +* Visibility: we can see our packages under a PyPI org page +* Maintainability: we can share granular PyPI access to improve the bus factor + +The general policy on which organization to use: + +* :pypi-org:`cpython`: + for development tools that are tied fairly closely to CPython development. + For example, :pypi:`blurb` and :pypi:`cherry-picker`. + Users generally shouldn’t have to care except for developing CPython itself + (although that doesn’t mean the tools necessarily have to be unusable for + anyone else). +* :pypi-org:`python`: + for general-audience projects that are maintained by the Python core team. + For example, :pypi:`pyperformance`, :pypi:`python-docs-theme` and + :pypi:`tzdata`. + + Governance ---------- From eb1fbc4ffb72b692b5b841cef904aebaa883c521 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 10 Jan 2025 19:53:48 +0200 Subject: [PATCH 411/538] Update repo RM role policy regarding EOL branches (#1483) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- developer-workflow/development-cycle.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 9beb8cb04..8a37692ad 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -363,9 +363,9 @@ Repository release manager role policy Release Managers for :ref:`in-development <indevbranch>`, :ref:`maintenance <maintbranch>`, and :ref:`security mode <secbranch>` Python releases are granted Administrator privileges on the repository. Once a release branch has -entered :ref:`end-of-life <eolbranch>`, the Release Manager for that branch is -removed as an Administrator and granted sole privileges (out side of repository -administrators) to merge changes to that branch. +entered :ref:`end-of-life <eolbranch>`, the Release Manager for that branch +creates a final tag and deletes the branch. After this, they are +removed as an Administrator. Multi-Factor Authentication must be enabled by the user in order to retain access as a Release Manager of the branch. From 5d0ab7a8db3f9c683b5181270adace844611e96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Sat, 11 Jan 2025 11:03:31 +0100 Subject: [PATCH 412/538] =?UTF-8?q?Add=20B=C3=A9n=C3=A9dikt=20Tran=20(#148?= =?UTF-8?q?5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index bb235ee94..a138f3739 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Bénédikt Tran,picnixz,2025-01-10,, Savannah Ostrowski,savannahostrowski,2024-11-13,, Matt Page,mpage,2024-10-10,, Kirill Podoprigora,Eclips4,2024-09-20,, From 6ccfb72c5e3b8511530e60f78cea636a897ac5b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:36:30 +0100 Subject: [PATCH 413/538] =?UTF-8?q?Add=20B=C3=A9n=C3=A9dikt=20Tran=20to=20?= =?UTF-8?q?`core-developers/experts.rst`=20(#1487)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 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 415dd315d..ec9fc2306 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -115,9 +115,9 @@ gettext glob grp gzip -hashlib tiran, gpshead* +hashlib tiran, gpshead*, picnixz heapq rhettinger*, stutzbach^ -hmac tiran, gpshead* +hmac tiran, gpshead*, picnixz html ezio-melotti* http idlelib kbkaiser (inactive), terryjreedy*, serwy (inactive), @@ -320,7 +320,7 @@ buildbots zware, pablogsal bytecode benjaminp, 1st1, markshannon, brandtbucher, carljm, iritkatriel context managers ncoghlan core workflow Mariatta, ezio-melotti, hugovk, AA-Turner -cryptography gpshead, dstufft +cryptography gpshead, dstufft, picnixz data formats database malemburg devguide merwok, ezio-melotti, willingc, Mariatta, hugovk, From cb898a1b8dbf40a9f21bc563d9952284aacf968f Mon Sep 17 00:00:00 2001 From: Maciej Olko <maciej.olko@gmail.com> Date: Wed, 15 Jan 2025 17:23:05 +0100 Subject: [PATCH 414/538] Link to the documentation translations dashboard (#1488) --- documentation/translating.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index bad1966ff..3c46e8bc1 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -10,7 +10,9 @@ Python documentation translations are governed by :PEP:`545`. They are built by `docsbuild-scripts <https://github.com/python/docsbuild-scripts/>`__ and hosted on docs.python.org. There are several documentation translations already -in production; others are works in progress. +in production; others are works in progress. See `the dashboard +<https://m-aciek.github.io/pydocs-translation-dashboard/>`__ for +details. .. list-table:: :header-rows: 1 From 7d020a3b1061fddd50aa3754ae04e46251746039 Mon Sep 17 00:00:00 2001 From: Maciej Olko <maciej.olko@gmail.com> Date: Wed, 15 Jan 2025 17:24:01 +0100 Subject: [PATCH 415/538] Translating: update how to get help (#1489) --- documentation/translating.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 3c46e8bc1..a2d1870a4 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -155,9 +155,10 @@ Here are the essential points of :PEP:`545`: How to get help =============== -Discussions about translations occur on the `translation mailing list <translation_ml_>`_, -and there's a `Libera.Chat IRC <https://libera.chat/>`_ channel, -``#python-doc``. +Discussions about translations occur on the Python Docs Discord +`#translations channel <https://discord.gg/h3qDwgyzga>`_, `translation +mailing list <translation_ml_>`_, and there's a `Libera.Chat IRC +<https://libera.chat/>`_ channel, ``#python-doc``. Translation FAQ From b59985c2df26a3baf81647aa66166aa9a9692d63 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:14:46 +0000 Subject: [PATCH 416/538] =?UTF-8?q?Emend=20=E2=80=98functions=E2=80=99=20t?= =?UTF-8?q?o=20=E2=80=98function=E2=80=99=20in=20the=20markup=20reference?= =?UTF-8?q?=20(#1491)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- documentation/markup.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index a7a9bcb76..65b8b8d03 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -22,8 +22,8 @@ Element Markup See also arguments/parameters ``*arg*`` :ref:`inline-markup` variables/literals/code ````foo````, ````42````, ````len(s) - 1```` :ref:`inline-markup` True/False/None ````True````, ````False````, ````None```` :ref:`inline-markup` -functions definitions ``.. function:: print(*args)`` :ref:`directives` -functions references ``:func:`print``` :ref:`roles` +function definitions ``.. function:: print(*args)`` :ref:`directives` +function references ``:func:`print``` :ref:`roles` attribute definitions ``.. attribute: `attr-name``` :ref:`information-units` attribute references ``:attr:`attr-name``` :ref:`roles` reference labels ``.. _label-name:`` :ref:`doc-ref-role` From d0ce5ccdb1b1b4f7cde75806d138ee5b6933a51e Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 17 Jan 2025 18:03:05 +0000 Subject: [PATCH 417/538] Document the OS-Linux label (#1493) --- triage/labels.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/triage/labels.rst b/triage/labels.rst index c2981f666..d78f6b472 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -62,7 +62,12 @@ OS labels These labels are used to specify which operating systems are affected. Since most issues either affect all systems or are specific to Unix, we don't have a dedicated Unix label. -Use :gh-label:`OS-windows`, :gh-label:`OS-mac`, and :gh-label:`OS-freebsd`. + +* :gh-label:`OS-android` +* :gh-label:`OS-freebsd` +* :gh-label:`OS-ios` +* :gh-label:`OS-linux` +* :gh-label:`OS-windows` 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 From ff5cf4aef64f4ecbba47ef9840298ac1a07715c6 Mon Sep 17 00:00:00 2001 From: Barry Warsaw <barry@python.org> Date: Fri, 17 Jan 2025 16:14:00 -0800 Subject: [PATCH 418/538] Link to `endoflife.date/python` in "Status of Python versions" (#1494) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- versions.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/versions.rst b/versions.rst index 2606999e5..db7f94682 100644 --- a/versions.rst +++ b/versions.rst @@ -16,6 +16,8 @@ Python release cycle .. raw:: html :file: include/release-cycle.svg +Another useful visualization is `endoflife.date/python <https://endoflife.date/python>`_. + Supported versions ================== From 4d0d0a41a576ed8408ccbd5a47bac2f31404c843 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 21 Jan 2025 01:37:07 +0200 Subject: [PATCH 419/538] Fix venv creation for the local Python using uv (#1498) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ab38ffc88..5a33d5089 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ ensure-venv: @if [ ! -d $(VENVDIR) ] ; then \ echo "Creating venv in $(VENVDIR)"; \ if $(UV) --version >/dev/null 2>&1; then \ - $(UV) venv $(VENVDIR); \ + $(UV) venv --python=$(PYTHON) $(VENVDIR); \ VIRTUAL_ENV=$(VENVDIR) $(UV) pip install -r $(REQUIREMENTS); \ else \ $(PYTHON) -m venv $(VENVDIR); \ From 78e7b2a439333771f82a3d9dba0b7b7cdb4c3242 Mon Sep 17 00:00:00 2001 From: Emir || 2099 <84385451+Emir2099@users.noreply.github.com> Date: Wed, 22 Jan 2025 16:31:53 +0530 Subject: [PATCH 420/538] Add section on obtaining a python.org email address for core team members (#1495) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- core-developers/become-core-developer.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index 40cedeb51..739792b48 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -60,6 +60,14 @@ are granted through these steps: were in the form of a separate post on the already open topic with the poll. +Getting a python.org email address +---------------------------------- + +Members of the core team can get an email address on the python.org domain. +For more details refer to the `python.org email policy +<https://www.python.org/psf/records/board/policies/email/>`_. + + Poll template ============= From bab2aa8e1866cf419af55a271b638a4d19f4cc45 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou <antoine@python.org> Date: Thu, 23 Jan 2025 12:45:45 +0100 Subject: [PATCH 421/538] Update Antoine's affiliation (#1501) --- core-developers/motivations.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core-developers/motivations.rst b/core-developers/motivations.rst index 71e2cee3d..b19c3062b 100644 --- a/core-developers/motivations.rst +++ b/core-developers/motivations.rst @@ -188,7 +188,7 @@ participating in the CPython core development process: .. topic:: Antoine Pitrou (France) * LinkedIn: `<https://www.linkedin.com/in/pitrou/>`_ (Senior Software Engineer) - * Voltron Data + * QuantStack * Python Software Foundation (Fellow) * Email address: antoine@python.org @@ -199,12 +199,12 @@ participating in the CPython core development process: world, and by the concrete roadblocks he was hitting in professional settings. Topics of choice have included interpreter optimizations, garbage collection, network programming, system programming and - concurrent programming (such as maintaining ``multiprocessing``). + concurrent programming. As a professional, Antoine has been first specializing in network programming, and more lately in open source data science infrastructure. - He is currently working full time on Apache Arrow as a technical leader - for Voltron Data. + He has made numerous contributions to Numba, Dask and is currently working + full time on Apache Arrow as a technical leader at QuantStack. .. topic:: Victor Stinner (France) From bb23f8967f42e1111d1c9ad6e2860e26282bb931 Mon Sep 17 00:00:00 2001 From: Petr Viktorin <encukou@gmail.com> Date: Tue, 28 Jan 2025 15:10:48 +0100 Subject: [PATCH 422/538] Remove note about backporting `versionchanged:: next` (#1503) The feature is now available in all active branches. --- documentation/markup.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index 65b8b8d03..9528075d9 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -1112,10 +1112,6 @@ units as well as normal text: .. _update_version_next.py: https://github.com/python/release-tools/blob/master/update_version_next.py - When backporting to versions before 3.14, check if ``Doc/tools/extensions/pyspecific.py`` - contains the function ``expand_version_arg``. If it's not there, - use a specific version instead of ``next``. - When adding documentation for a function that existed in a past version, but wasn't documented yet, use the version number where the function was added instead of ``next``. From b8b92a593bb4b155c0286f38d75cb5241af9cf34 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 3 Feb 2025 13:53:34 +0000 Subject: [PATCH 423/538] Wording tweaks in translating.rst (#1490) * Changed "picker" to "switcher" which is more commonly used and the term in the PEP * Added "The" before "consensus" for grammatical correctness, "version" to align with the question/title * Removed unnecessary "some" from section title --- documentation/translating.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index a2d1870a4..9e90a01d5 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -127,7 +127,7 @@ The important steps look like this: PR or by asking on the `translation mailing list <translation_ml_>`_. - When ``bugs.html``, ``tutorial``, and ``library/functions`` are 100% completed, ask on the `translation mailing list <translation_ml_>`_ for - your language to be added in the language picker on docs.python.org. + your language to be added in the language switcher on docs.python.org. PEP 545 summary @@ -167,12 +167,12 @@ Translation FAQ Which version of the Python documentation should be translated? --------------------------------------------------------------- -Consensus is to work on current stable. You can then propagate your +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 some tools to help in managing the repo? --------------------------------------------------- +Are there tools to help in managing the repo? +--------------------------------------------- Here's what we're using: From d0899f7a4166b6f0b62feed85a1ed44b350af990 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar <76171953+octonawish-akcodes@users.noreply.github.com> Date: Mon, 3 Feb 2025 23:53:16 +0530 Subject: [PATCH 424/538] Update mailing list information following retirement of `python-dev` (#1249) Signed-off-by: Abhishek Kumar <abhishek22512@gmail.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- .github/CONTRIBUTING.md | 4 +- developer-workflow/communication-channels.rst | 38 +++++++++---------- getting-started/getting-help.rst | 19 ---------- 3 files changed, 19 insertions(+), 42 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 218b07b63..028715319 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -33,8 +33,8 @@ Due to the fact that this project is entirely volunteer-run (that is, no one is to work on Python full-time), we unfortunately can make no guarantees as to if or when a core developer will get around to reviewing your pull request. If no core developer has done a review or responded to changes made because of a -"changes requested" review, please feel free to email [python-dev](https://mail.python.org/mailman3/lists/python-dev.python.org/) to ask if -someone could take a look at your pull request. +"changes requested" review, please consider seeking assistance through the +[Core Development Discourse category](https://discuss.python.org/c/core-dev/23). ## Code of Conduct diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 499ca9b96..00c569178 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -27,12 +27,13 @@ in return. Mailing lists ============= -.. note:: Some mailing lists have been supplanted by categories in the - Python `Discourse`_. Specifically, +.. note:: + + Mailing lists have generally been replaced by the `Discourse`_ forum. + Specifically, * The python-dev list is superseded by the `Core Development`_ and `PEPs`_ categories on Discourse. - * The python-ideas list is superseded by posts in the `Ideas`_ category on Discourse. @@ -42,17 +43,21 @@ Mailing lists - Ideas about new functionality should **not** start here, and instead should be discussed in `Ideas`_. - Technical support questions should also not be asked here, and instead - should go to the python-list_ or python-help_ mailing lists, or the - `Python Help`_ category on Discourse. + should go to the `Python Help`_ category on Discourse or the python-list_. -Existing threads on the python-dev_, python-committers_, and python-ideas_ mailing lists -can be accessed through the `online archive <web gateway_>`__. + Previous threads on the python-dev_, python-committers_, and python-ideas_ + mailing lists can be accessed through the `online archive + <https://mail.python.org/archives/>`__. + + .. _python-committers: https://mail.python.org/mailman3/lists/python-committers.python.org/ + .. _python-dev: https://mail.python.org/mailman3/lists/python-dev.python.org/ + .. _python-ideas: https://mail.python.org/mailman3/lists/python-ideas.python.org General Python questions should go to `python-list`_ or `tutor`_ -or similar resources, such as StackOverflow_ or the ``#python`` IRC channel +or similar resources, such as `Stack Overflow`_ or the ``#python`` IRC channel on Libera.Chat_. -`The core-workflow <https://github.com/python/core-workflow/issues>`_ +The `core-workflow <https://github.com/python/core-workflow/issues>`__ issue tracker is the place to discuss and work on improvements to the CPython core development workflow. @@ -62,16 +67,10 @@ https://mail.python.org/mailman3/ (newer lists, using Mailman3). Some lists may be mirrored at `GMANE <https://gmane.io/>`_ and can be read and posted to in various ways, including via web browsers, NNTP newsreaders, and RSS feed readers. -.. _issue tracker: https://github.com/python/cpython/issues -.. _python-committers: https://mail.python.org/mailman3/lists/python-committers.python.org/ -.. _python-dev: https://mail.python.org/mailman3/lists/python-dev.python.org/ -.. _python-help: https://mail.python.org/mailman/listinfo/python-help -.. _python-ideas: https://mail.python.org/mailman3/lists/python-ideas.python.org .. _python-list: https://mail.python.org/mailman/listinfo/python-list .. _tutor: https://mail.python.org/mailman/listinfo/tutor -.. _StackOverflow: https://stackoverflow.com/ +.. _Stack Overflow: https://stackoverflow.com/ .. _Libera.Chat: https://libera.chat/ -.. _web gateway: https://mail.python.org/archives/ .. _communication-discourse: @@ -79,11 +78,8 @@ ways, including via web browsers, NNTP newsreaders, and RSS feed readers. Discourse (discuss.python.org web forum) ======================================== -We have our own `Discourse`_ forum for both developers and users. This forum -complements the `python-dev`_, `python-ideas`_, `python-help`_, and -`python-list`_ mailing lists. - -This forum has different categories and most core development discussions +We have our own `Discourse`_ forum for both developers and users. +It has different categories and most core development discussions take place in the open forum categories for `PEPs`_ and `Core Development`_ (these are the Discourse equivalents to the python-dev mailing list). All categories are open for users to read and post with the exception of diff --git a/getting-started/getting-help.rst b/getting-started/getting-help.rst index 4e993a1e9..50b7583e7 100644 --- a/getting-started/getting-help.rst +++ b/getting-started/getting-help.rst @@ -37,25 +37,6 @@ Those particularly relevant for help contributing to Python itself include: .. _Ideas: https://discuss.python.org/c/ideas/6 -.. _help-mailing-lists: - -Mailing lists -------------- - -Further options for seeking assistance include the -`python-ideas`_ and `python-dev`_ mailing lists, -which correspond to the `Ideas`_ and `Core Development`_ -:ref:`help-discourse` categories, respectively. -The Discourse categories are generally more active -and are the preferred venue for new discussions, -but the mailing lists are still monitored and responded to. -These mailing lists are for questions involving the -development *of* Python, **not** for development *with* Python. - -.. _python-ideas: https://mail.python.org/mailman3/lists/python-ideas.python.org -.. _python-dev: https://mail.python.org/mailman3/lists/python-dev.python.org/ - - Ask #python-dev --------------- From 5a3c60a89b9283d6c7976c2d3545f31ae3c69266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kul=C3=ADk?= <Kulikjak@gmail.com> Date: Thu, 6 Feb 2025 16:15:38 +0100 Subject: [PATCH 425/538] Add kulikjak to Solaris Maintainers list (#1508) --- 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 ec9fc2306..990c692bb 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -298,7 +298,7 @@ Linux macOS ronaldoussoren, ned-deily, freakboy3742 NetBSD1 OS2/EMX aimacintyre^ -Solaris/OpenIndiana jcea +Solaris/OpenIndiana jcea, kulikjak Windows tjguk, zware, zooba, pfmoore JVM/Java frank.wierzbicki^ =================== =========== From 436f07c2b6b48d08727be461c771a86e8f90da31 Mon Sep 17 00:00:00 2001 From: Trent Nelson <trent@trent.me> Date: Fri, 7 Feb 2025 14:53:58 -0800 Subject: [PATCH 426/538] Reactivate my (Trent Nelson) status. (#1509) --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index a138f3739..cf50c739d 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -114,7 +114,7 @@ Guilherme Polo,,2008-04-24,2017-02-10,Did not make GitHub transition Jeroen Ruigrok van der Werven,,2008-04-12,2017-02-10,For documentation; did not make GitHub transition Benjamin Peterson,benjaminp,2008-03-25,,For bug triage David Wolever,wolever,2008-03-17,2020-11-21,For 2to3 module -Trent Nelson,tpn,2008-03-17,2020-11-26, +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, Christian Heimes,tiran,2007-10-31,, From b28d4de4d7bc79c199acdf3dfc19bd0dd0ff22fe Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 10 Feb 2025 15:44:00 +0200 Subject: [PATCH 427/538] Fix table markup to show markup table (#1511) Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- documentation/markup.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/markup.rst b/documentation/markup.rst index 9528075d9..fc8deb4bb 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -22,8 +22,8 @@ Element Markup See also arguments/parameters ``*arg*`` :ref:`inline-markup` variables/literals/code ````foo````, ````42````, ````len(s) - 1```` :ref:`inline-markup` True/False/None ````True````, ````False````, ````None```` :ref:`inline-markup` -function definitions ``.. function:: print(*args)`` :ref:`directives` -function references ``:func:`print``` :ref:`roles` +function definitions ``.. function:: print(*args)`` :ref:`directives` +function references ``:func:`print``` :ref:`roles` attribute definitions ``.. attribute: `attr-name``` :ref:`information-units` attribute references ``:attr:`attr-name``` :ref:`roles` reference labels ``.. _label-name:`` :ref:`doc-ref-role` From 0dba72aea8943712c408e206687bd6360fb4d69e Mon Sep 17 00:00:00 2001 From: Revisto <theRevisto@gmail.com> Date: Mon, 10 Feb 2025 03:53:28 +0330 Subject: [PATCH 428/538] docs: update Persian (fa) translation contact to Revisto --- documentation/translating.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 9e90a01d5..b9e751197 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -62,8 +62,8 @@ details. - Albertas Gimbutas (:github-user:`albertas`, `email <mailto:albertasgim@gmail.com>`__) - `Original mail <https://mail.python.org/pipermail/doc-sig/2019-July/004138.html>`__ * - Persian (fa) - - Komeil Parseh (:github-user:`mmdbalkhi`) - - :github:`GitHub <mmdbalkhi/python-docs-fa>` + - Revisto (:github-user:`revisto`) + - :github:`GitHub <revisto/python-docs-fa>` * - `Polish (pl) <https://docs.python.org/pl/>`__ - Maciej Olko (:github-user:`m-aciek`) - :github:`GitHub <python/python-docs-pl>`, From b3bb594a84a1dfca9aaac824774b708a1d86ccd2 Mon Sep 17 00:00:00 2001 From: Revisto <theRevisto@gmail.com> Date: Mon, 10 Feb 2025 04:10:06 +0330 Subject: [PATCH 429/538] docs: update Persian (fa) translation contact to Alireza Shabani --- documentation/translating.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index b9e751197..6737678dc 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -62,7 +62,7 @@ details. - Albertas Gimbutas (:github-user:`albertas`, `email <mailto:albertasgim@gmail.com>`__) - `Original mail <https://mail.python.org/pipermail/doc-sig/2019-July/004138.html>`__ * - Persian (fa) - - Revisto (:github-user:`revisto`) + - Alireza Shabani (:github-user:`revisto`) - :github:`GitHub <revisto/python-docs-fa>` * - `Polish (pl) <https://docs.python.org/pl/>`__ - Maciej Olko (:github-user:`m-aciek`) From 753d33b94858cfd2d28b063352896693c0c34004 Mon Sep 17 00:00:00 2001 From: Marco Rougeth <rougeth@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:28:08 +0000 Subject: [PATCH 430/538] Add Rafael Fontenelle as a contact for pt_BR translations (#1514) --- documentation/translating.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 6737678dc..85ce63f73 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -73,7 +73,8 @@ details. - Gustavo Toffo - * - `Portuguese as spoken in Brasil (pt-br) <https://docs.python.org/pt-br/>`__ - - Marco Rougeth + - Rafael Fontenelle (:github-user:`rffontenelle`), + Marco Rougeth (:github-user:`rougeth`) - :github:`GitHub <python/python-docs-pt-br>`, `wiki <https://python.org.br/traducao/>`__, `Telegram <https://t.me/pybr_i18n>`__, From fcbc46875893b882fcf8e76cf56b305fce61a128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Tue, 18 Feb 2025 13:47:40 +0100 Subject: [PATCH 431/538] Memorialize Michael Foord (#1515) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- core-developers/developers.csv | 2 +- core-developers/experts.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index cf50c739d..398b7f226 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -100,7 +100,7 @@ Doug Hellmann,dhellmann,2009-09-20,2020-11-11,For documentation; relinquished pr Frank Wierzbicki,,2009-08-02,2017-02-10,For Jython compatibility; did not make GitHub transition Ezio Melotti,ezio-melotti,2009-06-07,,For documentation Philip Jenvey,pjenvey,2009-05-07,2020-11-26,For Jython compatibility -Michael Foord,voidspace,2009-04-01,,For IronPython compatibility +Michael Foord,voidspace,2009-04-01,2025-01-24,For IronPython compatibility; deceased R\. David Murray,bitdancer,2009-03-30,, Chris Withers,cjw296,2009-03-08,, Tarek Ziadé,tarekziade,2008-12-21,2017-02-10,For distutils module diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 990c692bb..683f35462 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -230,8 +230,8 @@ turtledemo terryjreedy* types 1st1 typing gvanrossum, JelleZijlstra*, AlexWaygood*, carljm, sobolevn* unicodedata malemburg, ezio-melotti -unittest voidspace*, ezio-melotti, rbtcollins, gpshead -unittest.mock voidspace* +unittest ezio-melotti, rbtcollins, gpshead +unittest.mock urllib orsenthil uu uuid @@ -358,7 +358,7 @@ runtime lifecycle ericsnowcurrently, kumaraditya303, zooba str.format ericvsmith* subinterpreters ericsnowcurrently, kumaraditya303 symbol table JelleZijlstra, carljm -testing voidspace, ezio-melotti +testing ezio-melotti test coverage threads gpshead time and dates malemburg, abalkin, pganssle From 903b45da6498200980deaf3b34126c66d3317300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Wed, 19 Feb 2025 15:15:48 +0100 Subject: [PATCH 432/538] Describe the memorialization procedure (#1516) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Seth Michael Larson <seth@python.org> --- core-developers/index.rst | 1 + core-developers/memorialization.rst | 146 ++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 core-developers/memorialization.rst diff --git a/core-developers/index.rst b/core-developers/index.rst index 8555943a0..2e6db104f 100644 --- a/core-developers/index.rst +++ b/core-developers/index.rst @@ -13,3 +13,4 @@ Core developers developer-log motivations become-core-developer + memorialization diff --git a/core-developers/memorialization.rst b/core-developers/memorialization.rst new file mode 100644 index 000000000..3167beca5 --- /dev/null +++ b/core-developers/memorialization.rst @@ -0,0 +1,146 @@ +.. _memorialize-core-developer: + +=============== +Memorialization +=============== + +Rationale +========= + +When a core developer passes away, memorializing accounts helps create +a space for remembering the contributor and protects against attempted +logins and fraudulent activity. + +The process +=========== + +The memorialization process is performed by a member of the PSF staff +with administrative access to current and historical systems where +core developers have access. + +After the status of the core developer in question is confirmed, +access to the systems listed below is revoked and some changes are +made to how the user displays to others. + +To respect the choices that someone made while alive, we aim to preserve +content of their accounts without changes after they've passed away. +To support the bereaved, in some instances, we may remove or change +certain content when the legacy contact or family members request it. + +GitHub +------ + +* The user is removed from the `python/ <https://github.com/orgs/python/>`_ + organization on GitHub; +* The user is removed from the `psf/ <https://github.com/orgs/psf/>`_ + organization on GitHub; +* The user is removed from the `pypa/ <https://github.com/orgs/pypa/>`_ + organization on GitHub. + +The PSF staff does not follow up with GitHub with regards to GitHub account +cancellation as this action is reserved for next-of-kin or designated by +the deceased GitHub user to act as an account successor. + +The general policy regarding deceased users on GitHub is described +`here <https://docs.github.com/en/site-policy/other-site-policies/github-deceased-user-policy>`_. + +Repositories in the organization +-------------------------------- + +* The user's GitHub handle is removed from ``/.github/CODEOWNERS``. + To see all that need action, perform + `this query <https://github.com/search?q=org%3Apython+path%3A**%2F.github%2FCODEOWNERS+USERNAME&type=code>`_. +* The user is marked as deceased in the private + `voters/python-core.toml <https://github.com/python/voters/blob/main/python-core.toml>`_ + file with the ``left=`` field set to the day of passing, if known. + +discuss.python.org +------------------ + +* The user's "custom status" is set to 🕊 ``in memoriam``; +* The user's "about me" is amended with ``$firstname passed away on $date. [In memoriam.]($in_memoriam_post_url)``; +* In the user's security "recently used devices" the staff member chooses "Log out all"; +* In the user's permissions the staff member chooses "Deactivate account"; +* The user's trust level is reset to ``1: basic user`` (trust level 0 doesn't allow links in "About Me"); +* The user's "associated accounts" (like GitHub) that provide an alternative + login method, are all disconnected; +* The user's API keys are revoked; +* The user's admin or moderator right is revoked; +* The user's primary email address is reset to ``USERNAME@in-memoriam.invalid`` and + secondary email addresses are removed (this step requires the administrator + to contact Discourse.org staff via ``team@discourse.org``) + +The "in memoriam" Discourse topic mentioned above is best created by +a community member close to the deceased. + +The general best practice for deceased community members on +Discourse-powered forums is described `here <https://meta.discourse.org/t/best-practices-for-deceased-community-members/146210>`_. + +python.org email account +------------------------ + +The PSF staff member emails ``postmaster@python.org`` to ask the email +administrator to: + +* remove SMTP access from ``USERNAME@python.org``; +* reset the password to POP3/IMAP for ``USERNAME@python.org``; +* disable email forwarding, if set up, for ``USERNAME@python.org``; +* remove this email from all mailing lists under ``@python.org``; +* remove any known alternate emails for the same user from all mailing lists + under ``@python.org``. + +python.org admin +---------------- + +* The user's account (``/admin/users/user``) is deactivated (NOT deleted) + and their staff and superuser status is unchecked; +* The user's password is reset to a long random string; +* The user's primary email address is set to ``USERNAME@in-memoriam.invalid`` + and set as unverified; +* The user's secondary email addresses are deleted; +* The user's API keys (both on the account and ``tastypie``) are deleted; +* The user's "I would like to be a PSF Voting Member" field is cleared. + +devguide.python.org +------------------- + +* The user is marked as deceased in `developers.csv <https://github.com/python/devguide/blob/main/core-developers/developers.csv>`_; +* The user is removed from the `Experts Index <https://github.com/python/devguide/blob/main/core-developers/experts.rst>`_. + +bugs.python.org +--------------- + +While the issue tracker was migrated to GitHub, the Roundup instance +is still up for historical purposes. + +* the PSF staff member logs into ``bugs.nyc1.psf.io``; +* the PSF staff member runs ``roundup-admin`` to set the user's email + address to ``USERNAME@in-memoriam.invalid``; +* the user's alternate emails are removed; +* the user's password is reset to a long random string; +* the PSF staff member removes any active login sessions from Postgres. + +Other PSF-related infrastructure +-------------------------------- + +* The PSF staff member notifies administrators of the Python Core Devs + Discord server to remove the user from the server. The PSF staff + does not follow up with Discord with regards to Discord account + cancellation. The general policy regarding deceased users on Discord + is available `here <https://support.discord.com/hc/en-us/articles/19872987802263--Deceased-or-Incapacitated-Users>`_. + +* The user is removed from Salt configuration for the PSF infrastructure + in `/pillar/base/users <https://github.com/python/psf-salt/tree/main/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 <https://github.com/search?q=repo%3Apython%2Fbuildmaster-config%20USERNAME&type=code>`_ + repository. + +PyPI +---- + +* The PSF staff member notifies PyPI admins by emailing them at + ``admin@pypi.org`` to mark the user as inactive, remove their email + addresses, prohibit their password resets, and revoke all API keys. From 78e6918b3e366feb2b946a720aa99b237a306805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Wed, 19 Feb 2025 16:18:56 +0100 Subject: [PATCH 433/538] Re-activate Armin Ronacher per committer's request --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 398b7f226..e419259b6 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -105,7 +105,7 @@ R\. David Murray,bitdancer,2009-03-30,, Chris Withers,cjw296,2009-03-08,, Tarek Ziadé,tarekziade,2008-12-21,2017-02-10,For distutils module Hirokazu Yamamoto,,2008-08-12,2017-02-10,For Windows build; did not make GitHub transition -Armin Ronacher,mitsuhiko,2008-07-23,2020-11-26,For documentation toolset and ast module +Armin Ronacher,mitsuhiko,2008-07-23,,For documentation toolset and ast module Antoine Pitrou,pitrou,2008-07-16,, Senthil Kumaran,orsenthil,2008-06-16,, Jesse Noller,,2008-06-16,2017-02-10,For multiprocessing module; did not make GitHub transition From f4a54669bc109a1443a1fbd975b5b653201ffe57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Wed, 19 Feb 2025 19:13:18 +0100 Subject: [PATCH 434/538] Update inactive core developers after confirmation --- core-developers/developers.csv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index e419259b6..9a89c9207 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -116,7 +116,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, +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 @@ -142,7 +142,7 @@ Facundo Batista,facundobatista,2004-10-16,, Sean Reifschneider,,2004-09-17,2017-02-10,Did not make GitHub transition Johannes Gijsbers,,2004-08-14,2005-07-27,Privileges relinquished on 2005-07-27 Matthias Klose,doko42,2004-08-04,, -PJ Eby,pjeby,2004-03-24,2020-11-26, +PJ Eby,pjeby,2004-03-24,2020-11-26,"Relinquished privileges on 2020-11-26" Vinay Sajip,vsajip,2004-02-20,, Hye-Shik Chang,hyeshik,2003-12-10,, Armin Rigo,,2003-10-24,2012-06-01,Privileges relinquished in 2012 @@ -157,7 +157,7 @@ Steve Holden,holdenweb,2002-06-14,2017-02-10,"Relinquished privileges on 2005-04 but granted again for Need for Speed sprint; did not make GitHub transition" Christian Tismer,ctismer,2002-05-17,,For Need for Speed sprint Jason Tishler,,2002-05-15,2017-02-10,Did not make GitHub transition -Walter Dörwald,doerwalter,2002-03-21,, +Walter Dörwald,doerwalter,2002-03-21,2021-11-16,"Relinquished privileges on 2021-11-16" Andrew MacIntyre,,2002-02-17,2016-01-02,Privileges relinquished 2016-01-02 Gregory P. Smith,gpshead,2002-01-08,, Anthony Baxter,,2001-12-21,2017-02-10,Did not make GitHub transition From f7c5e60a4bedeac3f1fc3947afd61ade2b9c42fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Wed, 19 Feb 2025 19:17:21 +0100 Subject: [PATCH 435/538] Mark Abhilash Raj as inactive per committer's request --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 9a89c9207..3f54b783b 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -31,7 +31,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,, +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,, From dbe885cad1ba48c0b987b364374882271ddc6311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Thu, 20 Feb 2025 10:39:08 +0100 Subject: [PATCH 436/538] Mark Andrew Kuchling as inactive per committer's request --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 3f54b783b..bde61fe46 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -190,7 +190,7 @@ Eric S. Raymond,,2000-06-02,2017-02-10,Did not make GitHub transition Greg Stein,,1999-11-07,2017-02-10,Did not make GitHub transition Just van Rossum,,1999-01-22,2017-02-10,Did not make GitHub transition Greg Ward,,1998-12-18,2017-02-10,Did not make GitHub transition -Andrew Kuchling,akuchling,1998-04-09,, +Andrew Kuchling,akuchling,1998-04-09,2022-11-09,Privileges relinquished 2022-11-09 Ken Manheimer,,1998-03-03,2005-04-08,Privileges relinquished on 2005-04-08 Jeremy Hylton,jeremyhylton,1997-08-13,, Roger E. Masse,,1996-12-09,2017-02-10,Did not make GitHub transition From 670038307811acbc2ca468935807e9a91744f17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Thu, 20 Feb 2025 15:49:56 +0100 Subject: [PATCH 437/538] Make it explicit the privileges for Eli Bendersky were relinquished per committer's request --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index bde61fe46..1de0d63ca 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -78,7 +78,7 @@ 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 Jason R. Coombs,jaraco,2011-03-14,,For sprinting on distutils2 Ross Lagerwall,,2011-03-13,2017-02-10,Did not make GitHub transition -Eli Bendersky,eliben,2011-01-11,2020-11-26, +Eli Bendersky,eliben,2011-01-11,2020-11-26,Relinquished privileges on 2020-11-26 Ned Deily,ned-deily,2011-01-09,, David Malcolm,davidmalcolm,2010-10-27,2020-11-12,relinquished privileges on 2020-11-12 Tal Einat,taleinat,2010-10-04,,Initially for IDLE From 75c827ab47b43c95533b549bcd3a65fe43d7db67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Thu, 20 Feb 2025 16:52:08 +0100 Subject: [PATCH 438/538] Clarify that @python.org email addresses don't get reused; reflow text to fit (#1517) --- core-developers/memorialization.rst | 32 ++++++++++++++++++----------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/core-developers/memorialization.rst b/core-developers/memorialization.rst index 3167beca5..61ec0560c 100644 --- a/core-developers/memorialization.rst +++ b/core-developers/memorialization.rst @@ -59,16 +59,19 @@ discuss.python.org * The user's "custom status" is set to 🕊 ``in memoriam``; * The user's "about me" is amended with ``$firstname passed away on $date. [In memoriam.]($in_memoriam_post_url)``; -* In the user's security "recently used devices" the staff member chooses "Log out all"; +* In the user's security "recently used devices" the staff member + chooses "Log out all"; * In the user's permissions the staff member chooses "Deactivate account"; -* The user's trust level is reset to ``1: basic user`` (trust level 0 doesn't allow links in "About Me"); -* The user's "associated accounts" (like GitHub) that provide an alternative - login method, are all disconnected; +* The user's trust level is reset to ``1: basic user`` (trust level 0 + doesn't allow links in "About Me"); +* The user's "associated accounts" (like GitHub) that provide an + alternative login method, are all disconnected; * The user's API keys are revoked; * The user's admin or moderator right is revoked; -* The user's primary email address is reset to ``USERNAME@in-memoriam.invalid`` and - secondary email addresses are removed (this step requires the administrator - to contact Discourse.org staff via ``team@discourse.org``) +* The user's primary email address is reset to + ``USERNAME@in-memoriam.invalid`` and secondary email addresses are + removed (this step requires the administrator to contact Discourse.org + staff via ``team@discourse.org``). The "in memoriam" Discourse topic mentioned above is best created by a community member close to the deceased. @@ -84,10 +87,15 @@ administrator to: * remove SMTP access from ``USERNAME@python.org``; * reset the password to POP3/IMAP for ``USERNAME@python.org``; -* disable email forwarding, if set up, for ``USERNAME@python.org``; +* disable email forwarding, if set up, for ``USERNAME@python.org`` and + leave a record permanently as "in memoriam" to avoid future account + name reuse; * remove this email from all mailing lists under ``@python.org``; -* remove any known alternate emails for the same user from all mailing lists - under ``@python.org``. +* remove any known alternate emails for the same user from all mailing + lists under ``@python.org``. + +In case the email shutdown causes issues for the estate executors, the +PSF will reasonably try to help if contacted directly. python.org admin ---------------- @@ -95,8 +103,8 @@ python.org admin * The user's account (``/admin/users/user``) is deactivated (NOT deleted) and their staff and superuser status is unchecked; * The user's password is reset to a long random string; -* The user's primary email address is set to ``USERNAME@in-memoriam.invalid`` - and set as unverified; +* The user's primary email address is set to + ``USERNAME@in-memoriam.invalid`` and set as unverified; * The user's secondary email addresses are deleted; * The user's API keys (both on the account and ``tastypie``) are deleted; * The user's "I would like to be a PSF Voting Member" field is cleared. From 2f2d66ceb6fe3f5471de820dedb3575d043c811c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Sat, 22 Feb 2025 12:39:50 +0100 Subject: [PATCH 439/538] Mark Meador Inge as active per committer's request --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 1de0d63ca..6ef1eff55 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -69,7 +69,7 @@ Hynek Schlawack,hynek,2012-05-14,, Richard Oudkerk,,2012-04-29,2017-02-10,For multiprocessing module; did not make GitHub transition Andrew Svetlov,asvetlov,2012-03-13,,At PyCon sprint Petri Lehtinen,akheron,2011-10-22,2020-11-12, -Meador Inge,meadori,2011-09-19,2020-11-26, +Meador Inge,meadori,2011-09-19,, Jeremy Kloth,jkloth,2011-09-12,, Sandro Tosi,sandrotosi,2011-08-01,, Alex Gaynor,alex,2011-07-18,,For PyPy compatibility (since expanded scope) From d8ae9f8e23c75aada8347b5664966a1f01a530f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Sun, 23 Feb 2025 19:51:17 +0100 Subject: [PATCH 440/538] Mark Robert Collins as inactive per committer's request --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 6ef1eff55..d89fc2abe 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -52,7 +52,7 @@ Xavier de Gaye,xdegaye,2016-06-03,2018-01-25,Privileges relinquished on 2018-01- Davin Potts,applio,2016-03-06,, Martin Panter,vadmium,2015-08-10,2020-11-26, Paul Moore,pfmoore,2015-03-15,, -Robert Collins,rbtcollins,2014-10-16,,To work on unittest +Robert Collins,rbtcollins,2014-10-16,2021-11-30,To work on unittest; privileges relinquished on 2021-11-30 Berker Peksağ,berkerpeksag,2014-06-26,, Steve Dower,zooba,2014-05-10,, Kushal Das,kushaldas,2014-04-14,, From f489bdd2bc964cab65bcc0d0e624c2899dba9e63 Mon Sep 17 00:00:00 2001 From: Yuki Kobayashi <drsuaimqjgar@gmail.com> Date: Mon, 24 Feb 2025 17:45:41 +0900 Subject: [PATCH 441/538] Remove extra indentations in `triage/issue-tracker.rst` (#1520) --- triage/issue-tracker.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/triage/issue-tracker.rst b/triage/issue-tracker.rst index b311a51a7..4dd0815e4 100644 --- a/triage/issue-tracker.rst +++ b/triage/issue-tracker.rst @@ -57,10 +57,10 @@ will ask you to do so now. First you need to select what kind of problem you want to report. The available choices include, for example: - * **Bug report**: an existing feature isn't working as expected. - * **Documentation**: there is missing, invalid, or misleading documentation. - * **Feature or enhancement**: suggest a new feature for Python. - * **Report a security vulnerability**: privately report a security vulnerability. +* **Bug report**: an existing feature isn't working as expected. +* **Documentation**: there is missing, invalid, or misleading documentation. +* **Feature or enhancement**: suggest a new feature for Python. +* **Report a security vulnerability**: privately report a security vulnerability. Depending on your choice, a dedicated form template will appear. In particular, you'll notice that the last button actually takes you to From 98671205e660606869f8c312a2eb536383e6a4e1 Mon Sep 17 00:00:00 2001 From: Maciej Olko <maciej.olko@gmail.com> Date: Thu, 27 Feb 2025 15:17:00 +0100 Subject: [PATCH 442/538] Note the ``python-docs-translations`` GitHub organisation (#1507) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- documentation/translating.rst | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 85ce63f73..3e9d08d89 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -11,7 +11,7 @@ They are built by `docsbuild-scripts <https://github.com/python/docsbuild-scripts/>`__ and hosted on docs.python.org. There are several documentation translations already in production; others are works in progress. See `the dashboard -<https://m-aciek.github.io/pydocs-translation-dashboard/>`__ for +<https://python-docs-translations.github.io/dashboard/>`__ for details. .. list-table:: @@ -113,20 +113,21 @@ First subscribe to the `translation mailing list <translation_ml_>`_, and introduce yourself and the translation you're starting. Translations fall under the aegis of the `PSF Translation Workgroup <translation_wg_>`_ -Then you can bootstrap your new translation by using our `cookiecutter -<https://github.com/JulienPalard/python-docs-cookiecutter>`__. +Then you can bootstrap your new translation by using `cookiecutter +<https://github.com/JulienPalard/python-docs-cookiecutter>`__ or +`bootstrapper <https://github.com/python-docs-translations/python-docs-bootstrapper>`__. The important steps look like this: -- Create the GitHub repo (anywhere) with the right hierarchy (using the - cookiecutter). +- 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 <translation_ml_>`_. -- When ``bugs.html``, ``tutorial``, and ``library/functions`` are 100% +- When ``bugs``, ``tutorial``, and ``library/functions`` are 100% completed, ask on the `translation mailing list <translation_ml_>`_ for your language to be added in the language switcher on docs.python.org. @@ -184,6 +185,10 @@ Here's what we're using: - :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? ----------------------------- From 2b6056ce5bd8a89fe806b84570ad18d502ffa00f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Mar 2025 01:39:42 +0000 Subject: [PATCH 443/538] Update Sphinx to 8.2 (#1525) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fe0a5348f..bad565b8c 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.1.3 +Sphinx~=8.2.1 From c1c1f82d5fb3d580f11572aebbb01dc56f7d8e0e Mon Sep 17 00:00:00 2001 From: Zachary Ware <zach@python.org> Date: Sun, 2 Mar 2025 19:37:52 -0600 Subject: [PATCH 444/538] Fix bn_IN coordinator username (#1526) When user links were originally translated from BPO to GH in #836, the wrong Kushal Das was chosen for some reason. Kushal's BPO profile clearly shows `kushaldas` rather than `Kushal997-das` as the correct GH username. --- documentation/translating.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 3e9d08d89..ea3cbaf2d 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -24,7 +24,7 @@ details. - Abdur-Rahmaan Janhangeer (:github-user:`Abdur-rahmaanJ`) - :github:`GitHub <Abdur-rahmaanJ/python-docs-ar>` * - Bengali as spoken in India (bn_IN) - - Kushal Das (:github-user:`Kushal997-das`) + - Kushal Das (:github-user:`kushaldas`) - :github:`GitHub <python/python-docs-bn-in>` * - `French (fr) <https://docs.python.org/fr/>`__ - Julien Palard (:github-user:`JulienPalard`) From ace43390bfc715e17c10f213f35b19473b4444e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Mon, 3 Mar 2025 16:21:23 +0100 Subject: [PATCH 445/538] Marked Hye-Shik Chang as inactive per core developer's request --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index d89fc2abe..c8afa93c6 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -144,7 +144,7 @@ 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" Vinay Sajip,vsajip,2004-02-20,, -Hye-Shik Chang,hyeshik,2003-12-10,, +Hye-Shik Chang,hyeshik,2003-12-10,2025-02-28,"Relinquished privileges 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 From 9f7395e3923d06a870d7aa5b8e0c9e5a5576ecb4 Mon Sep 17 00:00:00 2001 From: Petr Viktorin <encukou@gmail.com> Date: Mon, 10 Mar 2025 15:08:02 +0100 Subject: [PATCH 446/538] C API: mention the workgroup, and the need to be stricter than our public promises (GH-1524) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * C API: mention the workgroup, and the need to be stricter than our public promises * Apply suggestions from code review Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> * Clarify: Internally→as core devs --------- Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- developer-workflow/c-api.rst | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/developer-workflow/c-api.rst b/developer-workflow/c-api.rst index 3f8c03e92..90c1d12e4 100644 --- a/developer-workflow/c-api.rst +++ b/developer-workflow/c-api.rst @@ -19,8 +19,13 @@ The C API is divided into these tiers: Each tier has different stability and maintenance requirements to consider when you add or change definitions in it. -The compatibility guarantees for public C API are explained in the -user documentation, ``Doc/c-api/stable.rst`` (:ref:`python:stable`). +The public backwards compatibility guarantees for public C API are explained +in the user documentation, ``Doc/c-api/stable.rst`` (:ref:`python:stable`). +C language compatibility guarantees are in ``Doc/c-api/intro.rst`` +(:ref:`python:api-intro`). + +As core developers, we need to be more careful about compatibility than what +we promise publicly. See :ref:`public-capi` for details. The internal API @@ -93,6 +98,17 @@ CPython's public C API is available when ``Python.h`` is included normally It should be defined in ``Include/cpython/`` (unless part of the Limited API, see below). +Before adding new public API, please ask in the `decisions repo`_ of +the :pep:`C API workgroup <731>`. +This helps us ensure *newly added* API is consistent and maintainable. + +Also check with the C API WG before requiring a C feature not present in C99. +While the *public* docs only promise compatibility with C11, in practice +we only intruduce C11 features individually as needed. + +.. _decisions repo: https://github.com/capi-workgroup/decisions/issues + + .. _public-api-guidelines: Guidelines for expanding/changing the public API From 02f5b33dbfbed025b78cd69787eb4db778935642 Mon Sep 17 00:00:00 2001 From: Octavian Mustafa <octaG-M@users.noreply.github.com> Date: Wed, 12 Mar 2025 04:01:15 +0200 Subject: [PATCH 447/538] Link to a Romanian translation (#1528) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Maciej Olko <maciej.olko@affirm.com> --- documentation/translating.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/documentation/translating.rst b/documentation/translating.rst index ea3cbaf2d..ee3bfcce2 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -79,6 +79,9 @@ details. `wiki <https://python.org.br/traducao/>`__, `Telegram <https://t.me/pybr_i18n>`__, `article <https://rgth.co/blog/python-ptbr-cenario-atual/>`__ + * - Romanian (ro) + - Octavian Mustafa (:github-user:`octaG-M`, `email <mailto:octawian@yahoo.com>`__) + - :github:`GitHub <octaG-M/python-docs-ro>` * - Russian (ru) - Daniil Kolesnikov (:github-user:`MLGRussianXP`, `email <mailto:mlgrussianxp@gmail.com>`__) - :github:`GitHub <MLGRussianXP/python-docs-ru>`, From 85eda4a6daed3c1cf4c601ef98da46b7ba1b8ac8 Mon Sep 17 00:00:00 2001 From: Maciej Olko <maciej.olko@gmail.com> Date: Wed, 12 Mar 2025 08:48:58 +0100 Subject: [PATCH 448/538] Shorten names of country-specific languages (#1492) --- documentation/translating.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index ee3bfcce2..04e8a0a6b 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -23,7 +23,7 @@ details. * - Arabic (ar) - Abdur-Rahmaan Janhangeer (:github-user:`Abdur-rahmaanJ`) - :github:`GitHub <Abdur-rahmaanJ/python-docs-ar>` - * - Bengali as spoken in India (bn_IN) + * - Bengali (bn_IN) - Kushal Das (:github-user:`kushaldas`) - :github:`GitHub <python/python-docs-bn-in>` * - `French (fr) <https://docs.python.org/fr/>`__ @@ -34,7 +34,7 @@ details. Fanis Petkos (:github-user:`thepetk`), Panagiotis Skias (:github-user:`skpanagiotis`) - :github:`GitHub <pygreece/python-docs-gr>` - * - Hindi as spoken in India (hi_IN) + * - Hindi (hi_IN) - Sanyam Khurana (:github-user:`CuriousLearner`) - :github:`GitHub <CuriousLearner/python-docs-hi-in>` * - Hungarian (hu) @@ -72,7 +72,7 @@ details. * - Portuguese (pt) - Gustavo Toffo - - * - `Portuguese as spoken in Brasil (pt-br) <https://docs.python.org/pt-br/>`__ + * - `Brazilian Portuguese (pt-br) <https://docs.python.org/pt-br/>`__ - Rafael Fontenelle (:github-user:`rffontenelle`), Marco Rougeth (:github-user:`rougeth`) - :github:`GitHub <python/python-docs-pt-br>`, From 07454edf3fc569bc27d38e7018ec3ba708fdf9e3 Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Wed, 19 Mar 2025 06:32:38 -0600 Subject: [PATCH 449/538] "Status of Python versions" page: more details in charts, more descriptive text (#1531) * Python version status: show when bugfix releases become security releases * Make them look all the same * Show EOL ones as red * Two graphs * Remove unacceptable newline * Join an unacceptably split line * Hide the starts of EOL versions * Special-case 2.7 * Remove 3.5 * Format * Put labels on top, if the mask doesn't work * simplify the svg paths * Add more explanation to the Python versions Status key * clarify what a feature fix is. * Update _tools/generate_release_cycle.py Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> * Update _tools/generate_release_cycle.py Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> * Update _tools/generate_release_cycle.py Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> * Update _tools/generate_release_cycle.py Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> * Update _tools/generate_release_cycle.py Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> * 3.13 gets two years of bug fixes, earlier gets 1.5 years * last changes from the review * use a consistent anchor for the full chart * more tweaking of the phase descriptions * Use `height` consistently * Clean up the path code * Remove the "shade" rectangle, keep left+right+border or a single rect * Use the same radius everywhere * Rearrange comments/assignments * No mask for active branches * Restore bold red color * Update _tools/release_cycle_template.svg.jinja --------- Co-authored-by: Petr Viktorin <encukou@gmail.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .gitignore | 1 + Makefile | 1 + _static/devguide_overrides.css | 56 +++++--- _tools/generate_release_cycle.py | 73 ++++++++-- _tools/release_cycle_template.svg.jinja | 184 +++++++++++++++++++----- make.ps1 | 3 +- versions.rst | 48 ++++--- 7 files changed, 280 insertions(+), 86 deletions(-) diff --git a/.gitignore b/.gitignore index df4dc9415..b71249201 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,4 @@ celerybeat-schedule include/branches.csv include/end-of-life.csv include/release-cycle.svg +include/release-cycle-all.svg diff --git a/Makefile b/Makefile index 5a33d5089..6baf33b32 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ 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 .PHONY: help diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css index 8e2c7c6fc..d47a1e602 100644 --- a/_static/devguide_overrides.css +++ b/_static/devguide_overrides.css @@ -48,35 +48,57 @@ fill: white; } -.release-cycle-chart .release-cycle-blob-label.release-cycle-blob-security, -.release-cycle-chart .release-cycle-blob-label.release-cycle-blob-bugfix { +.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.release-cycle-blob-end-of-life { - fill: #DD2200; - stroke: #FF8888; +.release-cycle-chart .release-cycle-blob-label.release-cycle-status-end-of-life, +.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-blob.release-cycle-blob-security { - fill: #FFDD44; - stroke: #FF8800; +.release-cycle-chart .release-cycle-status-security { + --status-bg-color: #FFDD44; + --status-border-color: #FF8800; } -.release-cycle-chart .release-cycle-blob.release-cycle-blob-bugfix { - fill: #00DD22; - stroke: #008844; +.release-cycle-chart .release-cycle-status-bugfix { + --status-bg-color: #00DD22; + --status-border-color: #008844; } -.release-cycle-chart .release-cycle-blob.release-cycle-blob-prerelease { - fill: teal; - stroke: darkgreen; +.release-cycle-chart .release-cycle-status-prerelease { + --status-bg-color: teal; + --status-border-color: darkgreen; } -.release-cycle-chart .release-cycle-blob.release-cycle-blob-feature { - fill: #2222EE; - stroke: #008888; +.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 { diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index 3a8fefec0..63d98cfce 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -25,24 +25,64 @@ def parse_date(date_str: str) -> dt.date: return dt.date.fromisoformat(date_str) +def parse_version(ver: str) -> list[int]: + return [int(i) for i in ver["key"].split(".")] + + class Versions: """For converting JSON to CSV and SVG.""" - def __init__(self) -> None: + def __init__(self, *, limit_to_active=False, special_py27=False) -> None: with open("include/release-cycle.json", encoding="UTF-8") as in_file: self.versions = json.load(in_file) # Generate a few additional fields for key, version in self.versions.items(): version["key"] = key - version["first_release_date"] = parse_date(version["first_release"]) + ver_info = parse_version(version) + if ver_info >= [3, 13]: + full_years = 2 + else: + full_years = 1.5 + version["first_release_date"] = r1 = parse_date(version["first_release"]) + version["start_security_date"] = r1 + dt.timedelta(days=full_years * 365) version["end_of_life_date"] = parse_date(version["end_of_life"]) + + self.cutoff = min(ver["first_release_date"] for ver in self.versions.values()) + + if limit_to_active: + self.cutoff = min( + version["first_release_date"] + for version in self.versions.values() + if version["status"] != "end-of-life" + ) + self.versions = { + key: version + for key, version in self.versions.items() + if version["end_of_life_date"] >= self.cutoff + or (special_py27 and key == "2.7") + } + if special_py27: + self.cutoff = min(self.cutoff, dt.date(2019, 8, 1)) + self.id_key = "active" + else: + self.id_key = "all" + self.sorted_versions = sorted( self.versions.values(), - key=lambda v: [int(i) for i in v["key"].split(".")], + key=parse_version, reverse=True, ) + # Set the row (Y coordinate) for the chart, to allow a gap between 2.7 + # and the rest + y = len(self.sorted_versions) + (1 if special_py27 else 0) + for version in self.sorted_versions: + if special_py27 and version["key"] == "2.7": + y -= 1 + version["y"] = y + y -= 1 + def write_csv(self) -> None: """Output CSV files.""" now_str = str(dt.datetime.now(dt.timezone.utc)) @@ -68,7 +108,7 @@ def write_csv(self) -> None: csv_file.writeheader() csv_file.writerows(versions.values()) - def write_svg(self, today: str) -> None: + def write_svg(self, today: str, out_path: str) -> None: """Output SVG file.""" env = jinja2.Environment( loader=jinja2.FileSystemLoader("_tools/"), @@ -85,6 +125,8 @@ def write_svg(self, today: str) -> None: # CSS. # (Ideally we'd actually use `em` units, but SVG viewBox doesn't take # those.) + + # Uppercase sizes are un-scaled SCALE = 18 # Width of the drawing and main parts @@ -96,7 +138,7 @@ def write_svg(self, today: str) -> None: # some positioning numbers in the template as well. LINE_HEIGHT = 1.5 - first_date = min(ver["first_release_date"] for ver in self.sorted_versions) + first_date = self.cutoff last_date = max(ver["end_of_life_date"] for ver in self.sorted_versions) def date_to_x(date: dt.date) -> float: @@ -105,7 +147,7 @@ def date_to_x(date: dt.date) -> float: total_days = (last_date - first_date).days ratio = num_days / total_days x = ratio * (DIAGRAM_WIDTH - LEGEND_WIDTH - RIGHT_MARGIN) - return x + LEGEND_WIDTH + return (x + LEGEND_WIDTH) * SCALE def year_to_x(year: int) -> float: """Convert year number to an SVG X coordinate of 1st January""" @@ -115,20 +157,21 @@ def format_year(year: int) -> str: """Format year number for display""" return f"'{year % 100:02}" - with open( - "include/release-cycle.svg", "w", encoding="UTF-8", newline="\n" - ) as f: + with open(out_path, "w", encoding="UTF-8", newline="\n") as f: template.stream( SCALE=SCALE, - diagram_width=DIAGRAM_WIDTH, - diagram_height=(len(self.sorted_versions) + 2) * LINE_HEIGHT, + diagram_width=DIAGRAM_WIDTH * SCALE, + diagram_height=(self.sorted_versions[0]["y"] + 2) * LINE_HEIGHT * SCALE, years=range(first_date.year, last_date.year + 1), - LINE_HEIGHT=LINE_HEIGHT, + line_height=LINE_HEIGHT * SCALE, + legend_width=LEGEND_WIDTH * SCALE, + right_margin=RIGHT_MARGIN * SCALE, versions=list(reversed(self.sorted_versions)), today=dt.datetime.strptime(today, "%Y-%m-%d").date(), year_to_x=year_to_x, date_to_x=date_to_x, format_year=format_year, + id_key=self.id_key, ).dump(f) @@ -145,8 +188,12 @@ def main() -> None: args = parser.parse_args() versions = Versions() + assert len(versions.versions) > 10 versions.write_csv() - versions.write_svg(args.today) + versions.write_svg(args.today, "include/release-cycle-all.svg") + + versions = Versions(limit_to_active=True, special_py27=True) + versions.write_svg(args.today, "include/release-cycle.svg") if __name__ == "__main__": diff --git a/_tools/release_cycle_template.svg.jinja b/_tools/release_cycle_template.svg.jinja index 5d39d307a..d3d5866a0 100644 --- a/_tools/release_cycle_template.svg.jinja +++ b/_tools/release_cycle_template.svg.jinja @@ -2,20 +2,26 @@ <svg xmlns="http://www.w3.org/2000/svg" class="release-cycle-chart" - viewBox="0 0 {{ diagram_width * SCALE }} {{ diagram_height * SCALE }}" + viewBox="0 0 {{ diagram_width }} {{ diagram_height }}" > + <defs> + <linearGradient id="release-cycle-mask-gradient-{{ id_key }}"> + <stop stop-color="black" offset="0%" /> + <stop stop-color="white" offset="100%" /> + </linearGradient> + </defs> {% for version in versions %} - {% set y = loop.index * LINE_HEIGHT %} + {% set y = version.y * line_height %} - {% if loop.index % 2 %} + {% if version.y % 2 %} <!-- Row shading --> <rect class="release-cycle-row-shade" x="0em" - y="{{ (y - 1.125) * SCALE }}" - width="{{ diagram_width * SCALE }}" - height="{{ LINE_HEIGHT * SCALE }}" + y="{{ y - 1.125 * SCALE }}" + width="{{ diagram_width }}" + height="{{ line_height }}" /> {% endif %} {% endfor %} @@ -23,8 +29,8 @@ {% for year in years %} <text class="release-cycle-year-text" - x="{{ (year_to_x(year) + year_to_x(year + 1)) / 2 * SCALE }}" - y="{{ (diagram_height - LINE_HEIGHT) * SCALE }}" + x="{{ (year_to_x(year) + year_to_x(year + 1)) / 2 }}" + y="{{ diagram_height - line_height }}" font-size="{{ SCALE * 0.75 }}" text-anchor="middle" > @@ -33,59 +39,159 @@ {% if not loop.last %} <line class="release-cycle-year-line" - x1="{{ year_to_x(year + 1) * SCALE }}" - x2="{{ year_to_x(year + 1) * SCALE }}" + x1="{{ year_to_x(year + 1) }}" + x2="{{ year_to_x(year + 1) }}" y1="0" - y2="{{ (diagram_height - LINE_HEIGHT) * SCALE }}" + y2="{{ diagram_height - line_height }}" font-size="{{ SCALE }}" /> {% endif %} {% endfor %} + <!-- Gradient mask to fade out end-of-life versions --> + <mask id="release-cycle-mask-{{ id_key }}"> + <rect + x="0" + y="0" + width="{{ legend_width }}" + height="{{ diagram_height }}" + fill="black" + /> + <rect + x="{{ legend_width - right_margin }}" + y="0" + width="{{ right_margin }}" + height="{{ diagram_height }}" + fill="url(#release-cycle-mask-gradient-{{ id_key }})" + /> + <rect + x="{{ legend_width }}" + y="0" + width="{{ diagram_width }}" + height="{{ diagram_height }}" + fill="white" + /> + </mask> + {% for version in versions %} - {% set y = loop.index * LINE_HEIGHT %} + <!-- Colourful blob with a label. --> + + {% set top_y = version.y * line_height - 1 * SCALE %} + {% set height = 1.25 * SCALE %} + {% set start_x = date_to_x(version.first_release_date) %} + {% 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 %} + + <!-- bugfix/security blobs need to be split between the two phases. + Draw the rectangle with two path elements instead. + Thanks Claude.ai for the initial conversion. + --> + {% set middle_x = ([end_x, date_to_x(version.start_security_date)]|min) %} + {% set left_width = (middle_x - start_x) %} + {% set right_width = (end_x - middle_x) %} + + {% if version.status != "end-of-life" %} + <!-- Split the blob using path operations + (Move-to, Vertical/Horizontal, Arc, Z=close shape; + lowercase means relative to the last point.) + We start drawing from the top of the straight boundary + between the half-blobs. + --> + <path + class="release-cycle-blob release-cycle-status-bugfix" + d=" + M{{ middle_x }},{{ top_y }} {#- start -#} + v{{ height }} {#- down -#} + H{{ start_x + radius }} {#- left -#} + a{{ radius }},{{ radius }} 90 0 1 {#- rounded corner -#} + {{ -radius }} {{ -radius }} + v{{ -height + 2*radius }} {#- up -#} + a{{ radius }},{{ radius }} 90 0 1 {#- rounded corner -#} + {{ radius }} {{ -radius }} + Z {#- right -#} + " + /> + <path + class="release-cycle-blob release-cycle-status-security" + d=" + M{{ middle_x }},{{ top_y }} {#- start -#} + v{{ height }} {#- down -#} + H{{ end_x - radius }} {#- right -#} + a{{ radius }},{{ radius }} 90 0 0 {#- rounded corner -#} + {{ radius }} {{ -radius }} + v{{ -height + 2*radius }} {#- up -#} + a{{ radius }},{{ radius }} 90 0 0 {#- rounded corner -#} + {{ -radius }} {{ -radius }} + Z {#- left -#} + " + /> + <!-- Add a common border --> + <rect + class="release-cycle-border release-cycle-status-{{ version.status }}" + x="{{ start_x }}" + y="{{ top_y }}" + width="{{ (end_x - start_x) }}" + height="{{ height }}" + rx="{{ radius }}" + ry="{{ radius }}" + /> + {% else %} + <!-- For EOL releases, use a single rounded rectangle --> + <rect + class="release-cycle-blob release-cycle-blob-full + release-cycle-status-{{ version.status }}" + x="{{ start_x }}" + y="{{ top_y }}" + width="{{ (end_x - start_x) }}" + height="{{ height }}" + rx="{{ radius }}" + ry="{{ radius }}" + mask="url(#release-cycle-mask-{{ id_key }})" + /> + {% endif %} + + <!-- Add text before/after/inside the blob --> + <text + class="release-cycle-blob-label release-cycle-status-{{ version.status }}" + font-size="{{ SCALE * 0.75 }}" + y="{{ small_text_y }}" + {% if version.status == "bugfix" %} + x="{{ (start_x + middle_x) / 2 }}" + text-anchor="middle" + {% elif version.status == "security" %} + x="{{ (middle_x + end_x) / 2 }}" + text-anchor="middle" + {% elif version.status == "end-of-life" %} + x="{{ end_x + (0.25 * SCALE) }}" + text-anchor="start" + {% else %} + x="{{ start_x - (0.25 * SCALE) }}" + text-anchor="end" + {% endif %} + > + {{ version.status }} + </text> <!-- Legend on the left --> <text class="release-cycle-version-label" x="{{ 0.5 * SCALE }}" - y="{{ y * SCALE }}" + y="{{ version.y * line_height }}" font-size="{{ SCALE }}" > Python {{ version.key }} </text> - - <!-- Colourful blob with a label --> - {% set start_x = date_to_x(version.first_release_date) %} - {% set end_x = date_to_x(version.end_of_life_date) %} - {% set mid_x = (start_x + end_x) / 2 %} - <rect - class="release-cycle-blob release-cycle-blob-{{ version.status }}" - x="{{ start_x * SCALE }}" - y="{{ (y - 1) * SCALE }}" - width="{{ (end_x - start_x) * SCALE }}" - height="{{ 1.25 * SCALE }}" - rx="0.25em" - ry="0.25em" - /> - <text - class="release-cycle-blob-label release-cycle-blob-{{ version.status }}" - x="{{ mid_x * SCALE }}" - y="{{ (y - 0.1) * SCALE }}" - font-size="{{ SCALE * 0.75 }}" - text-anchor="middle" - > - {{ version.status }} - </text> {% endfor %} <!-- A line for today --> <line class="release-cycle-today-line" - x1="{{ date_to_x(today) * SCALE }}" - x2="{{ date_to_x(today) * SCALE }}" + x1="{{ date_to_x(today) }}" + x2="{{ date_to_x(today) }}" y1="0" - y2="{{ (diagram_height - LINE_HEIGHT) * SCALE }}" + y2="{{ diagram_height - line_height }}" font-size="{{ SCALE }}" /> </svg> diff --git a/make.ps1 b/make.ps1 index 71a8f56f4..d6b5f3293 100644 --- a/make.ps1 +++ b/make.ps1 @@ -64,7 +64,8 @@ if ($target -Eq "clean") { $ToClean = @( $BUILDDIR, $_VENV_DIR, - "include/branches.csv", "include/end-of-life.csv", "include/release-cycle.svg" + "include/branches.csv", "include/end-of-life.csv", + "include/release-cycle.svg", "include/release-cycle-all.svg" ) foreach ($item in $ToClean) { if (Test-Path -Path $item) { diff --git a/versions.rst b/versions.rst index db7f94682..8cfd259f8 100644 --- a/versions.rst +++ b/versions.rst @@ -10,13 +10,12 @@ branch that accepts new features. The latest release for each Python version can be found on the `download page <https://www.python.org/downloads/>`_. -Python release cycle -==================== - .. raw:: html :file: include/release-cycle.svg -Another useful visualization is `endoflife.date/python <https://endoflife.date/python>`_. +(See :ref:`below <full-chart>` for a chart with older versions. +Another useful visualization is `endoflife.date/python <https://endoflife.date/python>`_.) + Supported versions ================== @@ -40,20 +39,37 @@ Unsupported versions :file: include/end-of-life.csv +.. _full-chart: + +Full chart +========== + +.. raw:: html + :file: include/release-cycle-all.svg + + Status key ========== -:feature: new features, bugfixes, and security fixes are accepted. -:prerelease: feature fixes, bugfixes, and security fixes are accepted for the - upcoming feature release. -:bugfix: bugfixes and security fixes are accepted, new binaries are still - released. (Also called **maintenance** mode or **stable** release) -:security: only security fixes are accepted and no more binaries are released, - but new source-only versions can be released -:end-of-life: release cycle is frozen; no further changes can be pushed to it. +Python releases go through five phases, as described in :pep:`602`. Release +managers can adjust specific dates as needed. -See also the :ref:`devcycle` page for more information about branches and backporting. +:feature: Before the first beta, the next full release can accept new features, + bug fixes, and security fixes. + +:prerelease: After the first beta, no new features can go in, but feature fixes + (including significant changes to new features), bug fixes, and security fixes + are accepted for the upcoming feature release. + +:bugfix: Once a version has been fully released, bug fixes and security fixes are + accepted. New binaries are built and released roughly every two months. This + phase is also called **maintenance** mode or **stable** release. -By default, the end-of-life is scheduled 5 years after the first release, -but can be adjusted by the release manager of each branch. All Python 2 -versions have reached end-of-life. +:security: After two years (18 months for versions before 3.13), only security + fixes are accepted and no more binaries are released. New source-only versions + can be released as needed. + +:end-of-life: Five years after a release, support ends. The release cycle is + frozen; no further changes are allowed. + +See also the :ref:`devcycle` page for more information about branches and backporting. From f4df9cc1b1cbbe9fceecf9932e6b7c0adeb5f378 Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Wed, 19 Mar 2025 06:43:54 -0600 Subject: [PATCH 450/538] use page titles as link text to avoid warnings (#1532) * use page titles as link text to avoid warnings Previously we had scary red messages: ``` devguide/core-developers/memorialization.rst:5: WARNING: Duplicate explicit target name: "here". [docutils] devguide/core-developers/memorialization.rst:5: WARNING: Duplicate explicit target name: "here". [docutils] ``` * remove a duplicate 'GitHub' --- core-developers/memorialization.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core-developers/memorialization.rst b/core-developers/memorialization.rst index 61ec0560c..b1e51cea2 100644 --- a/core-developers/memorialization.rst +++ b/core-developers/memorialization.rst @@ -41,8 +41,9 @@ The PSF staff does not follow up with GitHub with regards to GitHub account cancellation as this action is reserved for next-of-kin or designated by the deceased GitHub user to act as an account successor. -The general policy regarding deceased users on GitHub is described -`here <https://docs.github.com/en/site-policy/other-site-policies/github-deceased-user-policy>`_. +The general policy regarding deceased users on GitHub is described on their +`Deceased User Policy <https://docs.github.com/en/site-policy/other-site-policies/github-deceased-user-policy>`_ +page. Repositories in the organization -------------------------------- @@ -77,7 +78,9 @@ The "in memoriam" Discourse topic mentioned above is best created by a community member close to the deceased. The general best practice for deceased community members on -Discourse-powered forums is described `here <https://meta.discourse.org/t/best-practices-for-deceased-community-members/146210>`_. +Discourse-powered forums is described on their +`Best practices for deceased community members <https://meta.discourse.org/t/best-practices-for-deceased-community-members/146210>`_ +page. python.org email account ------------------------ @@ -135,7 +138,8 @@ 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 `here <https://support.discord.com/hc/en-us/articles/19872987802263--Deceased-or-Incapacitated-Users>`_. + is available on their `Deceased or Incapacitated Users <https://support.discord.com/hc/en-us/articles/19872987802263--Deceased-or-Incapacitated-Users>`_ + page. * The user is removed from Salt configuration for the PSF infrastructure in `/pillar/base/users <https://github.com/python/psf-salt/tree/main/pillar/base/users>`_ From 6ea7bd693eb9a5044b3166c6fd02a417486d9c58 Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Sun, 23 Mar 2025 17:11:09 -0600 Subject: [PATCH 451/538] contrib: restructure Getting Started - Setup and Building into a Workflows section (#1467) * todo: why duplicate toctree docs here? * general re-organization * contrib: replace Get Started with Workflows * a central links file This makes it easier to move content around without worrying about where the links are defined. It will also be easier to have canonical links that can be used from multiple places in the guide. * contrib: restructure Getting Started - Setup and Building into a Workflows section The Getting Started section has a lot of technical detail. I thought it would be better moved to the end, and referenced from the contribution paths earlier in the guide. I haven't updated the paths yet. Also: - I added a central links.rst that can be included anywhere. - I omitted the "Editors and tools" section. It doesn't provide any useful information. - Perhaps the Workflows section could be further categorized. - The `c_blah_start` and `c_blah_end` comments are only for the temporary inclusions being used to demonstrate the new organization. * re-order the columns --- contrib/core-team/index.rst | 2 + contrib/get-started/index.rst | 15 ------ contrib/index.rst | 29 ++++++----- contrib/project/directory-structure.rst | 17 +++++++ contrib/project/index.rst | 1 + contrib/workflows/codespaces.rst | 17 +++++++ contrib/workflows/compile.rst | 22 +++++++++ contrib/workflows/get-source.rst | 19 ++++++++ contrib/workflows/index.rst | 25 ++++++++++ contrib/workflows/install-dependencies.rst | 17 +++++++ contrib/workflows/install-git.rst | 17 +++++++ contrib/workflows/regenerate.rst | 28 +++++++++++ contrib/workflows/troubleshooting.rst | 17 +++++++ documentation/markup.rst | 3 ++ getting-started/setup-building.rst | 56 +++++++++++++++++----- links.rst | 6 +++ triage/labels.rst | 2 +- 17 files changed, 252 insertions(+), 41 deletions(-) delete mode 100644 contrib/get-started/index.rst create mode 100644 contrib/project/directory-structure.rst create mode 100644 contrib/workflows/codespaces.rst create mode 100644 contrib/workflows/compile.rst create mode 100644 contrib/workflows/get-source.rst create mode 100644 contrib/workflows/index.rst create mode 100644 contrib/workflows/install-dependencies.rst create mode 100644 contrib/workflows/install-git.rst create mode 100644 contrib/workflows/regenerate.rst create mode 100644 contrib/workflows/troubleshooting.rst create mode 100644 links.rst diff --git a/contrib/core-team/index.rst b/contrib/core-team/index.rst index 281ed0f47..a89d08aff 100644 --- a/contrib/core-team/index.rst +++ b/contrib/core-team/index.rst @@ -5,6 +5,8 @@ |purpose| +.. _c_coreteam: + ========= Core team ========= diff --git a/contrib/get-started/index.rst b/contrib/get-started/index.rst deleted file mode 100644 index 70e61b1b1..000000000 --- a/contrib/get-started/index.rst +++ /dev/null @@ -1,15 +0,0 @@ -.. _c_gettingstarted: - -=============== -Getting started -=============== - -.. important:: - - |draft| - - |purpose| - - -* Basic setup -* Git bootcamp (simplified for everyone to use) diff --git a/contrib/index.rst b/contrib/index.rst index b3ef0d992..f9b54bc56 100644 --- a/contrib/index.rst +++ b/contrib/index.rst @@ -52,7 +52,6 @@ these common sections: * :ref:`c_intro` * :ref:`c_project` -* :ref:`c_gettingstarted` Then choose a path based on your type of activity: @@ -68,18 +67,10 @@ major section at the top of each column.]* :widths: 10 10 10 :header-rows: 1 - * - :ref:`Triaging <c_triage>` - - :ref:`Documentation <c_docs>` + * - :ref:`Documentation <c_docs>` - :ref:`Code <c_code>` + - :ref:`Triaging <c_triage>` * - - * :ref:`tracker` - * :ref:`triaging` - * :ref:`helptriage` - * :ref:`experts` - * :ref:`labels` - * :ref:`gh-faq` - * :ref:`triage-team` - - * :ref:`docquality` * :ref:`documenting` * :ref:`style-guide` @@ -95,7 +86,19 @@ major section at the top of each column.]* * :ref:`communication` * :ref:`gitbootcamp` * :ref:`devcycle` + - + * :ref:`tracker` + * :ref:`triaging` + * :ref:`helptriage` + * :ref:`experts` + * :ref:`labels` + * :ref:`gh-faq` + * :ref:`triage-team` + +Core team members will find guidance in the :ref:`c_coreteam` section. +Contents +======== .. toctree:: :maxdepth: 3 @@ -103,13 +106,13 @@ major section at the top of each column.]* contrib-plan intro/index project/index - get-started/index triage/index - code/index doc/index + code/index core-team/index user-success security + workflows/index .. _Python: https://www.python.org/ diff --git a/contrib/project/directory-structure.rst b/contrib/project/directory-structure.rst new file mode 100644 index 000000000..0cebb25f7 --- /dev/null +++ b/contrib/project/directory-structure.rst @@ -0,0 +1,17 @@ +.. important:: + + |draft| + + |purpose| + +.. _c_directory_structure: + +=================== +Directory structure +=================== + +[This is the :ref:`build_directory_structure` section from the devguide.] + +.. include:: ../../getting-started/setup-building.rst + :start-after: c_directory_structure_start + :end-before: c_directory_structure_end diff --git a/contrib/project/index.rst b/contrib/project/index.rst index 5d26b15aa..9d3c89b9a 100644 --- a/contrib/project/index.rst +++ b/contrib/project/index.rst @@ -24,5 +24,6 @@ moving parts, who is involved, how do they interact?] governance generative-ai.rst github + directory-structure.rst channels outreach diff --git a/contrib/workflows/codespaces.rst b/contrib/workflows/codespaces.rst new file mode 100644 index 000000000..eb97ef7c2 --- /dev/null +++ b/contrib/workflows/codespaces.rst @@ -0,0 +1,17 @@ +.. important:: + + |draft| + + |purpose| + +.. _c_using_codespaces: + +======================= +Using GitHub Codespaces +======================= + +[This is the :ref:`using-codespaces` section from the devguide.] + +.. include:: ../../getting-started/setup-building.rst + :start-after: c_codespaces_start + :end-before: c_codespaces_end diff --git a/contrib/workflows/compile.rst b/contrib/workflows/compile.rst new file mode 100644 index 000000000..18157b717 --- /dev/null +++ b/contrib/workflows/compile.rst @@ -0,0 +1,22 @@ +.. important:: + + |draft| + + |purpose| + +.. _c_compiling: + +================= +Compile and build +================= + +.. note:: + [This is the :ref:`compiling` section from the devguide. I think this page + is too long and could be split by build target, but we can leave that for a + later time.] + +.. include:: ../../getting-started/setup-building.rst + :start-after: c_compile_and_build_start + :end-before: c_compile_and_build_end + +.. include:: ../../links.rst diff --git a/contrib/workflows/get-source.rst b/contrib/workflows/get-source.rst new file mode 100644 index 000000000..ed56fe4e1 --- /dev/null +++ b/contrib/workflows/get-source.rst @@ -0,0 +1,19 @@ +.. important:: + + |draft| + + |purpose| + +.. _c_checkout: + +=================== +Get the source code +=================== + +.. note:: + [This is the :ref:`checkout` section from the devguide. We might need to edit + it to clarify that some steps are only needed for code contribution.] + +.. include:: ../../getting-started/setup-building.rst + :start-after: c_get_source_code_start + :end-before: c_get_source_code_end diff --git a/contrib/workflows/index.rst b/contrib/workflows/index.rst new file mode 100644 index 000000000..2c6ccf2bc --- /dev/null +++ b/contrib/workflows/index.rst @@ -0,0 +1,25 @@ +.. _c_workflows: + +========= +Workflows +========= + +.. important:: + + |draft| + + |purpose| + + +This section contains details of workflows needed for all kinds of +contribution. + +.. toctree:: + + install-git.rst + get-source.rst + install-dependencies.rst + compile.rst + regenerate.rst + troubleshooting.rst + codespaces.rst diff --git a/contrib/workflows/install-dependencies.rst b/contrib/workflows/install-dependencies.rst new file mode 100644 index 000000000..9a511c6da --- /dev/null +++ b/contrib/workflows/install-dependencies.rst @@ -0,0 +1,17 @@ +.. important:: + + |draft| + + |purpose| + +.. _c_build-dependencies: + +==================== +Install Dependencies +==================== + +[This is the :ref:`build-dependencies` section from the devguide.] + +.. include:: ../../getting-started/setup-building.rst + :start-after: c_install_dependencies_start + :end-before: c_install_dependencies_end diff --git a/contrib/workflows/install-git.rst b/contrib/workflows/install-git.rst new file mode 100644 index 000000000..e3d738b2a --- /dev/null +++ b/contrib/workflows/install-git.rst @@ -0,0 +1,17 @@ +.. important:: + + |draft| + + |purpose| + +.. _c_vcsetup: + +=========== +Install Git +=========== + +[This is the :ref:`vcsetup` section from the devguide.] + +.. include:: ../../getting-started/setup-building.rst + :start-after: c_install_git_start + :end-before: c_install_git_end diff --git a/contrib/workflows/regenerate.rst b/contrib/workflows/regenerate.rst new file mode 100644 index 000000000..b5bca7dca --- /dev/null +++ b/contrib/workflows/regenerate.rst @@ -0,0 +1,28 @@ +.. important:: + + |draft| + + |purpose| + +.. _c_regenerating: + +=============================== +Regenerating auto-created files +=============================== + +.. note:: + [These are two similar sections from the is the :ref:`setup-building` section from the devguide.] + +Regenerate ``configure`` +======================== + +.. include:: ../../getting-started/setup-building.rst + :start-after: c_regenerate_configure_start + :end-before: c_regenerate_configure_end + +Regenerate the ABI dump +======================= + +.. include:: ../../getting-started/setup-building.rst + :start-after: c_regenerate_abi_start + :end-before: c_regenerate_abi_end diff --git a/contrib/workflows/troubleshooting.rst b/contrib/workflows/troubleshooting.rst new file mode 100644 index 000000000..68aa80158 --- /dev/null +++ b/contrib/workflows/troubleshooting.rst @@ -0,0 +1,17 @@ +.. important:: + + |draft| + + |purpose| + +.. _c_build_troubleshooting: + +=========== +Install Git +=========== + +[This is the :ref:`build_troubleshooting` section from the devguide.] + +.. include:: ../../getting-started/setup-building.rst + :start-after: c_build_troubleshooting_start + :end-before: c_build_troubleshooting_end diff --git a/documentation/markup.rst b/documentation/markup.rst index fc8deb4bb..ce9ba648d 100644 --- a/documentation/markup.rst +++ b/documentation/markup.rst @@ -1215,6 +1215,9 @@ units as well as normal text: Table-of-contents markup ------------------------ +.. TODO: This is a copy of the Sphinx description of the toctree directive. + Why duplicate it here? + Since reST does not have facilities to interconnect several documents, or split documents into multiple output files, Sphinx uses a custom directive to add relations between the single files the documentation is made of, as well as diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 03b2777b8..29342ffc9 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -36,6 +36,8 @@ and are provided for development and testing purposes only. Install Git =========== +.. c_install_git_start + CPython is developed using `Git <https://git-scm.com>`_ 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. @@ -58,12 +60,15 @@ itself. Git is easily available for all common operating systems. ``git push``, or ``git fetch``. On Windows, you should also :ref:`enable autocrlf <autocrlf>`. +.. c_install_git_end .. _checkout: Get the source code =================== +.. c_get_source_code_start + The CPython repo is hosted on GitHub. To get a copy of the source code you should :ref:`fork the Python repository on GitHub <fork-cpython>`, :ref:`create a local clone of your personal fork, and configure the remotes <clone-your-fork>`. @@ -143,11 +148,15 @@ To make sure your code is linted correctly, we recommend setting up Now pre-commit will run automatically on ``git commit``. +.. c_get_source_code_end + .. _compiling: Compile and build ================= +.. c_compile_and_build_start + CPython provides several compilation flags which help with debugging various things. While all of the known flags can be found in the ``Misc/SpecialBuilds.txt`` file, the most critical one is the ``Py_DEBUG`` flag @@ -606,6 +615,8 @@ single test, or a subset of tests. See the `iOS README <https://github.com/python/cpython/blob/main/iOS/README.rst#debugging-test-failures>`__ for details. +.. c_compile_and_build_end + .. _build-dependencies: .. _deps-on-linux: .. _macOS and OS X: @@ -614,6 +625,8 @@ for details. Install dependencies ==================== +.. c_install_dependencies_start + This section explains how to install libraries which are needed to compile some of CPython's modules (for example, ``zlib``). @@ -784,9 +797,6 @@ some of CPython's modules (for example, ``zlib``). to the `macOS README <https://github.com/python/cpython/blob/main/Mac/README.rst>`_. - .. _clang: https://clang.llvm.org/ - .. _ccache: https://ccache.dev/ - .. 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 written completely in Python: as of this writing, CPython contains slightly @@ -825,11 +835,15 @@ some of CPython's modules (for example, ``zlib``). CPython. If you use the pre-compiled binaries, you should unpack each tarball into a separate folder, and use that folder as the configuration target. +.. c_install_dependencies_end + .. _regenerate_configure: Regenerate ``configure`` ======================== +.. c_regenerate_configure_start + 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. @@ -868,19 +882,21 @@ and make sure the :file:`pkg.m4` macro file located in the appropriate :program:`autoreconf` runs :program:`autoconf` and a number of other tools repeatedly as appropriate. -.. _build_troubleshooting: +.. c_regenerate_configure_end Regenerate the ABI dump ======================= +.. c_regenerate_abi_start + Maintenance branches (not ``main``) have a special file located in -``Doc/data/pythonX.Y.abi`` that allows us to know if a given Pull Request +``Doc/data/pythonX.Y.abi`` that allows us to know if a given pull request affects the public ABI. This file is used by the GitHub CI in a check -called ``Check if the ABI has changed`` that will fail if a given Pull Request +called ``Check if the ABI has changed`` that will fail if a given pull request has changes to the ABI and the ABI file is not updated. -This check acts as a fail-safe and **doesn't necessarily mean that the Pull -Request cannot be merged**. When this check fails you should add the relevant +This check acts as a fail-safe and **doesn't necessarily mean that the pull +request cannot be merged**. When this check fails you should add the relevant release manager to the PR so that they are aware of the change and they can validate if the change can be made or not. @@ -909,9 +925,15 @@ Note that the ``ubuntu`` version used to execute the script matters and **must** match the version used by the CI to check the ABI. See the ``.github/workflows/build.yml`` file for more information. +.. c_regenerate_abi_end + +.. _build_troubleshooting: + Troubleshoot the build ====================== +.. c_build_troubleshooting_start + This section lists some of the common problems that may arise during the compilation of Python, with proposed solutions. @@ -930,6 +952,8 @@ To overcome this problem, auto-generated files are also checked into the Git repository. So if you don't touch the auto-generation scripts, there's no real need to auto-generate anything. +.. c_build_troubleshooting_end + Editors and tools ================= @@ -940,11 +964,13 @@ support. For editors and tools which the core developers have felt some special comment is needed for coding *in* Python, see :ref:`resources`. -.. _build-directory-structure: +.. _build_directory_structure: Directory structure =================== +.. c_directory_structure_start + There are several top-level directories in the CPython source tree. Knowing what each one is meant to hold will help you find where a certain piece of functionality is implemented. Do realize, though, there are always exceptions to @@ -1000,8 +1026,7 @@ every rule. ``Tools`` Various tools that are (or have been) used to maintain Python. - -.. _issue tracker: https://github.com/python/cpython/issues +.. c_directory_structure_end .. _using-codespaces: @@ -1009,6 +1034,8 @@ every rule. Contribute using GitHub Codespaces ================================== +.. c_codespaces_start + .. _codespaces-whats-codespaces: What is GitHub Codespaces? @@ -1069,5 +1096,10 @@ 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. - .. TODO: add docker instructions + +.. c_codespaces_end + + + +.. include:: ../links.rst diff --git a/links.rst b/links.rst new file mode 100644 index 000000000..4f0eb5881 --- /dev/null +++ b/links.rst @@ -0,0 +1,6 @@ +.. Links for use anywhere. Include this file to use them. + +.. _issue tracker: https://github.com/python/cpython/issues + +.. _clang: https://clang.llvm.org/ +.. _ccache: https://ccache.dev/ diff --git a/triage/labels.rst b/triage/labels.rst index d78f6b472..3abaf5369 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -41,7 +41,7 @@ Component labels ================ These labels are mostly used to specify which :ref:`part of the codebase -<build-directory-structure>` is affected by the issue/PR: +<build_directory_structure>` is affected by the issue/PR: * :gh-label:`stdlib`: for standard library modules in the :cpy-file:`Lib` directory (written in Python). From 9c257f95a16682fbc707d8d8b2a6fa04a6bca354 Mon Sep 17 00:00:00 2001 From: Hood Chatham <roberthoodchatham@gmail.com> Date: Wed, 26 Mar 2025 12:50:07 +0100 Subject: [PATCH 452/538] Add section on building for Emscripten (#1533) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- getting-started/setup-building.rst | 91 ++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 29342ffc9..64d7f054b 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -467,6 +467,97 @@ used in ``python.sh``: .. _wasmtime: https://wasmtime.dev .. _WebAssembly: https://webassembly.org + +Emscripten +---------- + +Emscripten_ is a complete open-source compiler toolchain. It compiles C/C++ code +into WebAssembly_/JavaScript executables, for use in JavaScript runtimes, +including browsers and Node.js. + +.. note:: + + The instructions below assume a Unix-based OS due to cross-compilation for + CPython being designed for ``./configure`` / ``make``. + +To build for Emscripten, you will need to cross-compile CPython. This requires a +C compiler just like building for :ref:`Unix <unix-compiling>` as well as: + +* The Emscripten compiler +* Node.js + +The simplest way to install the Emscripten compiler is: + +.. code-block:: sh + + # Install Emscripten + git clone https://github.com/emscripten-core/emsdk + ./emsdk/emsdk install 4.0.5 + ./emsdk/emsdk activate 4.0.5 + 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``. + +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 +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). + +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): + +.. code-block:: shell + + python3 Tools/wasm/emscripten build --quiet -- --config-cache --with-pydebug + +That single command will configure and build both the build Python and the +Emscripten build in ``cross-build/build`` and +``cross-build/wasm32-emscripten/build/python/``, 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/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 configure-host --quiet -- --config-cache + python Tools/wasm/emscripten make-host --quiet + +.. note:: + + The ``configure-host`` command infers the use of ``--with-pydebug`` from the + build Python. + +Running the separate commands after ``emscripten 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-emscripten/build/python/python.sh`` helper file which you +can use to run the ``python.mjs`` file: + +.. code-block:: shell + + cross-build/wasm32-emscripten/build/python/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 +used in ``python.sh``: + +.. code-block:: shell + + make -C cross-build/wasm32-emscripten/build/python/ test + + +.. _Emscripten: https://emscripten.org/ +.. _WebAssembly: https://webassembly.org + + Android ------- From c194d71d7d88272e4fc097129af6856ebf07d24a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 8 Apr 2025 21:51:25 +0300 Subject: [PATCH 453/538] Python 3.12 is now in security-only (#1536) --- 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 b77e90487..54367b2ad 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -18,7 +18,7 @@ "3.12": { "branch": "3.12", "pep": 693, - "status": "bugfix", + "status": "security", "first_release": "2023-10-02", "end_of_life": "2028-10", "release_manager": "Thomas Wouters" From c696ab556faabae8fe0328ec9467c25bacb72111 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 9 Apr 2025 23:36:42 +0300 Subject: [PATCH 454/538] Update info about new CLA bot (#1538) --- core-developers/committing.rst | 3 ++- developer-workflow/communication-channels.rst | 10 ++++++---- getting-started/pull-request-lifecycle.rst | 6 +++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/core-developers/committing.rst b/core-developers/committing.rst index 326578c0b..d83d42321 100644 --- a/core-developers/committing.rst +++ b/core-developers/committing.rst @@ -62,7 +62,8 @@ to enter the public source tree. Ask yourself the following questions: Licensing Agreement <https://www.python.org/psf/contrib/contrib-form/>`_ (CLA), unless their change has no possible intellectual property associated with it (for example, fixing a spelling mistake in documentation). - The `CPython CLA Bot <https://github.com/apps/cpython-cla-bot/>`_ + The `Python Software Foundation Contributor License Agreement Management Bot + <https://github.com/psf/clabot>`_ 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. diff --git a/developer-workflow/communication-channels.rst b/developer-workflow/communication-channels.rst index 00c569178..e9360d201 100644 --- a/developer-workflow/communication-channels.rst +++ b/developer-workflow/communication-channels.rst @@ -250,15 +250,16 @@ order to make open source pleasant for everyone involved. Additional repositories ======================= -`Python Core Workflow`_ hosts the codebase for tools such as :pypi:`blurb`. +`Python Core Workflow`_ hosts an issue tracker for workflow discussions. -Other core workflow tools are: +Some core workflow tools are: * `cherry_picker`_ (:pypi:`PyPI <cherry_picker>`) * `bedevere`_ +* `blurb`_ (:pypi:`PyPI <blurb>`) * `blurb_it`_ * `miss-islington`_ -* `cla-bot`_ +* `clabot`_ * `webhook-mailer`_ Python `Performance Benchmark`_ project is intended to be an authoritative @@ -267,8 +268,9 @@ source of benchmarks for all Python implementations. .. _Python Core Workflow: https://github.com/python/core-workflow .. _cherry_picker: https://github.com/python/cherry-picker .. _bedevere: https://github.com/python/bedevere +.. _blurb: https://github.com/python/blurb .. _blurb_it: https://github.com/python/blurb_it .. _miss-islington: https://github.com/python/miss-islington -.. _cla-bot: https://github.com/ambv/cla-bot +.. _clabot: https://github.com/psf/clabot .. _webhook-mailer: https://github.com/python/webhook-mailer .. _Performance Benchmark: https://github.com/python/pyperformance diff --git a/getting-started/pull-request-lifecycle.rst b/getting-started/pull-request-lifecycle.rst index 59242f13f..f95ad6555 100644 --- a/getting-started/pull-request-lifecycle.rst +++ b/getting-started/pull-request-lifecycle.rst @@ -354,14 +354,14 @@ Here are the steps needed in order to sign the CLA: 1. Create a change and submit it as a pull request. -2. When ``cpython-cla-bot`` comments on your pull request that commit +2. When ``python-cla-bot`` comments on your pull request that commit authors are required to sign a Contributor License Agreement, click on the button in the comment to sign it. It's enough to log in through GitHub. The process is automatic. -3. After signing, the comment by ``cpython-cla-bot`` will update to +3. After signing, the comment by ``python-cla-bot`` will update to indicate that "all commit authors signed the Contributor License - Agreement. + Agreement". .. _PSF license: https://docs.python.org/dev/license.html#terms-and-conditions-for-accessing-or-otherwise-using-python .. _contributor agreement: https://www.python.org/psf/contrib/ From 3e45e1777b10337b9d211c6c9c79f21e0f198acb Mon Sep 17 00:00:00 2001 From: Barry Warsaw <barry@python.org> Date: Wed, 16 Apr 2025 16:47:10 -0700 Subject: [PATCH 455/538] A few minor clarifications about the new developer process (#1539) --- core-developers/become-core-developer.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core-developers/become-core-developer.rst b/core-developers/become-core-developer.rst index 739792b48..70b7e25af 100644 --- a/core-developers/become-core-developer.rst +++ b/core-developers/become-core-developer.rst @@ -38,10 +38,12 @@ are granted through these steps: #. If the candidate receives at least two-thirds positive votes when the poll closes (as per :pep:`13`), the submitter `emails the steering council <mailto:steering-council@python.org>`_ with the candidate's email address - requesting that the council either accept or reject the proposed membership. + requesting that the council either accept or reject the proposed membership. Technically, the + council may only `veto a positive vote <https://peps.python.org/pep-0013/#membership>`_. -#. Assuming the steering council does not object, a member of the council or delegate - (approver) will email the candidate: +#. 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 <current owners>`) will + email the candidate: - A request for account details as required by `🔒 python/voters <https://github.com/python/voters>`_. From 26de2eff7b7dc964fa62d891ddfdc5933ef2850b Mon Sep 17 00:00:00 2001 From: Zachary Ware <zach@python.org> Date: Thu, 17 Apr 2025 14:34:09 -0500 Subject: [PATCH 456/538] Remove myself from the Windows expert list (#1540) --- 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 683f35462..25dfbd5f7 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -299,7 +299,7 @@ macOS ronaldoussoren, ned-deily, freakboy3742 NetBSD1 OS2/EMX aimacintyre^ Solaris/OpenIndiana jcea, kulikjak -Windows tjguk, zware, zooba, pfmoore +Windows tjguk, zooba, pfmoore JVM/Java frank.wierzbicki^ =================== =========== From f1b7e2505ab681933931c3b32e7db3036fa50039 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Fri, 18 Apr 2025 20:40:40 +0100 Subject: [PATCH 457/538] Ensure ``make -j`` uses a reasonable argument (#1541) ``make -j`` means no limit on the number of concurrent jobs, rather than a sensible number constrained by the system's resources. When building with LTO, it is easy to run out of memory when too many jobs run at the same time. Co-authored-by: Thomas Wouters <thomas@python.org> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- developer-workflow/extension-modules.rst | 7 +++++-- getting-started/setup-building.rst | 13 ++++++------- index.rst | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/developer-workflow/extension-modules.rst b/developer-workflow/extension-modules.rst index 61c1ff08a..d6be88824 100644 --- a/developer-workflow/extension-modules.rst +++ b/developer-workflow/extension-modules.rst @@ -547,8 +547,11 @@ Now that the configuration is in place, it remains to compile the project: .. tip:: - Use ``make -j`` to speed-up compilation by utilizing as many CPU cores - as possible or ``make -jN`` to allow at most *N* concurrent jobs. + Use ``make -jN`` to speed-up compilation by utilizing as many CPU cores + as possible, where *N* is as many CPU cores you want to spare (and have + memory for). Be careful using ``make -j`` with no argument, as this puts + no limit on the number of jobs, and compilation can sometimes use up a + lot of memory (like when building with LTO). * ``make regen-configure`` updates the :cpy-file:`configure` script. diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 64d7f054b..0db68d18b 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -203,14 +203,13 @@ do to get a pydebug build of CPython. Once ``configure`` is done, you can then compile CPython with:: - $ make -s -j2 + $ make -s -j $(nproc) This will build CPython with only warnings and errors being printed to -stderr and utilize up to 2 CPU cores. If you are using a multi-core machine -with more than 2 cores (or a single-core machine), you can adjust the number -passed into the ``-j`` flag to match the number of cores you have (or if your -version of Make supports it, you can use ``-j`` without a number and Make -will not limit the number of steps that can run simultaneously.). +stderr. The ``-j`` argument means that :program:`make` will concurrently run +tasks, limiting the number of parallel jobs to the number of CPU cores in your +computer. You can adjust the number passed to the ``-j`` flag to change +the limit on parallel jobs, which can trade RAM usage versus compilation time. At the end of the build you should see a success message, followed by a list of extension modules that haven't been built because their @@ -875,7 +874,7 @@ some of CPython's modules (for example, ``zlib``). And finally, run ``make``:: - $ make -s -j2 + $ make -s -j $(nproc) There will sometimes be optional modules added for a new release which won't yet be identified in the OS-level build dependencies. In those cases, diff --git a/index.rst b/index.rst index 9dbc06908..138211a03 100644 --- a/index.rst +++ b/index.rst @@ -43,13 +43,13 @@ instructions please see the :ref:`setup guide <setup>`. .. code-block:: shell - ./configure --with-pydebug && make -j + ./configure --with-pydebug && make -j $(nproc) .. tab:: macOS .. code-block:: shell - ./configure --with-pydebug && make -j + ./configure --with-pydebug && make -j $(nproc) .. tab:: Windows From 3dcd01d090f4d2b99cdea1bbe75b220b9e11d997 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 30 Apr 2025 12:02:03 +0300 Subject: [PATCH 458/538] Use 'make -j8' for macOS (#1545) --- getting-started/setup-building.rst | 2 +- index.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index 0db68d18b..e1f5398eb 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -874,7 +874,7 @@ some of CPython's modules (for example, ``zlib``). And finally, run ``make``:: - $ make -s -j $(nproc) + $ make -s -j8 There will sometimes be optional modules added for a new release which won't yet be identified in the OS-level build dependencies. In those cases, diff --git a/index.rst b/index.rst index 138211a03..b70461dc0 100644 --- a/index.rst +++ b/index.rst @@ -49,7 +49,7 @@ instructions please see the :ref:`setup guide <setup>`. .. code-block:: shell - ./configure --with-pydebug && make -j $(nproc) + ./configure --with-pydebug && make -j8 .. tab:: Windows @@ -74,7 +74,7 @@ instructions please see the :ref:`setup guide <setup>`. .. code-block:: shell - ./python.exe -m test -j3 + ./python.exe -m test -j8 Note: :ref:`Most <mac-python.exe>` macOS systems use :file:`./python.exe` in order to avoid filename conflicts with From c8677dbfa1ce2ad6b44fa1e2f8df675d80f7098e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 30 Apr 2025 18:34:19 +0300 Subject: [PATCH 459/538] Remove outdated reference to note about 3.5 branch (#1546) --- developer-workflow/development-cycle.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index 8a37692ad..d807d74ec 100644 --- a/developer-workflow/development-cycle.rst +++ b/developer-workflow/development-cycle.rst @@ -178,9 +178,6 @@ and beta releases. Being in beta can be viewed much like being in RC_ but without the extra overhead of needing commit reviews. -Please see the note in the `In-development (main) branch`_ section above for -new information about the creation of the 3.5 maintenance branch during beta. - .. _rc: From 446ccf0641612f049e2cc16ce2c9de931bc8b98a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 30 Apr 2025 19:12:18 +0300 Subject: [PATCH 460/538] Remove redundant ``--keep-going`` when running Sphinx (#1544) --- Makefile | 4 ++-- make.bat | 2 +- make.ps1 | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 6baf33b32..9817feb15 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,8 @@ SPHINXBUILD = $(VENVDIR)/bin/sphinx-build # there are duplicate labels. These cause warnings, which prevent the # build from finishing. Turn off --fail-on-warning so we can see the # finished results. -#SPHINXOPTS = --fail-on-warning --keep-going -SPHINXOPTS = --keep-going +#SPHINXOPTS = --fail-on-warning +SPHINXOPTS = BUILDDIR = _build BUILDER = html JOBS = auto diff --git a/make.bat b/make.bat index b48678366..fec822e95 100644 --- a/make.bat +++ b/make.bat @@ -11,7 +11,7 @@ if "%PYTHON%" == "" ( ) set BUILDDIR=_build -set SPHINXOPTS=--fail-on-warning --keep-going +set SPHINXOPTS=--fail-on-warning set _ALL_SPHINX_OPTS=%SPHINXOPTS% if "%1" == "check" goto check diff --git a/make.ps1 b/make.ps1 index d6b5f3293..ffda67269 100644 --- a/make.ps1 +++ b/make.ps1 @@ -8,7 +8,7 @@ Set-StrictMode -Version 3.0 $ErrorActionPreference = "Stop" $BUILDDIR = "_build" -$SPHINXOPTS = "--fail-on-warning --keep-going" +$SPHINXOPTS = "--fail-on-warning" $_ALL_SPHINX_OPTS = $SPHINXOPTS $_PYTHON = $Env:PYTHON ?? "py -3" From 394cbc4b13b866fa1588c3b8ac2ce70f33c41195 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 5 May 2025 21:21:31 +0100 Subject: [PATCH 461/538] Correct grammar in label description (#1550) --- triage/labels.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triage/labels.rst b/triage/labels.rst index 3abaf5369..d87880357 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -130,7 +130,7 @@ Other labels * :gh-label:`sprint`: for easier filtering of issues/PRs being worked on during official sprints. * :gh-label:`stale`: for issues/PRs that have been inactive for a while. -* :gh-label:`triaged`: for issue has been accepted as valid by a triager. +* :gh-label:`triaged`: for issues that have been accepted as valid by a triager. .. _GitHub Labels for PRs: From f34189c158b40fdccfc8f14f2bd47af0df247278 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 5 May 2025 21:22:10 +0100 Subject: [PATCH 462/538] Fix blocker label description (#1549) --- triage/labels.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/triage/labels.rst b/triage/labels.rst index d87880357..8fd6f345e 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -122,11 +122,11 @@ Other labels * :gh-label:`pending`: for issues/PRs that will be closed unless further feedback is provided. * :gh-label:`release-blocker`/:gh-label:`deferred-blocker`: for issues/PRs - and the :ref:`branch's release manager <branchstatus>` - removing or retaining the label as appropriate. that, unless fixed, will hold the current or next release respectively. Triagers may set these labels for issues that must be fixed before a release, + and the :ref:`branch's release manager <branchstatus>` will review them and determine if they indeed qualify, + removing or retaining the label as appropriate. * :gh-label:`sprint`: for easier filtering of issues/PRs being worked on during official sprints. * :gh-label:`stale`: for issues/PRs that have been inactive for a while. From d7d1fd3a72b9d0539b35f90f2ec534dad2afa411 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 7 May 2025 20:13:59 +0300 Subject: [PATCH 463/538] Add Python 3.15 (#1552) --- include/release-cycle.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/release-cycle.json b/include/release-cycle.json index 54367b2ad..d6811f6d1 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -1,8 +1,16 @@ { - "3.14": { + "3.15": { "branch": "main", - "pep": 745, + "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": "prerelease", "first_release": "2025-10-01", "end_of_life": "2030-10", "release_manager": "Hugo van Kemenade" From d4d960897e405b5b7d3be1befc1c25ec6473d15a Mon Sep 17 00:00:00 2001 From: Savannah Bailey <savannahostrowski@gmail.com> Date: Thu, 8 May 2025 13:16:44 -0700 Subject: [PATCH 464/538] Savannah Ostrowski to Savannah Bailey (#1551) --- core-developers/developers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index c8afa93c6..567093ba5 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,5 +1,5 @@ Bénédikt Tran,picnixz,2025-01-10,, -Savannah Ostrowski,savannahostrowski,2024-11-13,, +Savannah Bailey,savannahostrowski,2024-11-13,, Matt Page,mpage,2024-10-10,, Kirill Podoprigora,Eclips4,2024-09-20,, Ned Batchelder,nedbat,2024-07-16,, From 3dba230066d05f65019ad89cd772f06aae1812f7 Mon Sep 17 00:00:00 2001 From: Maciej Olko <maciej.olko@gmail.com> Date: Thu, 8 May 2025 23:29:43 +0200 Subject: [PATCH 465/538] Fix first release date of Python 3.14 (#1555) --- 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 d6811f6d1..214871b64 100644 --- a/include/release-cycle.json +++ b/include/release-cycle.json @@ -11,7 +11,7 @@ "branch": "3.14", "pep": 745, "status": "prerelease", - "first_release": "2025-10-01", + "first_release": "2025-10-07", "end_of_life": "2030-10", "release_manager": "Hugo van Kemenade" }, From 3e3055e6b1d5272700adaf84d6d1dd2560d578d5 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 10 May 2025 12:27:19 +0100 Subject: [PATCH 466/538] Exclude github.com in linkcheck (#1556) --- conf.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/conf.py b/conf.py index 0319de4dd..769cd19d1 100644 --- a/conf.py +++ b/conf.py @@ -84,18 +84,9 @@ r'\/.*', ] -# Check the link itself, but ignore anchors that are added by JS -# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-linkcheck_anchors_ignore_for_url -linkcheck_anchors_ignore_for_url = [ - # GitHub - r'https://github.com/.*', -] - linkcheck_ignore = [ - # The voters repo is private and appears as a 404 - 'https://github.com/python/voters', - # The python-core team link is private, redirects to login - 'https://github.com/orgs/python/teams/python-core', + # Checks fail due to rate limits + r'https://github.com/.*', # The Discourse groups are private unless you are logged in 'https://discuss.python.org/groups/staff', 'https://discuss.python.org/groups/moderators', From 24f7a45c49574d0eb32b4cc7fac87806da03439c Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 10 May 2025 22:30:13 +0100 Subject: [PATCH 467/538] Add zstd to build dependencies (#1558) --- core-developers/experts.rst | 9 +++++---- getting-started/setup-building.rst | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 25dfbd5f7..75d2a6b20 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -66,7 +66,6 @@ bdb binascii bisect rhettinger* builtins -bz2 calendar cmath cmd @@ -77,6 +76,11 @@ collections rhettinger* collections.abc rhettinger*, stutzbach^ colorsys compileall carljm +compression.bz2 +compression.gzip +compression.lzma +compression.zlib Yhg1s, gpshead* +compression.zstd concurrent.futures pitrou, brianquinlan, gpshead* configparser ambv* contextlib ncoghlan, 1st1 @@ -114,7 +118,6 @@ getpass gettext glob grp -gzip hashlib tiran, gpshead*, picnixz heapq rhettinger*, stutzbach^ hmac tiran, gpshead*, picnixz @@ -135,7 +138,6 @@ libmpdec linecache locale malemburg logging vsajip -lzma mailbox marshal math rhettinger, stutzbach^ @@ -257,7 +259,6 @@ xmlrpc zipapp pfmoore zipfile alanmcintyre^, serhiy-storchaka, Yhg1s, gpshead zipimport Yhg1s* -zlib Yhg1s, gpshead* ==================== ============================================= diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index e1f5398eb..3229d54f8 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -739,9 +739,9 @@ some of CPython's modules (for example, ``zlib``). $ sudo dnf install \ gcc gcc-c++ gdb lzma glibc-devel libstdc++-devel openssl-devel \ - readline-devel zlib-devel libffi-devel bzip2-devel xz-devel \ - sqlite sqlite-devel sqlite-libs libuuid-devel gdbm-libs perf \ - expat expat-devel mpdecimal python3-pip + readline-devel zlib-devel libzstd-devel libffi-devel bzip2-devel \ + xz-devel sqlite sqlite-devel sqlite-libs libuuid-devel gdbm-libs \ + perf expat expat-devel mpdecimal python3-pip On **Debian**, **Ubuntu**, and other ``apt``-based systems, try to get the @@ -777,7 +777,7 @@ 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 + 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. @@ -812,7 +812,7 @@ some of CPython's modules (for example, ``zlib``). For **Homebrew**, install dependencies using ``brew``:: - $ brew install pkg-config openssl@3 xz gdbm tcl-tk mpdecimal + $ brew install pkg-config openssl@3 xz gdbm tcl-tk mpdecimal zstd .. tab:: Python 3.13+ @@ -853,7 +853,7 @@ some of CPython's modules (for example, ``zlib``). For **MacPorts**, install dependencies using ``port``:: - $ sudo port install pkgconfig openssl xz gdbm tcl tk +quartz mpdecimal + $ sudo port install pkgconfig openssl xz gdbm tk +quartz mpdecimal zstd .. tab:: Python 3.13+ From 3c5b52fdc4a6bd4c08cea0d3b479ad97689e5189 Mon Sep 17 00:00:00 2001 From: Ezio Melotti <ezio.melotti@gmail.com> Date: Mon, 12 May 2025 11:09:46 +0200 Subject: [PATCH 468/538] Remove extra whitespace (#1560) --- 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 3229d54f8..efa3cf31d 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -740,7 +740,7 @@ some of CPython's modules (for example, ``zlib``). $ sudo dnf install \ gcc gcc-c++ gdb lzma glibc-devel libstdc++-devel openssl-devel \ readline-devel zlib-devel libzstd-devel libffi-devel bzip2-devel \ - xz-devel sqlite sqlite-devel sqlite-libs libuuid-devel gdbm-libs \ + xz-devel sqlite sqlite-devel sqlite-libs libuuid-devel gdbm-libs \ perf expat expat-devel mpdecimal python3-pip From 450b56067ae9a499fade8b2eba9ac5e794f85b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= <lukasz@langa.pl> Date: Tue, 13 May 2025 11:37:50 +0200 Subject: [PATCH 469/538] Add Diego Russo to core developers (#1561) --- core-developers/developers.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/core-developers/developers.csv b/core-developers/developers.csv index 567093ba5..aaa8d5d61 100644 --- a/core-developers/developers.csv +++ b/core-developers/developers.csv @@ -1,3 +1,4 @@ +Diego Russo,diegorusso,2025-05-13,, Bénédikt Tran,picnixz,2025-01-10,, Savannah Bailey,savannahostrowski,2024-11-13,, Matt Page,mpage,2024-10-10,, From 3a65d93636d57de0c466dab21ab519bf7fdb2f01 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <greg@krypto.org> Date: Mon, 19 May 2025 16:15:38 -0400 Subject: [PATCH 470/538] use a forever link to docs discord invite (#1563) --- contrib/contrib-plan.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/contrib-plan.rst b/contrib/contrib-plan.rst index 36a171bf1..65e386e2b 100644 --- a/contrib/contrib-plan.rst +++ b/contrib/contrib-plan.rst @@ -43,5 +43,5 @@ To help, you can: .. _Write an issue: https://github.com/python/devguide/issues .. _Make a pull request: https://github.com/python/devguide/pulls -.. _Python Docs Discord: https://discord.gg/NeGgyhUZ +.. _Python Docs Discord: https://discord.gg/qcfPbnM2zH .. _Docs Editorial Board: https://python.github.io/editorial-board/ From 2ba15bba00f33611cf66854f1c2d35ff93aab884 Mon Sep 17 00:00:00 2001 From: Ned Batchelder <ned@nedbatchelder.com> Date: Tue, 27 May 2025 18:38:49 -0400 Subject: [PATCH 471/538] the prerelease label needs to be black (#1564) * the prerelease label needs to be black * better for dark mode --- _static/devguide_overrides.css | 1 + 1 file changed, 1 insertion(+) diff --git a/_static/devguide_overrides.css b/_static/devguide_overrides.css index d47a1e602..5b6d67b09 100644 --- a/_static/devguide_overrides.css +++ b/_static/devguide_overrides.css @@ -55,6 +55,7 @@ } .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); From 24fa99f9894910fb935030e0986b5f39211a176c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka <storchaka@gmail.com> Date: Sun, 1 Jun 2025 03:20:40 +0300 Subject: [PATCH 472/538] Update my experts list (#1565) --- core-developers/experts.rst | 51 ++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 75d2a6b20..60d127a41 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -56,7 +56,7 @@ __future__ __main__ gvanrossum, ncoghlan _thread abc -argparse savannahostrowski* +argparse serhiy-storchaka*, savannahostrowski* array ast benjaminp, pablogsal, isidentical, JelleZijlstra, eclips4 asyncio 1st1, asvetlov, gvanrossum, graingert, kumaraditya303, willingc @@ -85,10 +85,10 @@ concurrent.futures pitrou, brianquinlan, gpshead* configparser ambv* contextlib ncoghlan, 1st1 contextvars -copy avassalotti -copyreg avassalotti +copy avassalotti, serhiy-storchaka* +copyreg avassalotti, serhiy-storchaka* cProfile -csv smontanaro (inactive) +csv smontanaro (inactive), serhiy-storchaka* ctypes theller (inactive), abalkin, amauryfa, meadori curses Yhg1s dataclasses ericvsmith*, carljm @@ -107,16 +107,16 @@ faulthandler vstinner, gpshead fcntl Yhg1s filecmp fileinput -fnmatch +fnmatch serhiy-storchaka* fractions ftplib giampaolo* functools rhettinger* gc pitrou, pablogsal -getopt +getopt serhiy-storchaka* getpath FFY00 getpass gettext -glob +glob serhiy-storchaka* grp hashlib tiran, gpshead*, picnixz heapq rhettinger*, stutzbach^ @@ -132,7 +132,8 @@ inspect 1st1 io benjaminp, stutzbach^ ipaddress pmoody^ itertools rhettinger* -json etrepum (inactive), ezio-melotti, rhettinger +json etrepum (inactive), ezio-melotti, rhettinger, + serhiy-storchaka* keyword libmpdec linecache @@ -152,15 +153,15 @@ nis nntplib numbers operator -optparse mitsuhiko +optparse mitsuhiko, serhiy-storchaka* os -os.path serhiy-storchaka +os.path serhiy-storchaka* ossaudiodev parser pablogsal pathlib barneygale* pdb gaogaotiantian -pickle avassalotti -pickletools avassalotti +pickle avassalotti, serhiy-storchaka* +pickletools avassalotti, serhiy-storchaka* pipes pkgutil platform malemburg @@ -174,11 +175,11 @@ pty Yhg1s* pwd py_compile carljm pyclbr isidentical -pydoc AA-Turner +pydoc AA-Turner, serhiy-storchaka* queue rhettinger* quopri random rhettinger -re ezio-melotti, serhiy-storchaka +re ezio-melotti, serhiy-storchaka* readline Yhg1s reprlib resource Yhg1s @@ -212,14 +213,14 @@ sysconfig FFY00 syslog jafo^* tabnanny tim-one (inactive) tarfile gustaebel -tempfile +tempfile serhiy-storchaka* termios Yhg1s -test ezio-melotti +test ezio-melotti, serhiy-storchaka* textwrap threading pitrou, gpshead time abalkin, pganssle timeit -tkinter gpolo^, serhiy-storchaka +tkinter gpolo^, serhiy-storchaka* token tokenize meadori tomllib hauntsaninja* @@ -232,7 +233,7 @@ turtledemo terryjreedy* types 1st1 typing gvanrossum, JelleZijlstra*, AlexWaygood*, carljm, sobolevn* unicodedata malemburg, ezio-melotti -unittest ezio-melotti, rbtcollins, gpshead +unittest ezio-melotti, rbtcollins, gpshead, serhiy-storchaka* unittest.mock urllib orsenthil uu @@ -268,7 +269,8 @@ Tools ================== =========== Tool Maintainers ================== =========== -Argument Clinic larryhastings, AlexWaygood*, erlend-aasland +Argument Clinic larryhastings, AlexWaygood*, erlend-aasland, + serhiy-storchaka* Deepfreeze gvanrossum, kumaraditya303 PEG Generator gvanrossum, pablogsal, lysnikolaou ================== =========== @@ -311,8 +313,9 @@ Miscellaneous ================== ========================================================== Interest Area Maintainers ================== ========================================================== -algorithms rhettinger* -argument clinic larryhastings, AlexWaygood*, erlend-aasland +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* bsd @@ -340,7 +343,7 @@ initialization FFY00 io benjaminp, stutzbach^, gpshead JIT brandtbucher*, savannahostrowski* locale malemburg -mathematics malemburg, stutzbach^, rhettinger +mathematics malemburg, stutzbach^, rhettinger, serhiy-storchaka memory management tim-one, malemburg, Yhg1s memoryview networking giampaolo, gpshead @@ -348,8 +351,8 @@ object model benjaminp, Yhg1s packaging tarekziade, malemburg, alexis^, merwok, dstufft, pfmoore pattern matching brandtbucher* peg parser gvanrossum, pablogsal, lysnikolaou -performance vstinner, serhiy-storchaka, 1st1, rhettinger, markshannon, brandtbucher, carljm, Fidget-Spinner, - AlexWaygood* +performance vstinner, serhiy-storchaka*, 1st1, rhettinger, markshannon, + brandtbucher, carljm, Fidget-Spinner, AlexWaygood* pip ncoghlan, dstufft, pfmoore, Marcus.Smith^, pradyunsg py3 transition benjaminp release management tarekziade, malemburg, benjaminp, warsaw, From 98f35362468918bea6a26973701fbd96491126f4 Mon Sep 17 00:00:00 2001 From: jwjacobson <116485484+jwjacobson@users.noreply.github.com> Date: Mon, 2 Jun 2025 21:01:27 -0400 Subject: [PATCH 473/538] Add Jeff Jacobson as coordinator of Indonesian translation (#1566) * Add Jeff Jacobson as coordinator of Indonesian translation * Add Jeff Jacobson as coordinator of Indonesian translation 2 * Add Jeff Jacobson as coordinator of Indonesian translation 2 --- documentation/translating.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index 04e8a0a6b..c87056332 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -42,7 +42,8 @@ details. - :github:`GitHub <python/python-docs-hu>`, `mailing list <https://mail.python.org/pipermail/python-hu>`__ * - `Indonesian (id) <https://docs.python.org/id/>`__ - - Oon Arfiandwi (:github-user:`oonid`) + - Oon Arfiandwi (:github-user:`oonid`), + Jeff Jacobson (:github-user:`jwjacobson`) - :github:`GitHub <python/python-docs-id>` * - Italian (it) - Alessandro Cucci (`email <mailto:alessandro.cucci@gmail.com>`__) From c6fa2673eeb27831100448026b3ab12012adec62 Mon Sep 17 00:00:00 2001 From: Irvan Putra <irvan.putra@gmail.com> Date: Wed, 4 Jun 2025 15:52:57 +0700 Subject: [PATCH 474/538] Add Irvan Putra as a co-ordinator of the Indonesian translation (#1567) --- documentation/translating.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/translating.rst b/documentation/translating.rst index c87056332..abbd2c74f 100644 --- a/documentation/translating.rst +++ b/documentation/translating.rst @@ -42,7 +42,7 @@ details. - :github:`GitHub <python/python-docs-hu>`, `mailing list <https://mail.python.org/pipermail/python-hu>`__ * - `Indonesian (id) <https://docs.python.org/id/>`__ - - Oon Arfiandwi (:github-user:`oonid`), + - Irvan Putra (:github-user:`irvan-putra`), Jeff Jacobson (:github-user:`jwjacobson`) - :github:`GitHub <python/python-docs-id>` * - Italian (it) From aaa8d72adaab1698105bde70aecf8c18c240ba96 Mon Sep 17 00:00:00 2001 From: Petr Viktorin <encukou@gmail.com> Date: Fri, 6 Jun 2025 10:34:04 +0200 Subject: [PATCH 475/538] Instructions to run the devcontainer locally (#1568) --- getting-started/setup-building.rst | 40 +++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/getting-started/setup-building.rst b/getting-started/setup-building.rst index efa3cf31d..aa783f24e 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -1186,7 +1186,45 @@ 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. -.. TODO: add docker instructions + +Building the container locally +------------------------------ + +If you want more control over the environment, or to work offline, +you can build the container locally. +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. + +In a clone of the `cpython-devcontainers repo <https://github.com/python/cpython-devcontainers>`_, +build the container and name it ``cpython-dev``: + +.. code-block:: bash + + docker build devcontainer/ --tag cpython-dev + +(Substitute ``podman`` for ``docker`` if you use Podman.) + +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. + +.. code-block:: bash + + docker run -it --rm --volume $PWD:/workspace --workdir /workspace cpython-dev + +.. code-block:: bash + + 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. .. c_codespaces_end From 11ae9dcd9d30b683682dedb6b9714c35cf1528c0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 9 Jun 2025 19:51:46 +0300 Subject: [PATCH 476/538] Exclude ``https://www.gnu.org/software/autoconf/`` in linkcheck (#1572) --- conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conf.py b/conf.py index 769cd19d1..ba7ee6040 100644 --- a/conf.py +++ b/conf.py @@ -87,6 +87,7 @@ linkcheck_ignore = [ # Checks fail due to rate limits r'https://github.com/.*', + r'https://www.gnu.org/software/autoconf/', # The Discourse groups are private unless you are logged in 'https://discuss.python.org/groups/staff', 'https://discuss.python.org/groups/moderators', From 48b8d07f9cd97efc061eb421d43fcb76d819f016 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 9 Jun 2025 19:52:52 +0300 Subject: [PATCH 477/538] Add hugovk to release management (#1571) --- core-developers/experts.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core-developers/experts.rst b/core-developers/experts.rst index 60d127a41..54f7fd373 100644 --- a/core-developers/experts.rst +++ b/core-developers/experts.rst @@ -297,13 +297,13 @@ Emscripten hoodmane, pmp-p, rdb, rth, ryanking13 FreeBSD HP-UX iOS freakboy3742, ned-deily +JVM/Java frank.wierzbicki^ Linux macOS ronaldoussoren, ned-deily, freakboy3742 NetBSD1 OS2/EMX aimacintyre^ Solaris/OpenIndiana jcea, kulikjak Windows tjguk, zooba, pfmoore -JVM/Java frank.wierzbicki^ =================== =========== @@ -316,9 +316,8 @@ Interest Area Maintainers algorithms rhettinger*, serhiy-storchaka argument clinic larryhastings, AlexWaygood*, erlend-aasland, serhiy-storchaka* -ast/compiler benjaminp, 1st1, pablogsal, markshannon, isidentical, brandtbucher, carljm, iritkatriel +AST/compiler benjaminp, 1st1, pablogsal, markshannon, isidentical, brandtbucher, carljm, iritkatriel autoconf/makefiles Yhg1s* -bsd issue tracker ezio-melotti buildbots zware, pablogsal bytecode benjaminp, 1st1, markshannon, brandtbucher, carljm, iritkatriel @@ -350,14 +349,13 @@ networking giampaolo, gpshead object model benjaminp, Yhg1s packaging tarekziade, malemburg, alexis^, merwok, dstufft, pfmoore pattern matching brandtbucher* -peg parser gvanrossum, pablogsal, lysnikolaou +PEG parser gvanrossum, pablogsal, lysnikolaou performance vstinner, serhiy-storchaka*, 1st1, rhettinger, markshannon, brandtbucher, carljm, Fidget-Spinner, AlexWaygood* pip ncoghlan, dstufft, pfmoore, Marcus.Smith^, pradyunsg -py3 transition benjaminp release management tarekziade, malemburg, benjaminp, warsaw, gvanrossum, anthonybaxter^, merwok, ned-deily, - birkenfeld, JulienPalard + birkenfeld, JulienPalard, hugovk runtime lifecycle ericsnowcurrently, kumaraditya303, zooba str.format ericvsmith* subinterpreters ericsnowcurrently, kumaraditya303 @@ -366,7 +364,7 @@ testing ezio-melotti test coverage threads gpshead time and dates malemburg, abalkin, pganssle -unicode malemburg, ezio-melotti, benjaminp +Unicode malemburg, ezio-melotti, benjaminp version control merwok, ezio-melotti ================== ========================================================== 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 478/538] 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 <carolcode@willingconsulting.com> --------- Co-authored-by: Carol Willing <carolcode@willingconsulting.com> --- 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 ba7ee6040..bedd99c42 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 3f2512bcf..eaa9e1a96 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 000000000..3d64858ad --- /dev/null +++ b/documentation/translations/coordinating.rst @@ -0,0 +1,123 @@ +============ +Coordinating +============ + +Starting a new translation +========================== + +First subscribe to the `translation mailing list <translation_ml_>`_, +and introduce yourself and the translation you're starting. Translations +fall under the aegis of the `PSF Translation Workgroup <translation_wg_>`_ + +Then you can bootstrap your new translation by using `cookiecutter +<https://github.com/JulienPalard/python-docs-cookiecutter>`__ or +`bootstrapper <https://github.com/python-docs-translations/python-docs-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 <translating>` to reflect your work and progress, either via a + PR or by asking on the `translation mailing list <translation_ml_>`_. +- When ``bugs``, ``tutorial``, and ``library/functions`` are 100% + completed, ask on the `translation mailing list <translation_ml_>`_ 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 <translation_ml_>`_. +- 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 <translation_ml_>`_. + 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 <translation_ml_>`_, 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 <translation_ml_>`_ 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 <translation_ml_>`_, or better, make a PR on the `devguide +<https://github.com/python/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 000000000..67ab049f9 --- /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 abbd2c74f..47f04cef8 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 <translation_ml_>`_, -and introduce yourself and the translation you're starting. Translations -fall under the aegis of the `PSF Translation Workgroup <translation_wg_>`_ - -Then you can bootstrap your new translation by using `cookiecutter -<https://github.com/JulienPalard/python-docs-cookiecutter>`__ or -`bootstrapper <https://github.com/python-docs-translations/python-docs-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 <translation_ml_>`_. -- When ``bugs``, ``tutorial``, and ``library/functions`` are 100% - completed, ask on the `translation mailing list <translation_ml_>`_ 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 <translation_ml_>`_. -- 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 <translation_ml_>`_. - - -The entry for my translation is missing/not up to date on this page -------------------------------------------------------------------- - -Ask on the `translation mailing list <translation_ml_>`_, or better, make a PR on the `devguide -<https://github.com/python/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 <translation_ml_>`_, 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 <translation_ml_>`_ 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 <encukou@gmail.com> Date: Sun, 15 Jun 2025 02:35:40 +0200 Subject: [PATCH 479/538] 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 aa783f24e..62da6b3fb 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 480/538] 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 3d64858ad..7568116c8 100644 --- a/documentation/translations/coordinating.rst +++ b/documentation/translations/coordinating.rst @@ -12,11 +12,13 @@ fall under the aegis of the `PSF Translation Workgroup <translation_wg_>`_ Then you can bootstrap your new translation by using `cookiecutter <https://github.com/JulienPalard/python-docs-cookiecutter>`__ or `bootstrapper <https://github.com/python-docs-translations/python-docs-bootstrapper>`__. +You can also start your translation using `Transifex <https://explore.transifex.com/python-doc/python-newest/>`_ +following this `guide <https://python-docs-transifex-automation.readthedocs.io/commands.html>`_. 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 481/538] 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 47f04cef8..d2cbe6621 100644 --- a/documentation/translations/translating.rst +++ b/documentation/translations/translating.rst @@ -82,7 +82,7 @@ details. `article <https://rgth.co/blog/python-ptbr-cenario-atual/>`__ * - Romanian (ro) - Octavian Mustafa (:github-user:`octaG-M`, `email <mailto:octawian@yahoo.com>`__) - - :github:`GitHub <octaG-M/python-docs-ro>` + - :github:`GitHub <python/python-docs-ro>` * - Russian (ru) - Daniil Kolesnikov (:github-user:`MLGRussianXP`, `email <mailto:mlgrussianxp@gmail.com>`__) - :github:`GitHub <MLGRussianXP/python-docs-ru>`, From f9cb7e5b2c11b25c931c822b003d66b7fa80a60d Mon Sep 17 00:00:00 2001 From: Micha Albert <micha@2231puppy.tech> Date: Sun, 15 Jun 2025 21:16:31 -0400 Subject: [PATCH 482/538] 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 184cf54bf..973b36b12 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 <pullrequest>`), use: From 2d657ff814d31b49d56633fbe42d75dd26b665d8 Mon Sep 17 00:00:00 2001 From: Peter Bierma <zintensitydev@gmail.com> Date: Mon, 16 Jun 2025 14:50:30 -0400 Subject: [PATCH 483/538] 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 aaa8d5d61..73e93ce46 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." <tomas.roun8@gmail.com> Date: Mon, 16 Jun 2025 21:41:54 +0200 Subject: [PATCH 484/538] 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 73e93ce46..b0ec46447 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 <encukou@gmail.com> Date: Wed, 18 Jun 2025 13:55:37 +0200 Subject: [PATCH 485/538] 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 b0ec46447..79f2e86f4 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." <tomas.roun8@gmail.com> Date: Thu, 19 Jun 2025 21:49:40 +0200 Subject: [PATCH 486/538] 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 54f7fd373..599d4d50e 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 487/538] 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 <carolcode@willingconsulting.com> * 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 <carolcode@willingconsulting.com> 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 f9b54bc56..b93d36504 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 599d4d50e..76ea564c2 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 <translating>`. +Translations are within the charter of +`Editorial Board <https://python.github.io/editorial-board/>`_. +For a list of translations and their coordinators, see +:ref:`this table of translations <translation-coordinators>`. diff --git a/documentation/translations/coordinating.rst b/documentation/translations/coordinating.rst index 7568116c8..4e78b9247 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 +<https://github.com/python/docsbuild-scripts/>`__ and hosted on +docs.python.org. Translations +are overseen by the `Editorial Board <EB_>`_ + Starting a new translation ========================== First subscribe to the `translation mailing list <translation_ml_>`_, -and introduce yourself and the translation you're starting. Translations -fall under the aegis of the `PSF Translation Workgroup <translation_wg_>`_ +and introduce yourself and the translation you're starting. -Then you can bootstrap your new translation by using `cookiecutter -<https://github.com/JulienPalard/python-docs-cookiecutter>`__ or +Then you can bootstrap your new translation by using the `cookiecutter +<https://github.com/python-docs-translations/python-docs-cookiecutter>`__ or `bootstrapper <https://github.com/python-docs-translations/python-docs-bootstrapper>`__. You can also start your translation using `Transifex <https://explore.transifex.com/python-doc/python-newest/>`_ following this `guide <https://python-docs-transifex-automation.readthedocs.io/commands.html>`_. @@ -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 <https://discord.gg/h3qDwgyzga>`_, `translation +mailing list <translation_ml_>`_, and the +`translations category <https://discuss.python.org/c/documentation/translations/>`_ +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 <https://github.com/python-docs-translations/transifex-automations/issues>`_. + + 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 <translation_ml_>`_. - 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 <translation_ml_>`_, or better, make a PR +on the `devguide <https://github.com/python/devguide/>`__. + + +Is there a Weblate instance we can translate on? +------------------------------------------------ + +There is currently no Weblate instance for Python translations. +See this `Discourse thread <https://discuss.python.org/t/docs-translation-platform/29940>`_ +for updates. -Ask on the `translation mailing list <translation_ml_>`_, or better, make a PR on the `devguide -<https://github.com/python/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 67ab049f9..2f5cfe0f4 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 d2cbe6621..7d1e2f251 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 -<https://github.com/python/docsbuild-scripts/>`__ and hosted on -docs.python.org. There are several documentation translations already -in production; others are works in progress. See `the dashboard -<https://python-docs-translations.github.io/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 +<https://python-docs-translations.github.io/dashboard/>`__. + +.. _translation-coordinators: .. list-table:: :header-rows: 1 * - Language - - Contact + - Coordination team - Links * - Arabic (ar) - Abdur-Rahmaan Janhangeer (:github-user:`Abdur-rahmaanJ`) - :github:`GitHub <Abdur-rahmaanJ/python-docs-ar>` - * - Bengali (bn_IN) + * - `Bengali (bn-IN) <https://docs.python.org/bn-in/>`__ - Kushal Das (:github-user:`kushaldas`) - :github:`GitHub <python/python-docs-bn-in>` * - `French (fr) <https://docs.python.org/fr/>`__ - Julien Palard (:github-user:`JulienPalard`) - - :github:`GitHub <python/python-docs-fr>` - * - Greek (gr) - - Lysandros Nikolaou (:github-user:`lysnikolaou`), - Fanis Petkos (:github-user:`thepetk`), - Panagiotis Skias (:github-user:`skpanagiotis`) - - :github:`GitHub <pygreece/python-docs-gr>` - * - Hindi (hi_IN) + - `AFPy/python-docs-fr <https://git.afpy.org/AFPy/python-docs-fr/>`_, + :github:`mirror <python/python-docs-fr>` + * - `Greek (el) <https://docs.python.org/el/>`__ + - | Lysandros Nikolaou (:github-user:`lysnikolaou`), + | Fanis Petkos (:github-user:`thepetk`), + | Panagiotis Skias (:github-user:`skpanagiotis`) + - :github:`GitHub <python/python-docs-el>` + * - Hindi (hi-IN) - Sanyam Khurana (:github-user:`CuriousLearner`) - :github:`GitHub <CuriousLearner/python-docs-hi-in>` * - Hungarian (hu) @@ -42,16 +45,16 @@ details. - :github:`GitHub <python/python-docs-hu>`, `mailing list <https://mail.python.org/pipermail/python-hu>`__ * - `Indonesian (id) <https://docs.python.org/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 <python/python-docs-id>` - * - Italian (it) + * - `Italian (it) <https://docs.python.org/it/>`__ - Alessandro Cucci (`email <mailto:alessandro.cucci@gmail.com>`__) - :github:`GitHub <python/python-docs-it>`, - `original mail <https://mail.python.org/pipermail/doc-sig/2019-April/004114.html>`__ + `original announcement <https://mail.python.org/pipermail/doc-sig/2019-April/004114.html>`__ * - `Japanese (ja) <https://docs.python.org/ja/>`__ - - Kinebuchi Tomohiko (:github-user:`cocoatomo`), - Atsuo Ishimoto (:github-user:`atsuoishimoto`) + - | Kinebuchi Tomohiko (:github-user:`cocoatomo`), + | Atsuo Ishimoto (:github-user:`atsuoishimoto`) - :github:`GitHub <python/python-docs-ja>` * - `Korean (ko) <https://docs.python.org/ko/>`__ - 오동권 (:github-user:`flowdas`) @@ -61,43 +64,44 @@ details. - :github:`GitHub <sanketgarade/python-doc-mr>` * - Lithuanian (lt) - Albertas Gimbutas (:github-user:`albertas`, `email <mailto:albertasgim@gmail.com>`__) - - `Original mail <https://mail.python.org/pipermail/doc-sig/2019-July/004138.html>`__ + - `original announcement <https://mail.python.org/pipermail/doc-sig/2019-July/004138.html>`__ * - Persian (fa) - Alireza Shabani (:github-user:`revisto`) - :github:`GitHub <revisto/python-docs-fa>` * - `Polish (pl) <https://docs.python.org/pl/>`__ - - Maciej Olko (:github-user:`m-aciek`) + - | Maciej Olko (:github-user:`m-aciek`), + | Stan Ulbrych (:github-user:`StanFromIreland`) - :github:`GitHub <python/python-docs-pl>`, `Transifex <tx_>`_, - `original mail <https://mail.python.org/pipermail/doc-sig/2019-April/004106.html>`__ + `original announcement <https://mail.python.org/pipermail/doc-sig/2019-April/004106.html>`__ * - Portuguese (pt) - Gustavo Toffo - * - `Brazilian Portuguese (pt-br) <https://docs.python.org/pt-br/>`__ - - Rafael Fontenelle (:github-user:`rffontenelle`), - Marco Rougeth (:github-user:`rougeth`) + - | Rafael Fontenelle (:github-user:`rffontenelle`), + | Marco Rougeth (:github-user:`rougeth`) - :github:`GitHub <python/python-docs-pt-br>`, - `wiki <https://python.org.br/traducao/>`__, + `guide <https://python.org.br/traducao/>`__, `Telegram <https://t.me/pybr_i18n>`__, `article <https://rgth.co/blog/python-ptbr-cenario-atual/>`__ - * - Romanian (ro) + * - `Romanian (ro) <https://docs.python.org/ro/>`__ - Octavian Mustafa (:github-user:`octaG-M`, `email <mailto:octawian@yahoo.com>`__) - :github:`GitHub <python/python-docs-ro>` * - Russian (ru) - Daniil Kolesnikov (:github-user:`MLGRussianXP`, `email <mailto:mlgrussianxp@gmail.com>`__) - :github:`GitHub <MLGRussianXP/python-docs-ru>`, - `mail <https://mail.python.org/pipermail/doc-sig/2019-May/004131.html>`__ + `original announcement <https://mail.python.org/pipermail/doc-sig/2019-May/004131.html>`__ * - `Simplified Chinese (zh-cn) <https://docs.python.org/zh-cn/>`__ - - Shengjing Zhu (:github-user:`zhsj`), - Du, Meng (:github-user:`dumeng`) + - | Shengjing Zhu (:github-user:`zhsj`), + | Du, Meng (:github-user:`dumeng`) - :github:`GitHub <python/python-docs-zh-cn>`, `Transifex <tx_>`_ * - `Spanish (es) <https://docs.python.org/es/>`__ - Raúl Cumplido - :github:`GitHub <python/python-docs-es>` * - `Traditional Chinese (zh-tw) <https://docs.python.org/zh-tw/>`__ - - 王威翔 Matt Wang (:github-user:`mattwang44`), - Josix Wang + - | 王威翔 Matt Wang (:github-user:`mattwang44`), + | Josix Wang - :github:`GitHub <python/python-docs-zh-tw>` * - `Turkish (tr) <https://docs.python.org/tr/>`__ - Ege Akman (:github-user:`egeakman`) @@ -108,33 +112,175 @@ details. - :github:`GitHub <python/python-docs-uk>`, `Transifex <tx_>`_ -.. _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 <https://discord.gg/h3qDwgyzga>`_, `translation -mailing list <translation_ml_>`_, and there's a `Libera.Chat IRC -<https://libera.chat/>`_ channel, ``#python-doc``. +mailing list <translation_ml_>`_, 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 <target>``` 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 <target>`_``) 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 <https://docs.python.org/3/tutorial/controlflow.html#keyword-arguments>`_ +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 <tx_>`_, + 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 <tx_>`_ 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 <https://help.transifex.com/en/articles/6248698-getting-started-as-a-translator>`__: + This covers signing up for an account and joining a translation team. +- `Translating with the Web Editor <https://help.transifex.com/en/articles/6318216-translating-with-the-web-editor>`__: + This covers getting to the editor, searching and filtering strings, and translating strings. +- `Other Tools in the Editor <https://help.transifex.com/en/articles/6318944-other-tools-in-the-editor>`__: + This covers the history, glossary, comments, keyboard shortcuts, and more. +- `Starting with the basics <https://help.transifex.com/en/collections/3441044-starting-with-the-basics>`__: + A group of documents with basic information. + +For further information about Transifex see our `documentation <https://python-docs-transifex-automation.readthedocs.io/>`_. + + +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 <https://github.com/python/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 <cornelius.roemer@gmail.com> Date: Tue, 24 Jun 2025 09:21:06 +0200 Subject: [PATCH 488/538] 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 <ezio.melotti@gmail.com> --- conf.py | 15 ++++++++++++++- versions.rst | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index bedd99c42..9bfe2305c 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 8cfd259f8..0a52829c2 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 <https://www.python.org/downloads/>`_. From 8b085665d9694d7ce4cf8ed0f231888fbf60dff8 Mon Sep 17 00:00:00 2001 From: Brett Cannon <brett@python.org> Date: Thu, 26 Jun 2025 04:01:46 -0700 Subject: [PATCH 489/538] Add instructions on how to use the dev container image from GHCR (#1581) Co-authored-by: Petr Viktorin <encukou@gmail.com> 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 62da6b3fb..910808453 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 <using-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 <https://www.docker.com/>`__ or `Podman <https://podman.io/>`__ +installed. -In a clone of the `cpython-devcontainers repo <https://github.com/python/cpython-devcontainers>`_, +.. _devcontainer-image: + +Using the pre-built container image +----------------------------------- + +`Dev container images <https://github.com/python/cpython-devcontainers/pkgs/container/devcontainer>`__ +are available from the +`GitHub Container Registry (GHCR) account for the Python org <https://github.com/orgs/python/packages>`__. + +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 <https://github.com/python/cpython-devcontainers>`_, 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 <zintensitydev@gmail.com> Date: Tue, 1 Jul 2025 11:26:58 -0400 Subject: [PATCH 490/538] 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 76ea564c2..6f40abe1d 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 <storchaka@gmail.com> Date: Thu, 3 Jul 2025 21:14:38 +0300 Subject: [PATCH 491/538] 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 6f40abe1d..4237d8241 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 <nas-github@arctrix.com> Date: Thu, 3 Jul 2025 16:23:05 -0700 Subject: [PATCH 492/538] 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 4237d8241..0e54a339f 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 <jelle.zijlstra@gmail.com> Date: Sat, 5 Jul 2025 15:30:50 -0700 Subject: [PATCH 493/538] 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 0e54a339f..5731b0c92 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 494/538] 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 9bfe2305c..5050f5c45 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 59cf7c1af..5b639cd5a 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 473cd3c6c..000000000 --- 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 7f2a103cd..73a9431c0 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 a89d08aff..d51a8a4e8 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 0c893ae08..70557589d 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 c9e0281b6..8fc6f94db 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 a3de32956..973385a15 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 000000000..d6b480d25 --- /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 b93d36504..0b5a3edc6 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 2e6db104f..f8dafe05e 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 70b7e25af..5735f72a1 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 b1e51cea2..2bcf24ae1 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 <https://github.com/python/devguide/blob/main/core-developers/developers.csv>`_; -* The user is removed from the `Experts Index <https://github.com/python/devguide/blob/main/core-developers/experts.rst>`_. +* The user is marked as deceased in `core-team.csv <https://github.com/python/devguide/blob/main/core-team/core-team.csv>`_; +* The user is removed from the `experts index <https://github.com/python/devguide/blob/main/core-team/experts.rst>`_. 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 665ef0700..77639ebf1 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 b70461dc0..4f62668ac 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" <mattwang44@gmail.com> Date: Tue, 8 Jul 2025 01:05:29 +0800 Subject: [PATCH 495/538] 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 5731b0c92..5791ff408 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 <drsuaimqjgar@gmail.com> Date: Wed, 9 Jul 2025 21:59:58 +0900 Subject: [PATCH 496/538] 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 5735f72a1..1067696bb 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 d6be88824..7131cfdf8 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 <https://podman.io/docs/installation>`_ - 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 <https://podman.io/docs/installation>`_ + 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 <clinic>`. diff --git a/development-tools/warnings.rst b/development-tools/warnings.rst index b6448f397..b30d81131 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 4e78b9247..d2878385e 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 <drsuaimqjgar@gmail.com> Date: Fri, 11 Jul 2025 02:34:50 +0900 Subject: [PATCH 497/538] Fix markup error in hyperlink target (#1604) Co-authored-by: Petr Viktorin <encukou@gmail.com> --- 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 910808453..bd026ea71 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 <drsuaimqjgar@gmail.com> Date: Sat, 19 Jul 2025 19:46:09 +0900 Subject: [PATCH 498/538] 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 642f40dce..2f4677430 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 <dominik.b.czarnota@gmail.com> Date: Sat, 19 Jul 2025 13:54:14 +0200 Subject: [PATCH 499/538] 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 <encukou@gmail.com> --- development-tools/clang.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/development-tools/clang.rst b/development-tools/clang.rst index f06834731..b353d82f0 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 <nachocab@gmail.com> Date: Sat, 19 Jul 2025 16:59:51 +0200 Subject: [PATCH 500/538] 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 9817feb15..3d485ae2d 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 973b36b12..7515992ec 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 <checkout>`. 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 <checkout>`. - 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 <pshrivastava403@outlook.com> Date: Sun, 20 Jul 2025 03:02:40 -0400 Subject: [PATCH 501/538] 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 8fd6f345e..7c2de5d6b 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -158,7 +158,7 @@ to trigger specific bot behaviors. * :gh-label:`skip news <skip%20news>`: 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 <buildbots>` 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 <roberthoodchatham@gmail.com> Date: Wed, 23 Jul 2025 11:11:13 +0200 Subject: [PATCH 502/538] 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 97856f713..c25de5012 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 7c2de5d6b..3d2679f7f 100644 --- a/triage/labels.rst +++ b/triage/labels.rst @@ -158,9 +158,13 @@ to trigger specific bot behaviors. * :gh-label:`skip news <skip%20news>`: 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 <buildbots>` 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 <buildbots>` 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 503/538] 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 c25de5012..e03849935 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 <marcorichetta@gmail.com> Date: Thu, 24 Jul 2025 13:27:11 +0200 Subject: [PATCH 504/538] 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 7d1e2f251..0c2202670 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 <aisk@users.noreply.github.com> Date: Fri, 25 Jul 2025 22:55:54 +0900 Subject: [PATCH 505/538] 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 4f62668ac..e19bb8826 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 506/538] Prefer 'core team' in `documentation/` and `getting-started/` (#1616) Co-authored-by: Mariatta <Mariatta@users.noreply.github.com> --- 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 d2878385e..4240382b9 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 <translation_ml_>`_. -- 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 50b7583e7..fc289fd44 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 f95ad6555..fe810e90f 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 <setup>`, git commit -m '<message>' git push origin <branch-name> - * 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 <branch-name> # 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 <accepting-and-merging-a-pr>` 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" <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 507/538] Document the ``type-refactor`` label (#1588) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Peter Bierma <zintensitydev@gmail.com> --- triage/labels.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/triage/labels.rst b/triage/labels.rst index 3d2679f7f..34c7dc26c 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 508/538] 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 e9360d201..9b088b350 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 -<https://github.com/python/cpython>`_ core developers. +<https://github.com/python/cpython>`_ 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 <https://planetpython.org/>`__. diff --git a/developer-workflow/development-cycle.rst b/developer-workflow/development-cycle.rst index d807d74ec..c8b2d5ebf 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 <indevbranch>` 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 <https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles>`_. -Common reasons for this role are: maintenance of Core Developer -Workflow tooling, Release Managers for all :ref:`in-development <indevbranch>`, +Common reasons for this role are: maintenance of core +workflow tooling, Release Managers for all :ref:`in-development <indevbranch>`, :ref:`maintenance <maintbranch>`, and :ref:`security mode <secbranch>` -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 f469f68d1..9d9019dbf 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 60112d6d3..b683e55e9 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 <pullrequest>`. If possible, also submit a :ref:`contributor agreement <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 509/538] 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 fde4a6c27..e2f0c5617 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 73a9431c0..aa16f10bd 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 d51a8a4e8..2ca21344b 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 70557589d..932216f7c 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 8fc6f94db..38ba31023 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 973385a15..d6902bd78 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 d6b480d25..ecfe856a4 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 d83d42321..41cf67254 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 <triage-team>` + the core team and members of the :ref:`Python Triage Team <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 <triage-team>` +members of the core team and :ref:`Python Triage Team <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 1067696bb..eb0f56e09 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 <coredev-template>` below) in the `Committers category`_ on the `Python Discourse`_. diff --git a/core-team/memorialization.rst b/core-team/memorialization.rst index 2bcf24ae1..7ab0fab02 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 b19c3062b..d5a87e22c 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 <experts>`. -* 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 5cd5ed7bd..3b2137d6b 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 <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 <communication-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 <communication-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 <emma@emmatyping.dev> Date: Sun, 3 Aug 2025 10:39:35 -0700 Subject: [PATCH 510/538] 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 79f2e86f4..ab87c50fa 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 <skirpichev@gmail.com> Date: Thu, 7 Aug 2025 18:07:43 +0300 Subject: [PATCH 511/538] 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 bd026ea71..4bcf3f116 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 <https://www.bytereef.org/mpdecimal/doc/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 <emma@emmatyping.dev> Date: Fri, 8 Aug 2025 00:22:22 -0700 Subject: [PATCH 512/538] 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 5791ff408..74ce892f7 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 <brett@python.org> Date: Wed, 13 Aug 2025 10:45:47 -0700 Subject: [PATCH 513/538] 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 4bcf3f116..5da12d4ef 100644 --- a/getting-started/setup-building.rst +++ b/getting-started/setup-building.rst @@ -386,14 +386,14 @@ compiler just like building for :ref:`Unix <unix-compiling>` 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 <using-codespaces>`. You can +All of this is provided in the :ref:`devcontainer <using-a-container>`. 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 <buildbots>`. @@ -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 <https://github.com/python/cpython-devcontainers/pkgs/container/devcontainer>`__ 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 <https://github.com/python/cpython-devcontainers>`_, +`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 <brett@python.org> Date: Wed, 13 Aug 2025 15:55:38 -0700 Subject: [PATCH 514/538] 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 5da12d4ef..0b9691c2a 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 515/538] 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 0b9691c2a..fde4498b4 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 <encukou@gmail.com> Date: Fri, 15 Aug 2025 14:21:14 +0200 Subject: [PATCH 516/538] 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 eb0f56e09..d7996cd42 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 <https://github.com/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 <https://discuss.python.org/c/committers/5>`_. 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 517/538] 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 0c2202670..be98ffeef 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 <https://mail.python.org/pipermail/python-hu>`__ * - `Indonesian (id) <https://docs.python.org/id/>`__ - | Irvan Putra (:github-user:`irvan-putra`), - | Jeff Jacobson (:github-user:`jwjacobson`) + | Jeff Jacobson (:github-user:`jwjacobson`), + | Lutfi Zuchri (:github-user:`lutfizuchri`) - :github:`GitHub <python/python-docs-id>` * - `Italian (it) <https://docs.python.org/it/>`__ - Alessandro Cucci (`email <mailto:alessandro.cucci@gmail.com>`__) 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 518/538] 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 49bd15b1d..68350c401 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 <https://docs.python.org/3/c-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 519/538] =?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 be98ffeef..052c306e5 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 <CuriousLearner/python-docs-hi-in>` * - Hungarian (hu) - - Tamás Bajusz (:github-user:`gbtami`) - - :github:`GitHub <python/python-docs-hu>`, - `mailing list <https://mail.python.org/pipermail/python-hu>`__ + - + - :github:`GitHub <python/python-docs-hu>` * - `Indonesian (id) <https://docs.python.org/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 520/538] 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 fde4498b4..f6a6f6a94 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 <skirpichev@gmail.com> Date: Mon, 18 Aug 2025 04:25:21 +0300 Subject: [PATCH 521/538] 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 <aisk1988@gmail.com> --- development-tools/clinic.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/development-tools/clinic.rst b/development-tools/clinic.rst index 2f4677430..6446d1a46 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 * <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 522/538] 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 0b5a3edc6..e519c7dab 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 4240382b9..aaed4b831 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 -<https://github.com/python/docsbuild-scripts/>`__ and hosted on -docs.python.org. Translations -are overseen by the `Editorial Board <EB_>`_ +found on this page and in :PEP:`545`. Translations are overseen by the +`Editorial Board <EB_>`_. + +.. _translation-help: + +Communication/help channels +=========================== + +Discussions about translations occur on the Python Docs Discord +`#translations channel <https://discord.gg/h3qDwgyzga>`_, `translation +mailing list <translation_ml_>`_, and the +`translations category <trans_disc_>`_ of the Python Discourse. + +For administrative issues, ping ``@python/editorial-board``. + Starting a new translation ========================== -First subscribe to the `translation mailing list <translation_ml_>`_, -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 <translation-help>`. + + +Announcement +------------ + +Post an announcement introducing yourself and the translation you're +starting on `Discourse <trans_disc>`_. 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 <translation-coordinators>` 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 <https://datatracker.ietf.org/doc/html/rfc5646.html>`_. +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 <https://github.com/python/cpython/tree/main/Doc>`_. +A correctly set up repository looks like this: +`python-docs-pl <https://github.com/python/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 <https://github.com/python-docs-translations/python-docs-cookiecutter>`__ or `bootstrapper <https://github.com/python-docs-translations/python-docs-bootstrapper>`__. -You can also start your translation using `Transifex <https://explore.transifex.com/python-doc/python-newest/>`_ -following this `guide <https://python-docs-transifex-automation.readthedocs.io/commands.html>`_. +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 <translating>` to reflect your work and progress, either via a - PR or by asking on the `translation mailing list <translation_ml_>`_. -- When ``bugs``, ``tutorial``, and ``library/functions`` are 100% - completed, ask on the `translation mailing list <translation_ml_>`_ for - your language to be added in the language switcher on docs.python.org. +Translation platform +~~~~~~~~~~~~~~~~~~~~ +You can also start your translation using +`Transifex <https://explore.transifex.com/python-doc/python-newest/>`_. +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 <https://python-docs-transifex-automation.readthedocs.io/workflows.html>`__. +An in-depth guide for manually doing this can also be found +in the same documentation's +`commands page <https://python-docs-transifex-automation.readthedocs.io/commands.html>`__. -Discussions about translations occur on the Python Docs Discord -`#translations channel <https://discord.gg/h3qDwgyzga>`_, `translation -mailing list <translation_ml_>`_, and the -`translations category <https://discuss.python.org/c/documentation/translations/>`_ -of the Python Discourse. +To be added as coordinators on Transifex for your language, open an issue +in the `tracker <https://github.com/python-docs-translations/transifex-automations/issues>`__. + + +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 <https://github.com/python/docsbuild-scripts/commit/e4a8aff9772738a63d0945042777d18c3d926930>`__ +if your translation was previously built but not in the switcher, or like +`this commit <https://github.com/python/docsbuild-scripts/commit/a601ce67c6c2f3be7fde3376d3e5d3851f19950b>`__ +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 <https://datatracker.ietf.org/doc/html/rfc5646.html>`_. + 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 <https://github.com/python-docs-translations/transifex-automations/issues>`_. +Some messages that appear in the docs must be translated in the +`Sphinx project <https://www.sphinx-doc.org/en/master/internals/contributing.html#translations>`__ +(`sphinx-doc on Transifex <https://app.transifex.com/sphinx-doc/>`__) or in +the `python-docs-theme <https://github.com/python/python-docs-theme>`_ +(currently this is not possible; see this +`issue <https://github.com/python/python-docs-theme/issues/194>`__). +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 <https://python-docs-transifex-automation.readthedocs.io/workflows.html#test-build-workflow>`_ +for sample workflows with usage guides. + +The `dashboard <https://python-docs-translations.github.io/dashboard/metadata.html>`_ +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 <translation_ml_>`_. - 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 <translation_ml_>`_. - 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 <translation_ml_>`_. + 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 <translation_ml_>`_, 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 <translation_ml_>`_ 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 <translation_ml_>`_, or better, make a PR -on the `devguide <https://github.com/python/devguide/>`__. +Make a PR on the `devguide <https://github.com/python/devguide/>`__ to update it. + + +How are translations built? +--------------------------- + +Translations are built by `docsbuild-scripts <https://github.com/python/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 2f5cfe0f4..a6d4dc4e7 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 052c306e5..ba0489020 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 <coordinating>` to get started. For more details about translations and their progress, see `the dashboard <https://python-docs-translations.github.io/dashboard/>`__. @@ -126,12 +126,13 @@ General discussions about translations occur on the Python Docs Discord mailing list <translation_ml_>`_, 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 <target>``` is provided, it generally +If alternate text (``:role:`text <target>```) 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 <https://github.com/python/devguide>`_ adding yourself, and ping -``@python/editorial-board``. +`devguide <https://github.com/python/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 000000000..e3e131861 --- /dev/null +++ b/documentation/translations/translator-workload.svg @@ -0,0 +1,191 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="460.8pt" + height="345.6pt" + viewBox="0 0 460.8 345.6" + version="1.1" + id="svg18" + sodipodi:docname="translator-workload.svg" + inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <sodipodi:namedview + id="namedview18" + pagecolor="#ffffff" + bordercolor="#000000" + borderopacity="0.25" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + inkscape:document-units="pt" + inkscape:zoom="1.0864401" + inkscape:cx="282.57426" + inkscape:cy="148.19041" + inkscape:window-width="1712" + inkscape:window-height="894" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg18" /> + <metadata + id="metadata1"> + <rdf:RDF> + <cc:Work> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:date>2025-06-29T10:46:39.952440</dc:date> + <dc:format>image/svg+xml</dc:format> + <dc:creator> + <cc:Agent> + <dc:title>Matplotlib v3.10.3, https://matplotlib.org/</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs1"> + <style + type="text/css" + id="style1">*{stroke-linejoin: round; stroke-linecap: butt}</style> + </defs> + <g + id="figure_1"> + <g + id="patch_1"> + <path + d="M 0 345.6 L 1 345.631436 L 2 345.668377 L 3 345.766123 L 4 345.798645 L 5 345.87227 L 6 345.910835 L 7 345.946248 L 8 346.003888 L 9 346.074274 L 10 346.126239 L 11 346.185328 L 12 346.273649 L 13 346.319794 L 14 346.362205 L 15 346.392697 L 16 346.418742 L 17 346.439942 L 18 346.494243 L 19 346.522181 L 20 346.551905 L 21 346.5773 L 22 346.5885 L 23 346.598624 L 24 346.59842 L 25 346.58891 L 26 346.577256 L 27 346.546227 L 28 346.535059 L 29 346.504942 L 30 346.445165 L 31 346.407973 L 32 346.368877 L 33 346.326437 L 34 346.293672 L 35 346.226246 L 36 346.18712 L 37 346.144445 L 38 346.073865 L 39 346.037474 L 40 345.979071 L 41 345.868118 L 42 345.79746 L 43 345.68452 L 44 345.638747 L 45 345.577464 L 46 345.528965 L 47 345.448142 L 48 345.329623 L 49 345.259412 L 50 345.17615 L 51 345.143008 L 52 345.091771 L 53 345.023372 L 54 344.957157 L 55 344.88024 L 56 344.852924 L 57 344.826447 L 58 344.803796 L 59 344.784265 L 60 344.757871 L 61 344.7081 L 62 344.673027 L 63 344.637161 L 64 344.621794 L 65 344.606025 L 66 344.602612 L 67 344.600195 L 68 344.600681 L 69 344.60261 L 70 344.615867 L 71 344.624258 L 72 344.645794 L 73 344.668827 L 74 344.68606 L 75 344.704523 L 76 344.724975 L 77 344.741575 L 78 344.804354 L 79 344.879619 L 80 344.912258 L 81 344.979822 L 82 345.033869 L 83 345.067573 L 84 345.157699 L 85 345.186234 L 86 345.21772 L 87 345.248731 L 88 345.303539 L 89 345.368126 L 90 345.406322 L 91 345.502256 L 92 345.551514 L 93 345.595583 L 94 345.635707 L 95 345.744074 L 96 345.785702 L 97 345.847844 L 98 345.917806 L 99 346.02231 L 100 346.059298 L 101 346.105175 L 102 346.17367 L 103 346.222416 L 104 346.300013 L 105 346.330554 L 106 346.400068 L 107 346.424041 L 108 346.452663 L 109 346.494456 L 110 346.516032 L 111 346.52998 L 112 346.556702 L 113 346.566012 L 114 346.578459 L 115 346.589514 L 116 346.595178 L 117 346.599942 L 118 346.594394 L 119 346.581106 L 120 346.573589 L 121 346.548804 L 122 346.525235 L 123 346.489055 L 124 346.463093 L 125 346.440771 L 126 346.372011 L 127 346.297476 L 128 346.203497 L 129 346.152445 L 130 346.098511 L 131 346.06326 L 132 345.957172 L 133 345.904908 L 134 345.868001 L 135 345.83697 L 136 345.775815 L 137 345.708395 L 138 345.659489 L 139 345.594297 L 140 345.556109 L 141 345.514113 L 142 345.472096 L 143 345.41258 L 144 345.29942 L 145 345.247169 L 146 345.207751 L 147 345.16065 L 148 345.10387 L 149 345.071207 L 150 345.035029 L 151 345.002939 L 152 344.968659 L 153 344.910281 L 154 344.865096 L 155 344.835472 L 156 344.785086 L 157 344.759889 L 158 344.738838 L 159 344.70387 L 160 344.67958 L 161 344.665513 L 162 344.646571 L 163 344.63091 L 164 344.618358 L 165 344.612522 L 166 344.60564 L 167 344.600466 L 168 344.602249 L 169 344.604974 L 170 344.616128 L 171 344.644363 L 172 344.688151 L 173 344.70884 L 174 344.749813 L 175 344.789888 L 176 344.808998 L 177 344.831507 L 178 344.898158 L 179 344.947868 L 180 345.021574 L 181 345.052888 L 182 345.12951 L 183 345.167808 L 184 345.241925 L 185 345.345983 L 186 345.415814 L 187 345.521048 L 188 345.576063 L 189 345.699538 L 190 345.770097 L 191 345.885936 L 192 345.936117 L 193 345.971721 L 194 346.063128 L 195 346.116636 L 196 346.204544 L 197 346.273729 L 198 346.320493 L 199 346.392537 L 200 346.442679 L 201 346.460069 L 202 346.487072 L 203 346.506499 L 204 346.525837 L 205 346.564086 L 206 346.580519 L 207 346.588888 L 208 346.593207 L 209 346.599762 L 210 346.597216 L 211 346.591757 L 212 346.575329 L 213 346.543394 L 214 346.505414 L 215 346.47061 L 216 346.407538 L 217 346.386111 L 218 346.335493 L 219 346.310536 L 220 346.254902 L 221 346.223673 L 222 346.173529 L 223 346.141036 L 224 346.060624 L 225 345.991698 L 226 345.876001 L 227 345.800522 L 228 345.684997 L 229 345.605513 L 230 345.497072 L 231 345.457704 L 232 345.354836 L 233 345.255038 L 234 345.209541 L 235 345.175219 L 236 345.123263 L 237 345.083616 L 238 345.048102 L 239 344.980457 L 240 344.941375 L 241 344.890894 L 242 344.841588 L 243 344.790518 L 244 344.746279 L 245 344.724259 L 246 344.708703 L 247 344.666256 L 248 344.651388 L 249 344.62866 L 250 344.608344 L 251 344.602547 L 252 344.600065 L 253 344.603122 L 254 344.614718 L 255 344.631638 L 256 344.663299 L 257 344.677382 L 258 344.730054 L 259 344.779143 L 260 344.833844 L 261 344.878192 L 262 344.948184 L 263 344.998567 L 264 345.052474 L 265 345.121913 L 266 345.179301 L 267 345.229466 L 268 345.306628 L 269 345.364818 L 270 345.425456 L 271 345.462657 L 272 345.527749 L 273 345.632879 L 274 345.693181 L 275 345.789503 L 276 345.821506 L 277 345.872523 L 278 345.989315 L 279 346.024762 L 280 346.080642 L 281 346.111018 L 282 346.199404 L 283 346.244168 L 284 346.325056 L 285 346.385202 L 286 346.448288 L 287 346.471236 L 288 346.487406 L 289 346.516335 L 290 346.546687 L 291 346.559261 L 292 346.58414 L 293 346.596224 L 294 346.599986 L 295 346.59555 L 296 346.583211 L 297 346.568798 L 298 346.552725 L 299 346.517204 L 300 346.49727 L 301 346.440681 L 302 346.373487 L 303 346.346117 L 304 346.311969 L 305 346.263289 L 306 346.215004 L 307 346.155927 L 308 346.060322 L 309 346.017182 L 310 345.967334 L 311 345.9088 L 312 345.861214 L 313 345.800086 L 314 345.744001 L 315 345.66983 L 316 345.552592 L 317 345.496868 L 318 345.388642 L 319 345.282492 L 320 345.17492 L 321 345.140412 L 322 345.037105 L 323 344.961381 L 324 344.921946 L 325 344.882562 L 326 344.86008 L 327 344.804267 L 328 344.778215 L 329 344.74798 L 330 344.697209 L 331 344.678558 L 332 344.656849 L 333 344.644203 L 334 344.62521 L 335 344.60782 L 336 344.600782 L 337 344.601806 L 338 344.60881 L 339 344.61818 L 340 344.641578 L 341 344.666661 L 342 344.67906 L 343 344.712153 L 344 344.72852 L 345 344.746925 L 346 344.796062 L 347 344.839875 L 348 344.88296 L 349 344.905901 L 350 344.946164 L 351 345.031024 L 352 345.073416 L 353 345.137802 L 354 345.182091 L 355 345.289937 L 356 345.366877 L 357 345.403319 L 358 345.458206 L 359 345.533307 L 360 345.591902 L 361 345.628477 L 362 345.740524 L 363 345.802209 L 364 345.852729 L 365 345.951514 L 366 345.989536 L 367 346.024984 L 368 346.116618 L 369 346.15989 L 370 346.213219 L 371 346.246084 L 372 346.308978 L 373 346.362832 L 374 346.419958 L 375 346.442048 L 376 346.485787 L 377 346.532881 L 378 346.549728 L 379 346.577802 L 380 346.588798 L 381 346.593367 L 382 346.599015 L 383 346.599066 L 384 346.595976 L 385 346.592463 L 386 346.586641 L 387 346.573789 L 388 346.550164 L 389 346.53528 L 390 346.511708 L 391 346.475389 L 392 346.443806 L 393 346.413913 L 394 346.335221 L 395 346.29867 L 396 346.272947 L 397 346.202274 L 398 346.111172 L 399 346.049215 L 400 346.015602 L 401 345.981102 L 402 345.883662 L 403 345.836072 L 404 345.804566 L 405 345.760881 L 406 345.690712 L 407 345.640845 L 408 345.606168 L 409 345.49652 L 410 345.463049 L 411 345.425707 L 412 345.345462 L 413 345.306968 L 414 345.265191 L 415 345.222766 L 416 345.113038 L 417 345.024753 L 418 344.950107 L 419 344.86165 L 420 344.787588 L 421 344.738423 L 422 344.682806 L 423 344.648106 L 424 344.636235 L 425 344.614012 L 426 344.602033 L 427 344.600281 L 428 344.605698 L 429 344.621896 L 430 344.638396 L 431 344.669579 L 432 344.682944 L 433 344.712587 L 434 344.77561 L 435 344.824931 L 436 344.87102 L 437 344.953247 L 438 344.99915 L 439 345.033475 L 440 345.087014 L 441 345.175901 L 442 345.207039 L 443 345.315088 L 444 345.42716 L 445 345.462598 L 446 345.547384 L 447 345.612991 L 448 345.715045 L 449 345.83126 L 450 345.871951 L 451 345.91304 L 452 345.949681 L 453 345.990677 L 454 346.066746 L 455 346.142812 L 456 346.1735 L 457 346.199991 L 458 346.256572 L 459 346.301088 L 460.8 346.331106 L 461.558162 344.6 L 461.600727 343.6 L 461.653592 342.6 L 461.684513 341.6 L 461.710788 340.6 L 461.725721 339.6 L 461.75601 338.6 L 461.777339 337.6 L 461.794228 336.6 L 461.798943 335.6 L 461.799553 334.6 L 461.797507 333.6 L 461.791646 332.6 L 461.772999 331.6 L 461.740942 330.6 L 461.694502 329.6 L 461.652556 328.6 L 461.585851 327.6 L 461.516785 326.6 L 461.46941 325.6 L 461.417891 324.6 L 461.378191 323.6 L 461.308771 322.6 L 461.24224 321.6 L 461.133331 320.6 L 461.068083 319.6 L 460.959875 318.6 L 460.898871 317.6 L 460.850186 316.6 L 460.773952 315.6 L 460.714421 314.6 L 460.639793 313.6 L 460.520966 312.6 L 460.423021 311.6 L 460.343973 310.6 L 460.298226 309.6 L 460.270954 308.6 L 460.227292 307.6 L 460.178708 306.6 L 460.146974 305.6 L 460.066744 304.6 L 460.000251 303.6 L 459.976226 302.6 L 459.915727 301.6 L 459.893495 300.6 L 459.874895 299.6 L 459.845569 298.6 L 459.829868 297.6 L 459.821569 296.6 L 459.811333 295.6 L 459.80099 294.6 L 459.801668 293.6 L 459.805448 292.6 L 459.821889 291.6 L 459.834023 290.6 L 459.844618 289.6 L 459.875995 288.6 L 459.901768 287.6 L 459.933177 286.6 L 459.955986 285.6 L 459.97358 284.6 L 460.023392 283.6 L 460.071052 282.6 L 460.142761 281.6 L 460.198524 280.6 L 460.224722 279.6 L 460.25549 278.6 L 460.345248 277.6 L 460.430042 276.6 L 460.495636 275.6 L 460.541461 274.6 L 460.584458 273.6 L 460.645971 272.6 L 460.745796 271.6 L 460.790226 270.6 L 460.840276 269.6 L 460.962117 268.6 L 461.02181 267.6 L 461.053376 266.6 L 461.085719 265.6 L 461.140279 264.6 L 461.182779 263.6 L 461.234251 262.6 L 461.322636 261.6 L 461.356833 260.6 L 461.400767 259.6 L 461.46448 258.6 L 461.539677 257.6 L 461.568491 256.6 L 461.610695 255.6 L 461.65328 254.6 L 461.670172 253.6 L 461.692653 252.6 L 461.73499 251.6 L 461.76495 250.6 L 461.783583 249.6 L 461.793375 248.6 L 461.797138 247.6 L 461.799976 246.6 L 461.798227 245.6 L 461.788871 244.6 L 461.778174 243.6 L 461.768304 242.6 L 461.749446 241.6 L 461.719107 240.6 L 461.680716 239.6 L 461.62123 238.6 L 461.577941 237.6 L 461.517203 236.6 L 461.433129 235.6 L 461.384836 234.6 L 461.341259 233.6 L 461.314378 232.6 L 461.282448 231.6 L 461.215256 230.6 L 461.134435 229.6 L 461.05889 228.6 L 461.01516 227.6 L 460.935265 226.6 L 460.873786 225.6 L 460.810161 224.6 L 460.702912 223.6 L 460.584202 222.6 L 460.542296 221.6 L 460.499342 220.6 L 460.437143 219.6 L 460.407006 218.6 L 460.374488 217.6 L 460.322553 216.6 L 460.217003 215.6 L 460.168557 214.6 L 460.122233 213.6 L 460.088417 212.6 L 460.04054 211.6 L 459.985662 210.6 L 459.961751 209.6 L 459.935714 208.6 L 459.879597 207.6 L 459.865723 206.6 L 459.839689 205.6 L 459.812943 204.6 L 459.805197 203.6 L 459.800044 202.6 L 459.806242 201.6 L 459.812549 200.6 L 459.82013 199.6 L 459.847636 198.6 L 459.891869 197.6 L 459.921407 196.6 L 459.963254 195.6 L 460.022428 194.6 L 460.045138 193.6 L 460.08177 192.6 L 460.138558 191.6 L 460.163728 190.6 L 460.246424 189.6 L 460.333356 188.6 L 460.38404 187.6 L 460.421434 186.6 L 460.505814 185.6 L 460.540325 184.6 L 460.632316 183.6 L 460.719341 182.6 L 460.842481 181.6 L 460.88035 180.6 L 460.927825 179.6 L 461.033351 178.6 L 461.130812 177.6 L 461.207449 176.6 L 461.239376 175.6 L 461.293616 174.6 L 461.332467 173.6 L 461.406172 172.6 L 461.438168 171.6 L 461.494707 170.6 L 461.530823 169.6 L 461.599425 168.6 L 461.630841 167.6 L 461.685508 166.6 L 461.704279 165.6 L 461.749908 164.6 L 461.772811 163.6 L 461.781352 162.6 L 461.788693 161.6 L 461.794988 160.6 L 461.798165 159.6 L 461.799751 158.6 L 461.798288 157.6 L 461.785334 156.6 L 461.770712 155.6 L 461.758856 154.6 L 461.740831 153.6 L 461.720453 152.6 L 461.697054 151.6 L 461.682145 150.6 L 461.627431 149.6 L 461.593834 148.6 L 461.531138 147.6 L 461.503763 146.6 L 461.459783 145.6 L 461.380836 144.6 L 461.323308 143.6 L 461.273329 142.6 L 461.201345 141.6 L 461.164813 140.6 L 461.0965 139.6 L 461.008294 138.6 L 460.886947 137.6 L 460.821266 136.6 L 460.787648 135.6 L 460.723371 134.6 L 460.6774 133.6 L 460.605243 132.6 L 460.565417 131.6 L 460.522787 130.6 L 460.416828 129.6 L 460.364043 128.6 L 460.284766 127.6 L 460.242362 126.6 L 460.210096 125.6 L 460.17523 124.6 L 460.132572 123.6 L 460.100999 122.6 L 460.03342 121.6 L 459.996535 120.6 L 459.968579 119.6 L 459.947731 118.6 L 459.922118 117.6 L 459.8845 116.6 L 459.869658 115.6 L 459.844928 114.6 L 459.826698 113.6 L 459.815291 112.6 L 459.809656 111.6 L 459.804902 110.6 L 459.800293 109.6 L 459.801966 108.6 L 459.807748 107.6 L 459.827744 106.6 L 459.839396 105.6 L 459.850385 104.6 L 459.863352 103.6 L 459.913766 102.6 L 459.934588 101.6 L 459.962535 100.6 L 460.01928 99.6 L 460.041924 98.6 L 460.093327 97.6 L 460.134463 96.6 L 460.217232 95.6 L 460.265692 94.6 L 460.317119 93.6 L 460.368279 92.6 L 460.435578 91.6 L 460.468732 90.6 L 460.53479 89.6 L 460.590975 88.6 L 460.652254 87.6 L 460.692237 86.6 L 460.78866 85.6 L 460.90042 84.6 L 460.939339 83.6 L 461.037188 82.6 L 461.071842 81.6 L 461.155524 80.6 L 461.20603 79.6 L 461.275073 78.6 L 461.376176 77.6 L 461.428622 76.6 L 461.51793 75.6 L 461.582938 74.6 L 461.624483 73.6 L 461.666823 72.6 L 461.688843 71.6 L 461.72633 70.6 L 461.743582 69.6 L 461.76699 68.6 L 461.775557 67.6 L 461.784646 66.6 L 461.791714 65.6 L 461.798741 64.6 L 461.799849 63.6 L 461.799863 62.6 L 461.797189 61.6 L 461.794163 60.6 L 461.788696 59.6 L 461.768701 58.6 L 461.75673 57.6 L 461.729611 56.6 L 461.702599 55.6 L 461.675433 54.6 L 461.620958 53.6 L 461.591342 52.6 L 461.549586 51.6 L 461.476477 50.6 L 461.433039 49.6 L 461.362348 48.6 L 461.323941 47.6 L 461.263602 46.6 L 461.232847 45.6 L 461.202349 44.6 L 461.143439 43.6 L 461.100262 42.6 L 461.05865 41.6 L 461.009535 40.6 L 460.944448 39.6 L 460.878053 38.6 L 460.75329 37.6 L 460.709475 36.6 L 460.655147 35.6 L 460.548443 34.6 L 460.505943 33.6 L 460.468449 32.6 L 460.378953 31.6 L 460.32173 30.6 L 460.252087 29.6 L 460.203068 28.6 L 460.147123 27.6 L 460.099998 26.6 L 460.06111 25.6 L 460.007418 24.6 L 459.961847 23.6 L 459.92491 22.6 L 459.902834 21.6 L 459.869951 20.6 L 459.840231 19.6 L 459.827681 18.6 L 459.815782 17.6 L 459.810664 16.6 L 459.802775 15.6 L 459.800144 14.6 L 459.800942 13.6 L 459.804183 12.6 L 459.819321 11.6 L 459.826258 10.6 L 459.842635 9.6 L 459.861048 8.6 L 459.89064 7.6 L 459.912722 6.6 L 459.970416 5.6 L 459.995607 4.6 L 460.06392 3.6 L 460.111046 2.6 L 460.148394 1.6 L 460.203603 0 L 459.8 0.506966 L 458.8 0.403856 L 457.8 0.349882 L 456.8 0.319162 L 455.8 0.263621 L 454.8 0.225886 L 453.8 0.157632 L 452.8 0.121803 L 451.8 0.052019 L 450.8 -0.007275 L 449.8 -0.045882 L 448.8 -0.079878 L 447.8 -0.122458 L 446.8 -0.169107 L 445.8 -0.223673 L 444.8 -0.309574 L 443.8 -0.35625 L 442.8 -0.413565 L 441.8 -0.443979 L 440.8 -0.52903 L 439.8 -0.562705 L 438.8 -0.650629 L 437.8 -0.705614 L 436.8 -0.744303 L 435.8 -0.814334 L 434.8 -0.84478 L 433.8 -0.902505 L 432.8 -0.919649 L 431.8 -0.944384 L 430.8 -0.959884 L 429.8 -0.983336 L 428.8 -0.99015 L 427.8 -0.994083 L 426.8 -0.997815 L 425.8 -0.999848 L 424.8 -0.991462 L 423.8 -0.975076 L 422.8 -0.948806 L 421.8 -0.935477 L 420.8 -0.905523 L 419.8 -0.871272 L 418.8 -0.850602 L 417.8 -0.80959 L 416.8 -0.736272 L 415.8 -0.713054 L 414.8 -0.672688 L 413.8 -0.645437 L 412.8 -0.564899 L 411.8 -0.511421 L 410.8 -0.43285 L 409.8 -0.384382 L 408.8 -0.270352 L 407.8 -0.169667 L 406.8 -0.085243 L 405.8 0.006297 L 404.8 0.10871 L 403.8 0.149518 L 402.8 0.192661 L 401.8 0.231962 L 400.8 0.265385 L 399.8 0.308493 L 398.8 0.414072 L 397.8 0.469773 L 396.8 0.5751 L 395.8 0.672097 L 394.8 0.695117 L 393.8 0.722104 L 392.8 0.752205 L 391.8 0.825447 L 390.8 0.862839 L 389.8 0.897798 L 388.8 0.916374 L 387.8 0.94688 L 386.8 0.959092 L 385.8 0.968868 L 384.8 0.978437 L 383.8 0.986646 L 382.8 0.997922 L 381.8 0.999784 L 380.8 0.993482 L 379.8 0.987469 L 378.8 0.982012 L 377.8 0.96182 L 376.8 0.951931 L 375.8 0.924178 L 374.8 0.905171 L 373.8 0.889772 L 372.8 0.860507 L 371.8 0.796703 L 370.8 0.74765 L 369.8 0.677461 L 368.8 0.648352 L 367.8 0.588782 L 366.8 0.541833 L 365.8 0.490711 L 364.8 0.436658 L 363.8 0.354971 L 362.8 0.276314 L 361.8 0.239654 L 360.8 0.118 L 359.8 0.039058 L 358.8 -0.025433 L 357.8 -0.071061 L 356.8 -0.18671 L 355.8 -0.234985 L 354.8 -0.270508 L 353.8 -0.314086 L 352.8 -0.349862 L 351.8 -0.420687 L 350.8 -0.457091 L 349.8 -0.554567 L 348.8 -0.623631 L 347.8 -0.689597 L 346.8 -0.754127 L 345.8 -0.777549 L 344.8 -0.804954 L 343.8 -0.853448 L 342.8 -0.883441 L 341.8 -0.915979 L 340.8 -0.930722 L 339.8 -0.944262 L 338.8 -0.967697 L 337.8 -0.980177 L 336.8 -0.987315 L 335.8 -0.992913 L 334.8 -0.998519 L 333.8 -1 L 332.8 -0.994007 L 331.8 -0.988042 L 330.8 -0.97653 L 329.8 -0.952723 L 328.8 -0.94259 L 327.8 -0.900632 L 326.8 -0.85856 L 325.8 -0.827344 L 324.8 -0.757486 L 323.8 -0.71323 L 322.8 -0.63076 L 321.8 -0.542573 L 320.8 -0.497653 L 319.8 -0.401923 L 318.8 -0.329819 L 317.8 -0.234829 L 316.8 -0.178455 L 315.8 -0.134258 L 314.8 -0.078442 L 313.8 -0.038504 L 312.8 0.036947 L 311.8 0.094942 L 310.8 0.132129 L 309.8 0.190656 L 308.8 0.293433 L 307.8 0.35016 L 306.8 0.421165 L 305.8 0.482934 L 304.8 0.520397 L 303.8 0.555683 L 302.8 0.599101 L 301.8 0.64096 L 300.8 0.668583 L 299.8 0.719698 L 298.8 0.753234 L 297.8 0.815297 L 296.8 0.834939 L 295.8 0.896712 L 294.8 0.919191 L 293.8 0.939414 L 292.8 0.960103 L 291.8 0.98653 L 290.8 0.997487 L 289.8 0.999269 L 288.8 0.996641 L 287.8 0.990091 L 286.8 0.968128 L 285.8 0.929128 L 284.8 0.908845 L 283.8 0.892196 L 282.8 0.830573 L 281.8 0.801989 L 280.8 0.778481 L 279.8 0.734033 L 278.8 0.70807 L 277.8 0.65771 L 276.8 0.581318 L 275.8 0.553797 L 274.8 0.521939 L 273.8 0.486315 L 272.8 0.398542 L 271.8 0.301531 L 270.8 0.221578 L 269.8 0.103903 L 268.8 0.031909 L 267.8 -0.072257 L 266.8 -0.183566 L 265.8 -0.278988 L 264.8 -0.373885 L 263.8 -0.440904 L 262.8 -0.501789 L 261.8 -0.54625 L 260.8 -0.581921 L 259.8 -0.661217 L 258.8 -0.691472 L 257.8 -0.765116 L 256.8 -0.797561 L 255.8 -0.842088 L 254.8 -0.863344 L 253.8 -0.891696 L 252.8 -0.920022 L 251.8 -0.954355 L 250.8 -0.967671 L 249.8 -0.984463 L 248.8 -0.995007 L 247.8 -0.998126 L 246.8 -0.999962 L 245.8 -0.994973 L 244.8 -0.989525 L 243.8 -0.97538 L 242.8 -0.940746 L 241.8 -0.921719 L 240.8 -0.879119 L 239.8 -0.861014 L 238.8 -0.816611 L 237.8 -0.794181 L 236.8 -0.753913 L 235.8 -0.721408 L 234.8 -0.658097 L 233.8 -0.569587 L 232.8 -0.483117 L 231.8 -0.403482 L 230.8 -0.349696 L 229.8 -0.289585 L 228.8 -0.218544 L 227.8 -0.098423 L 226.8 0.006039 L 225.8 0.116842 L 224.8 0.170115 L 223.8 0.243365 L 222.8 0.281948 L 221.8 0.357711 L 220.8 0.435272 L 219.8 0.521412 L 218.8 0.548855 L 217.8 0.644831 L 216.8 0.720941 L 215.8 0.771105 L 214.8 0.825458 L 213.8 0.853129 L 212.8 0.889151 L 211.8 0.920712 L 210.8 0.938819 L 209.8 0.955558 L 208.8 0.972565 L 207.8 0.989619 L 206.8 0.99403 L 205.8 0.998289 L 204.8 0.999886 L 203.8 0.998359 L 202.8 0.995935 L 201.8 0.992476 L 200.8 0.982211 L 199.8 0.962483 L 198.8 0.950784 L 197.8 0.90804 L 196.8 0.88236 L 195.8 0.838178 L 194.8 0.782063 L 193.8 0.725365 L 192.8 0.693505 L 191.8 0.656796 L 190.8 0.628663 L 189.8 0.572864 L 188.8 0.538147 L 187.8 0.46646 L 186.8 0.410402 L 185.8 0.328747 L 184.8 0.273173 L 183.8 0.188865 L 182.8 0.14624 L 181.8 0.055234 L 180.8 -0.005051 L 179.8 -0.110128 L 178.8 -0.174313 L 177.8 -0.253509 L 176.8 -0.319736 L 175.8 -0.374012 L 174.8 -0.407139 L 173.8 -0.463853 L 172.8 -0.50741 L 171.8 -0.604653 L 170.8 -0.678599 L 169.8 -0.740393 L 168.8 -0.768808 L 167.8 -0.794142 L 166.8 -0.860397 L 165.8 -0.903414 L 164.8 -0.931921 L 163.8 -0.943915 L 162.8 -0.957989 L 161.8 -0.968817 L 160.8 -0.984115 L 159.8 -0.993971 L 158.8 -0.999784 L 157.8 -0.998949 L 156.8 -0.996987 L 155.8 -0.993379 L 154.8 -0.976068 L 153.8 -0.966337 L 152.8 -0.932307 L 151.8 -0.907236 L 150.8 -0.868539 L 149.8 -0.802605 L 148.8 -0.761617 L 147.8 -0.686776 L 146.8 -0.654849 L 145.8 -0.630635 L 144.8 -0.604815 L 143.8 -0.545775 L 142.8 -0.491063 L 141.8 -0.384861 L 140.8 -0.304585 L 139.8 -0.187843 L 138.8 -0.08788 L 137.8 -0.035566 L 136.8 0.003007 L 135.8 0.039368 L 134.8 0.160354 L 133.8 0.191539 L 132.8 0.227915 L 131.8 0.290066 L 130.8 0.378077 L 129.8 0.42247 L 128.8 0.470988 L 127.8 0.569778 L 126.8 0.611246 L 125.8 0.653898 L 124.8 0.718748 L 123.8 0.785183 L 122.8 0.805272 L 121.8 0.829751 L 120.8 0.870359 L 119.8 0.894905 L 118.8 0.911852 L 117.8 0.942871 L 116.8 0.965923 L 115.8 0.985366 L 114.8 0.992773 L 113.8 0.996995 L 112.8 0.999656 L 111.8 0.999239 L 110.8 0.993894 L 109.8 0.984738 L 108.8 0.972213 L 107.8 0.945446 L 106.8 0.91655 L 105.8 0.86624 L 104.8 0.837897 L 103.8 0.782994 L 102.8 0.745187 L 101.8 0.692498 L 100.8 0.662794 L 99.8 0.631793 L 98.8 0.601321 L 97.8 0.559084 L 96.8 0.531062 L 95.8 0.433515 L 94.8 0.35707 L 93.8 0.301773 L 92.8 0.220903 L 91.8 0.143522 L 90.8 0.062112 L 89.8 0.005147 L 88.8 -0.117966 L 87.8 -0.149535 L 86.8 -0.216766 L 85.8 -0.295058 L 84.8 -0.387611 L 83.8 -0.421765 L 82.8 -0.452679 L 81.8 -0.503004 L 80.8 -0.547822 L 79.8 -0.588823 L 78.8 -0.618678 L 77.8 -0.663526 L 76.8 -0.74679 L 75.8 -0.76885 L 74.8 -0.812967 L 73.8 -0.833129 L 72.8 -0.893251 L 71.8 -0.93548 L 70.8 -0.958737 L 69.8 -0.976732 L 68.8 -0.983734 L 67.8 -0.995973 L 66.8 -0.999442 L 65.8 -0.998259 L 64.8 -0.994084 L 63.8 -0.980354 L 62.8 -0.972703 L 61.8 -0.958263 L 60.8 -0.927611 L 59.8 -0.902922 L 58.8 -0.882675 L 57.8 -0.864202 L 56.8 -0.845248 L 55.8 -0.810642 L 54.8 -0.743359 L 53.8 -0.695131 L 52.8 -0.665749 L 51.8 -0.633906 L 50.8 -0.555682 L 49.8 -0.45647 L 48.8 -0.412576 L 47.8 -0.301816 L 46.8 -0.248043 L 45.8 -0.189835 L 44.8 -0.153658 L 43.8 -0.098867 L 42.8 -0.015916 L 41.8 0.031754 L 40.8 0.120599 L 39.8 0.168247 L 38.8 0.248469 L 37.8 0.337896 L 36.8 0.382122 L 35.8 0.441179 L 34.8 0.539628 L 33.8 0.57467 L 32.8 0.620434 L 31.8 0.673635 L 30.8 0.709483 L 29.8 0.751738 L 28.8 0.793097 L 27.8 0.820445 L 26.8 0.88147 L 25.8 0.904483 L 24.8 0.919261 L 23.8 0.934284 L 22.8 0.947208 L 21.8 0.979534 L 20.8 0.996802 L 19.8 0.999844 L 18.8 0.997823 L 17.8 0.99401 L 16.8 0.978994 L 15.8 0.970072 L 14.8 0.95778 L 13.8 0.929404 L 12.8 0.901094 L 11.8 0.866107 L 10.8 0.813717 L 9.8 0.765101 L 8.8 0.721134 L 7.8 0.682742 L 6.8 0.590438 L 5.8 0.563187 L 4.8 0.517238 L 3.8 0.475854 L 2.8 0.436431 L 1.8 0.377515 L 0 0.273593 L 0.227262 1 L 0.140289 2 L 0.091558 3 L 0.053928 4 L 0.017733 5 L -0.06793 6 L -0.161753 7 L -0.273189 8 L -0.360274 9 L -0.40709 10 L -0.463838 11 L -0.531601 12 L -0.573508 13 L -0.625352 14 L -0.650645 15 L -0.724163 16 L -0.770317 17 L -0.791479 18 L -0.851149 19 L -0.887991 20 L -0.917061 21 L -0.941292 22 L -0.951546 23 L -0.981839 24 L -0.994579 25 L -0.999784 26 L -0.999825 27 L -0.998417 28 L -0.992654 29 L -0.986301 30 L -0.967662 31 L -0.943214 32 L -0.912437 33 L -0.895086 34 L -0.880479 35 L -0.851999 36 L -0.833049 37 L -0.804776 38 L -0.736949 39 L -0.694852 40 L -0.659088 41 L -0.608192 42 L -0.546144 43 L -0.469078 44 L -0.390646 45 L -0.314256 46 L -0.272519 47 L -0.174586 48 L -0.104796 49 L -0.033939 50 L 0.084549 51 L 0.122597 52 L 0.158643 53 L 0.20132 54 L 0.299241 55 L 0.371531 56 L 0.414118 57 L 0.451421 58 L 0.546295 59 L 0.588994 60 L 0.621715 61 L 0.647784 62 L 0.677809 63 L 0.707013 64 L 0.742447 65 L 0.763133 66 L 0.785911 67 L 0.848282 68 L 0.876933 69 L 0.89743 70 L 0.932584 71 L 0.952705 72 L 0.963835 73 L 0.983785 74 L 0.997162 75 L 0.998974 76 L 0.993744 77 L 0.987133 78 L 0.961107 79 L 0.93948 80 L 0.917584 81 L 0.899066 82 L 0.868853 83 L 0.826455 84 L 0.799415 85 L 0.778893 86 L 0.743514 87 L 0.655618 88 L 0.618638 89 L 0.545793 90 L 0.443104 91 L 0.409892 92 L 0.309442 93 L 0.277702 94 L 0.234758 95 L 0.200953 96 L 0.120665 97 L 0.086322 98 L 0.0144 99 L -0.061467 100 L -0.117562 101 L -0.207304 102 L -0.24726 103 L -0.314957 104 L -0.42911 105 L -0.460269 106 L -0.525752 107 L -0.557786 108 L -0.642979 109 L -0.673037 110 L -0.719408 111 L -0.749116 112 L -0.778759 113 L -0.843855 114 L -0.877651 115 L -0.902804 116 L -0.918897 117 L -0.955058 118 L -0.973964 119 L -0.984187 120 L -0.992492 121 L -0.999215 122 L -0.996501 123 L -0.988797 124 L -0.971166 125 L -0.940938 126 L -0.912341 127 L -0.885031 128 L -0.825603 129 L -0.77009 130 L -0.688452 131 L -0.647196 132 L -0.60259 133 L -0.511042 134 L -0.430427 135 L -0.384469 136 L -0.292923 137 L -0.225967 138 L -0.179248 139 L -0.136118 140 L -0.077875 141 L -0.030604 142 L 0.026452 143 L 0.080989 144 L 0.196427 145 L 0.315576 146 L 0.370627 147 L 0.40698 148 L 0.502034 149 L 0.546466 150 L 0.575573 151 L 0.667237 152 L 0.714029 153 L 0.749742 154 L 0.795559 155 L 0.859505 156 L 0.892455 157 L 0.917515 158 L 0.933607 159 L 0.970088 160 L 0.979122 161 L 0.985274 162 L 0.990848 163 L 0.99806 164 L 0.99889 165 L 0.994277 166 L 0.981883 167 L 0.973583 168 L 0.937803 169 L 0.919049 170 L 0.901448 171 L 0.87707 172 L 0.844234 173 L 0.771924 174 L 0.735339 175 L 0.713128 176 L 0.683072 177 L 0.643552 178 L 0.614091 179 L 0.569454 180 L 0.500184 181 L 0.392301 182 L 0.355195 183 L 0.247165 184 L 0.140245 185 L 0.103559 186 L 0.051805 187 L -0.035129 188 L -0.106027 189 L -0.227181 190 L -0.260107 191 L -0.313632 192 L -0.359984 193 L -0.401339 194 L -0.450067 195 L -0.490327 196 L -0.533979 197 L -0.560575 198 L -0.651745 199 L -0.691652 200 L -0.720319 201 L -0.762616 202 L -0.811738 203 L -0.865675 204 L -0.918013 205 L -0.952001 206 L -0.967156 207 L -0.980387 208 L -0.992416 209 L -0.998222 210 L -0.99846 211 L -0.995029 212 L -0.978361 213 L -0.950969 214 L -0.910428 215 L -0.890133 216 L -0.872536 217 L -0.847806 218 L -0.794595 219 L -0.753623 220 L -0.693228 221 L -0.609661 222 L -0.563669 223 L -0.532753 224 L -0.502298 225 L -0.455614 226 L -0.387673 227 L -0.355756 228 L -0.30615 229 L -0.205734 230 L -0.170513 231 L -0.129026 232 L -0.0754 233 L -0.035334 234 L 0.07453 235 L 0.195709 236 L 0.233871 237 L 0.303602 238 L 0.362359 239 L 0.415477 240 L 0.479944 241 L 0.522985 242 L 0.587131 243 L 0.631929 244 L 0.71055 245 L 0.733761 246 L 0.756219 247 L 0.826066 248 L 0.846169 249 L 0.872053 250 L 0.895656 251 L 0.909427 252 L 0.933238 253 L 0.968289 254 L 0.987905 255 L 0.997925 256 L 0.999511 257 L 0.997397 258 L 0.994191 259 L 0.987806 260 L 0.972822 261 L 0.963505 262 L 0.943913 263 L 0.912031 264 L 0.858743 265 L 0.824485 266 L 0.803278 267 L 0.770858 268 L 0.745139 269 L 0.704247 270 L 0.679944 271 L 0.652386 272 L 0.613312 273 L 0.574818 274 L 0.521172 275 L 0.478431 276 L 0.446006 277 L 0.408082 278 L 0.378531 279 L 0.304491 280 L 0.26975 281 L 0.198648 282 L 0.140692 283 L 0.106477 284 L 0.001931 285 L -0.031948 286 L -0.139586 287 L -0.197401 288 L -0.263521 289 L -0.338446 290 L -0.397233 291 L -0.504686 292 L -0.600611 293 L -0.660743 294 L -0.694963 295 L -0.772666 296 L -0.810252 297 L -0.853431 298 L -0.881952 299 L -0.917155 300 L -0.941985 301 L -0.967909 302 L -0.983386 303 L -0.988682 304 L -0.999195 305 L -0.999894 306 L -0.998307 307 L -0.983759 308 L -0.976299 309 L -0.949036 310 L -0.904736 311 L -0.887316 312 L -0.847912 313 L -0.811558 314 L -0.773772 315 L -0.719976 316 L -0.6736 317 L -0.625248 318 L -0.57127 319 L -0.507815 320 L -0.41649 321 L -0.374633 322 L -0.343546 323 L -0.27172 324 L -0.238363 325 L -0.204546 326 L -0.16887 327 L -0.085534 328 L -0.053624 329 L 0.040791 330 L 0.163353 331 L 0.248217 332 L 0.307634 333 L 0.341295 334 L 0.436499 335 L 0.466063 336 L 0.500969 337 L 0.532344 338 L 0.629809 339 L 0.655764 340 L 0.706154 341 L 0.736458 342 L 0.792812 343 L 0.811609 344 L 0.857562 345.6 z " + style="fill: #ffffff; stroke: #ffffff; stroke-width: 4; stroke-linejoin: miter" + id="path1" /> + <path + d="M 0 345.6 L 1 345.631436 L 2 345.668377 L 3 345.766123 L 4 345.798645 L 5 345.87227 L 6 345.910835 L 7 345.946248 L 8 346.003888 L 9 346.074274 L 10 346.126239 L 11 346.185328 L 12 346.273649 L 13 346.319794 L 14 346.362205 L 15 346.392697 L 16 346.418742 L 17 346.439942 L 18 346.494243 L 19 346.522181 L 20 346.551905 L 21 346.5773 L 22 346.5885 L 23 346.598624 L 24 346.59842 L 25 346.58891 L 26 346.577256 L 27 346.546227 L 28 346.535059 L 29 346.504942 L 30 346.445165 L 31 346.407973 L 32 346.368877 L 33 346.326437 L 34 346.293672 L 35 346.226246 L 36 346.18712 L 37 346.144445 L 38 346.073865 L 39 346.037474 L 40 345.979071 L 41 345.868118 L 42 345.79746 L 43 345.68452 L 44 345.638747 L 45 345.577464 L 46 345.528965 L 47 345.448142 L 48 345.329623 L 49 345.259412 L 50 345.17615 L 51 345.143008 L 52 345.091771 L 53 345.023372 L 54 344.957157 L 55 344.88024 L 56 344.852924 L 57 344.826447 L 58 344.803796 L 59 344.784265 L 60 344.757871 L 61 344.7081 L 62 344.673027 L 63 344.637161 L 64 344.621794 L 65 344.606025 L 66 344.602612 L 67 344.600195 L 68 344.600681 L 69 344.60261 L 70 344.615867 L 71 344.624258 L 72 344.645794 L 73 344.668827 L 74 344.68606 L 75 344.704523 L 76 344.724975 L 77 344.741575 L 78 344.804354 L 79 344.879619 L 80 344.912258 L 81 344.979822 L 82 345.033869 L 83 345.067573 L 84 345.157699 L 85 345.186234 L 86 345.21772 L 87 345.248731 L 88 345.303539 L 89 345.368126 L 90 345.406322 L 91 345.502256 L 92 345.551514 L 93 345.595583 L 94 345.635707 L 95 345.744074 L 96 345.785702 L 97 345.847844 L 98 345.917806 L 99 346.02231 L 100 346.059298 L 101 346.105175 L 102 346.17367 L 103 346.222416 L 104 346.300013 L 105 346.330554 L 106 346.400068 L 107 346.424041 L 108 346.452663 L 109 346.494456 L 110 346.516032 L 111 346.52998 L 112 346.556702 L 113 346.566012 L 114 346.578459 L 115 346.589514 L 116 346.595178 L 117 346.599942 L 118 346.594394 L 119 346.581106 L 120 346.573589 L 121 346.548804 L 122 346.525235 L 123 346.489055 L 124 346.463093 L 125 346.440771 L 126 346.372011 L 127 346.297476 L 128 346.203497 L 129 346.152445 L 130 346.098511 L 131 346.06326 L 132 345.957172 L 133 345.904908 L 134 345.868001 L 135 345.83697 L 136 345.775815 L 137 345.708395 L 138 345.659489 L 139 345.594297 L 140 345.556109 L 141 345.514113 L 142 345.472096 L 143 345.41258 L 144 345.29942 L 145 345.247169 L 146 345.207751 L 147 345.16065 L 148 345.10387 L 149 345.071207 L 150 345.035029 L 151 345.002939 L 152 344.968659 L 153 344.910281 L 154 344.865096 L 155 344.835472 L 156 344.785086 L 157 344.759889 L 158 344.738838 L 159 344.70387 L 160 344.67958 L 161 344.665513 L 162 344.646571 L 163 344.63091 L 164 344.618358 L 165 344.612522 L 166 344.60564 L 167 344.600466 L 168 344.602249 L 169 344.604974 L 170 344.616128 L 171 344.644363 L 172 344.688151 L 173 344.70884 L 174 344.749813 L 175 344.789888 L 176 344.808998 L 177 344.831507 L 178 344.898158 L 179 344.947868 L 180 345.021574 L 181 345.052888 L 182 345.12951 L 183 345.167808 L 184 345.241925 L 185 345.345983 L 186 345.415814 L 187 345.521048 L 188 345.576063 L 189 345.699538 L 190 345.770097 L 191 345.885936 L 192 345.936117 L 193 345.971721 L 194 346.063128 L 195 346.116636 L 196 346.204544 L 197 346.273729 L 198 346.320493 L 199 346.392537 L 200 346.442679 L 201 346.460069 L 202 346.487072 L 203 346.506499 L 204 346.525837 L 205 346.564086 L 206 346.580519 L 207 346.588888 L 208 346.593207 L 209 346.599762 L 210 346.597216 L 211 346.591757 L 212 346.575329 L 213 346.543394 L 214 346.505414 L 215 346.47061 L 216 346.407538 L 217 346.386111 L 218 346.335493 L 219 346.310536 L 220 346.254902 L 221 346.223673 L 222 346.173529 L 223 346.141036 L 224 346.060624 L 225 345.991698 L 226 345.876001 L 227 345.800522 L 228 345.684997 L 229 345.605513 L 230 345.497072 L 231 345.457704 L 232 345.354836 L 233 345.255038 L 234 345.209541 L 235 345.175219 L 236 345.123263 L 237 345.083616 L 238 345.048102 L 239 344.980457 L 240 344.941375 L 241 344.890894 L 242 344.841588 L 243 344.790518 L 244 344.746279 L 245 344.724259 L 246 344.708703 L 247 344.666256 L 248 344.651388 L 249 344.62866 L 250 344.608344 L 251 344.602547 L 252 344.600065 L 253 344.603122 L 254 344.614718 L 255 344.631638 L 256 344.663299 L 257 344.677382 L 258 344.730054 L 259 344.779143 L 260 344.833844 L 261 344.878192 L 262 344.948184 L 263 344.998567 L 264 345.052474 L 265 345.121913 L 266 345.179301 L 267 345.229466 L 268 345.306628 L 269 345.364818 L 270 345.425456 L 271 345.462657 L 272 345.527749 L 273 345.632879 L 274 345.693181 L 275 345.789503 L 276 345.821506 L 277 345.872523 L 278 345.989315 L 279 346.024762 L 280 346.080642 L 281 346.111018 L 282 346.199404 L 283 346.244168 L 284 346.325056 L 285 346.385202 L 286 346.448288 L 287 346.471236 L 288 346.487406 L 289 346.516335 L 290 346.546687 L 291 346.559261 L 292 346.58414 L 293 346.596224 L 294 346.599986 L 295 346.59555 L 296 346.583211 L 297 346.568798 L 298 346.552725 L 299 346.517204 L 300 346.49727 L 301 346.440681 L 302 346.373487 L 303 346.346117 L 304 346.311969 L 305 346.263289 L 306 346.215004 L 307 346.155927 L 308 346.060322 L 309 346.017182 L 310 345.967334 L 311 345.9088 L 312 345.861214 L 313 345.800086 L 314 345.744001 L 315 345.66983 L 316 345.552592 L 317 345.496868 L 318 345.388642 L 319 345.282492 L 320 345.17492 L 321 345.140412 L 322 345.037105 L 323 344.961381 L 324 344.921946 L 325 344.882562 L 326 344.86008 L 327 344.804267 L 328 344.778215 L 329 344.74798 L 330 344.697209 L 331 344.678558 L 332 344.656849 L 333 344.644203 L 334 344.62521 L 335 344.60782 L 336 344.600782 L 337 344.601806 L 338 344.60881 L 339 344.61818 L 340 344.641578 L 341 344.666661 L 342 344.67906 L 343 344.712153 L 344 344.72852 L 345 344.746925 L 346 344.796062 L 347 344.839875 L 348 344.88296 L 349 344.905901 L 350 344.946164 L 351 345.031024 L 352 345.073416 L 353 345.137802 L 354 345.182091 L 355 345.289937 L 356 345.366877 L 357 345.403319 L 358 345.458206 L 359 345.533307 L 360 345.591902 L 361 345.628477 L 362 345.740524 L 363 345.802209 L 364 345.852729 L 365 345.951514 L 366 345.989536 L 367 346.024984 L 368 346.116618 L 369 346.15989 L 370 346.213219 L 371 346.246084 L 372 346.308978 L 373 346.362832 L 374 346.419958 L 375 346.442048 L 376 346.485787 L 377 346.532881 L 378 346.549728 L 379 346.577802 L 380 346.588798 L 381 346.593367 L 382 346.599015 L 383 346.599066 L 384 346.595976 L 385 346.592463 L 386 346.586641 L 387 346.573789 L 388 346.550164 L 389 346.53528 L 390 346.511708 L 391 346.475389 L 392 346.443806 L 393 346.413913 L 394 346.335221 L 395 346.29867 L 396 346.272947 L 397 346.202274 L 398 346.111172 L 399 346.049215 L 400 346.015602 L 401 345.981102 L 402 345.883662 L 403 345.836072 L 404 345.804566 L 405 345.760881 L 406 345.690712 L 407 345.640845 L 408 345.606168 L 409 345.49652 L 410 345.463049 L 411 345.425707 L 412 345.345462 L 413 345.306968 L 414 345.265191 L 415 345.222766 L 416 345.113038 L 417 345.024753 L 418 344.950107 L 419 344.86165 L 420 344.787588 L 421 344.738423 L 422 344.682806 L 423 344.648106 L 424 344.636235 L 425 344.614012 L 426 344.602033 L 427 344.600281 L 428 344.605698 L 429 344.621896 L 430 344.638396 L 431 344.669579 L 432 344.682944 L 433 344.712587 L 434 344.77561 L 435 344.824931 L 436 344.87102 L 437 344.953247 L 438 344.99915 L 439 345.033475 L 440 345.087014 L 441 345.175901 L 442 345.207039 L 443 345.315088 L 444 345.42716 L 445 345.462598 L 446 345.547384 L 447 345.612991 L 448 345.715045 L 449 345.83126 L 450 345.871951 L 451 345.91304 L 452 345.949681 L 453 345.990677 L 454 346.066746 L 455 346.142812 L 456 346.1735 L 457 346.199991 L 458 346.256572 L 459 346.301088 L 460.8 346.331106 L 461.558162 344.6 L 461.600727 343.6 L 461.653592 342.6 L 461.684513 341.6 L 461.710788 340.6 L 461.725721 339.6 L 461.75601 338.6 L 461.777339 337.6 L 461.794228 336.6 L 461.798943 335.6 L 461.799553 334.6 L 461.797507 333.6 L 461.791646 332.6 L 461.772999 331.6 L 461.740942 330.6 L 461.694502 329.6 L 461.652556 328.6 L 461.585851 327.6 L 461.516785 326.6 L 461.46941 325.6 L 461.417891 324.6 L 461.378191 323.6 L 461.308771 322.6 L 461.24224 321.6 L 461.133331 320.6 L 461.068083 319.6 L 460.959875 318.6 L 460.898871 317.6 L 460.850186 316.6 L 460.773952 315.6 L 460.714421 314.6 L 460.639793 313.6 L 460.520966 312.6 L 460.423021 311.6 L 460.343973 310.6 L 460.298226 309.6 L 460.270954 308.6 L 460.227292 307.6 L 460.178708 306.6 L 460.146974 305.6 L 460.066744 304.6 L 460.000251 303.6 L 459.976226 302.6 L 459.915727 301.6 L 459.893495 300.6 L 459.874895 299.6 L 459.845569 298.6 L 459.829868 297.6 L 459.821569 296.6 L 459.811333 295.6 L 459.80099 294.6 L 459.801668 293.6 L 459.805448 292.6 L 459.821889 291.6 L 459.834023 290.6 L 459.844618 289.6 L 459.875995 288.6 L 459.901768 287.6 L 459.933177 286.6 L 459.955986 285.6 L 459.97358 284.6 L 460.023392 283.6 L 460.071052 282.6 L 460.142761 281.6 L 460.198524 280.6 L 460.224722 279.6 L 460.25549 278.6 L 460.345248 277.6 L 460.430042 276.6 L 460.495636 275.6 L 460.541461 274.6 L 460.584458 273.6 L 460.645971 272.6 L 460.745796 271.6 L 460.790226 270.6 L 460.840276 269.6 L 460.962117 268.6 L 461.02181 267.6 L 461.053376 266.6 L 461.085719 265.6 L 461.140279 264.6 L 461.182779 263.6 L 461.234251 262.6 L 461.322636 261.6 L 461.356833 260.6 L 461.400767 259.6 L 461.46448 258.6 L 461.539677 257.6 L 461.568491 256.6 L 461.610695 255.6 L 461.65328 254.6 L 461.670172 253.6 L 461.692653 252.6 L 461.73499 251.6 L 461.76495 250.6 L 461.783583 249.6 L 461.793375 248.6 L 461.797138 247.6 L 461.799976 246.6 L 461.798227 245.6 L 461.788871 244.6 L 461.778174 243.6 L 461.768304 242.6 L 461.749446 241.6 L 461.719107 240.6 L 461.680716 239.6 L 461.62123 238.6 L 461.577941 237.6 L 461.517203 236.6 L 461.433129 235.6 L 461.384836 234.6 L 461.341259 233.6 L 461.314378 232.6 L 461.282448 231.6 L 461.215256 230.6 L 461.134435 229.6 L 461.05889 228.6 L 461.01516 227.6 L 460.935265 226.6 L 460.873786 225.6 L 460.810161 224.6 L 460.702912 223.6 L 460.584202 222.6 L 460.542296 221.6 L 460.499342 220.6 L 460.437143 219.6 L 460.407006 218.6 L 460.374488 217.6 L 460.322553 216.6 L 460.217003 215.6 L 460.168557 214.6 L 460.122233 213.6 L 460.088417 212.6 L 460.04054 211.6 L 459.985662 210.6 L 459.961751 209.6 L 459.935714 208.6 L 459.879597 207.6 L 459.865723 206.6 L 459.839689 205.6 L 459.812943 204.6 L 459.805197 203.6 L 459.800044 202.6 L 459.806242 201.6 L 459.812549 200.6 L 459.82013 199.6 L 459.847636 198.6 L 459.891869 197.6 L 459.921407 196.6 L 459.963254 195.6 L 460.022428 194.6 L 460.045138 193.6 L 460.08177 192.6 L 460.138558 191.6 L 460.163728 190.6 L 460.246424 189.6 L 460.333356 188.6 L 460.38404 187.6 L 460.421434 186.6 L 460.505814 185.6 L 460.540325 184.6 L 460.632316 183.6 L 460.719341 182.6 L 460.842481 181.6 L 460.88035 180.6 L 460.927825 179.6 L 461.033351 178.6 L 461.130812 177.6 L 461.207449 176.6 L 461.239376 175.6 L 461.293616 174.6 L 461.332467 173.6 L 461.406172 172.6 L 461.438168 171.6 L 461.494707 170.6 L 461.530823 169.6 L 461.599425 168.6 L 461.630841 167.6 L 461.685508 166.6 L 461.704279 165.6 L 461.749908 164.6 L 461.772811 163.6 L 461.781352 162.6 L 461.788693 161.6 L 461.794988 160.6 L 461.798165 159.6 L 461.799751 158.6 L 461.798288 157.6 L 461.785334 156.6 L 461.770712 155.6 L 461.758856 154.6 L 461.740831 153.6 L 461.720453 152.6 L 461.697054 151.6 L 461.682145 150.6 L 461.627431 149.6 L 461.593834 148.6 L 461.531138 147.6 L 461.503763 146.6 L 461.459783 145.6 L 461.380836 144.6 L 461.323308 143.6 L 461.273329 142.6 L 461.201345 141.6 L 461.164813 140.6 L 461.0965 139.6 L 461.008294 138.6 L 460.886947 137.6 L 460.821266 136.6 L 460.787648 135.6 L 460.723371 134.6 L 460.6774 133.6 L 460.605243 132.6 L 460.565417 131.6 L 460.522787 130.6 L 460.416828 129.6 L 460.364043 128.6 L 460.284766 127.6 L 460.242362 126.6 L 460.210096 125.6 L 460.17523 124.6 L 460.132572 123.6 L 460.100999 122.6 L 460.03342 121.6 L 459.996535 120.6 L 459.968579 119.6 L 459.947731 118.6 L 459.922118 117.6 L 459.8845 116.6 L 459.869658 115.6 L 459.844928 114.6 L 459.826698 113.6 L 459.815291 112.6 L 459.809656 111.6 L 459.804902 110.6 L 459.800293 109.6 L 459.801966 108.6 L 459.807748 107.6 L 459.827744 106.6 L 459.839396 105.6 L 459.850385 104.6 L 459.863352 103.6 L 459.913766 102.6 L 459.934588 101.6 L 459.962535 100.6 L 460.01928 99.6 L 460.041924 98.6 L 460.093327 97.6 L 460.134463 96.6 L 460.217232 95.6 L 460.265692 94.6 L 460.317119 93.6 L 460.368279 92.6 L 460.435578 91.6 L 460.468732 90.6 L 460.53479 89.6 L 460.590975 88.6 L 460.652254 87.6 L 460.692237 86.6 L 460.78866 85.6 L 460.90042 84.6 L 460.939339 83.6 L 461.037188 82.6 L 461.071842 81.6 L 461.155524 80.6 L 461.20603 79.6 L 461.275073 78.6 L 461.376176 77.6 L 461.428622 76.6 L 461.51793 75.6 L 461.582938 74.6 L 461.624483 73.6 L 461.666823 72.6 L 461.688843 71.6 L 461.72633 70.6 L 461.743582 69.6 L 461.76699 68.6 L 461.775557 67.6 L 461.784646 66.6 L 461.791714 65.6 L 461.798741 64.6 L 461.799849 63.6 L 461.799863 62.6 L 461.797189 61.6 L 461.794163 60.6 L 461.788696 59.6 L 461.768701 58.6 L 461.75673 57.6 L 461.729611 56.6 L 461.702599 55.6 L 461.675433 54.6 L 461.620958 53.6 L 461.591342 52.6 L 461.549586 51.6 L 461.476477 50.6 L 461.433039 49.6 L 461.362348 48.6 L 461.323941 47.6 L 461.263602 46.6 L 461.232847 45.6 L 461.202349 44.6 L 461.143439 43.6 L 461.100262 42.6 L 461.05865 41.6 L 461.009535 40.6 L 460.944448 39.6 L 460.878053 38.6 L 460.75329 37.6 L 460.709475 36.6 L 460.655147 35.6 L 460.548443 34.6 L 460.505943 33.6 L 460.468449 32.6 L 460.378953 31.6 L 460.32173 30.6 L 460.252087 29.6 L 460.203068 28.6 L 460.147123 27.6 L 460.099998 26.6 L 460.06111 25.6 L 460.007418 24.6 L 459.961847 23.6 L 459.92491 22.6 L 459.902834 21.6 L 459.869951 20.6 L 459.840231 19.6 L 459.827681 18.6 L 459.815782 17.6 L 459.810664 16.6 L 459.802775 15.6 L 459.800144 14.6 L 459.800942 13.6 L 459.804183 12.6 L 459.819321 11.6 L 459.826258 10.6 L 459.842635 9.6 L 459.861048 8.6 L 459.89064 7.6 L 459.912722 6.6 L 459.970416 5.6 L 459.995607 4.6 L 460.06392 3.6 L 460.111046 2.6 L 460.148394 1.6 L 460.203603 0 L 459.8 0.506966 L 458.8 0.403856 L 457.8 0.349882 L 456.8 0.319162 L 455.8 0.263621 L 454.8 0.225886 L 453.8 0.157632 L 452.8 0.121803 L 451.8 0.052019 L 450.8 -0.007275 L 449.8 -0.045882 L 448.8 -0.079878 L 447.8 -0.122458 L 446.8 -0.169107 L 445.8 -0.223673 L 444.8 -0.309574 L 443.8 -0.35625 L 442.8 -0.413565 L 441.8 -0.443979 L 440.8 -0.52903 L 439.8 -0.562705 L 438.8 -0.650629 L 437.8 -0.705614 L 436.8 -0.744303 L 435.8 -0.814334 L 434.8 -0.84478 L 433.8 -0.902505 L 432.8 -0.919649 L 431.8 -0.944384 L 430.8 -0.959884 L 429.8 -0.983336 L 428.8 -0.99015 L 427.8 -0.994083 L 426.8 -0.997815 L 425.8 -0.999848 L 424.8 -0.991462 L 423.8 -0.975076 L 422.8 -0.948806 L 421.8 -0.935477 L 420.8 -0.905523 L 419.8 -0.871272 L 418.8 -0.850602 L 417.8 -0.80959 L 416.8 -0.736272 L 415.8 -0.713054 L 414.8 -0.672688 L 413.8 -0.645437 L 412.8 -0.564899 L 411.8 -0.511421 L 410.8 -0.43285 L 409.8 -0.384382 L 408.8 -0.270352 L 407.8 -0.169667 L 406.8 -0.085243 L 405.8 0.006297 L 404.8 0.10871 L 403.8 0.149518 L 402.8 0.192661 L 401.8 0.231962 L 400.8 0.265385 L 399.8 0.308493 L 398.8 0.414072 L 397.8 0.469773 L 396.8 0.5751 L 395.8 0.672097 L 394.8 0.695117 L 393.8 0.722104 L 392.8 0.752205 L 391.8 0.825447 L 390.8 0.862839 L 389.8 0.897798 L 388.8 0.916374 L 387.8 0.94688 L 386.8 0.959092 L 385.8 0.968868 L 384.8 0.978437 L 383.8 0.986646 L 382.8 0.997922 L 381.8 0.999784 L 380.8 0.993482 L 379.8 0.987469 L 378.8 0.982012 L 377.8 0.96182 L 376.8 0.951931 L 375.8 0.924178 L 374.8 0.905171 L 373.8 0.889772 L 372.8 0.860507 L 371.8 0.796703 L 370.8 0.74765 L 369.8 0.677461 L 368.8 0.648352 L 367.8 0.588782 L 366.8 0.541833 L 365.8 0.490711 L 364.8 0.436658 L 363.8 0.354971 L 362.8 0.276314 L 361.8 0.239654 L 360.8 0.118 L 359.8 0.039058 L 358.8 -0.025433 L 357.8 -0.071061 L 356.8 -0.18671 L 355.8 -0.234985 L 354.8 -0.270508 L 353.8 -0.314086 L 352.8 -0.349862 L 351.8 -0.420687 L 350.8 -0.457091 L 349.8 -0.554567 L 348.8 -0.623631 L 347.8 -0.689597 L 346.8 -0.754127 L 345.8 -0.777549 L 344.8 -0.804954 L 343.8 -0.853448 L 342.8 -0.883441 L 341.8 -0.915979 L 340.8 -0.930722 L 339.8 -0.944262 L 338.8 -0.967697 L 337.8 -0.980177 L 336.8 -0.987315 L 335.8 -0.992913 L 334.8 -0.998519 L 333.8 -1 L 332.8 -0.994007 L 331.8 -0.988042 L 330.8 -0.97653 L 329.8 -0.952723 L 328.8 -0.94259 L 327.8 -0.900632 L 326.8 -0.85856 L 325.8 -0.827344 L 324.8 -0.757486 L 323.8 -0.71323 L 322.8 -0.63076 L 321.8 -0.542573 L 320.8 -0.497653 L 319.8 -0.401923 L 318.8 -0.329819 L 317.8 -0.234829 L 316.8 -0.178455 L 315.8 -0.134258 L 314.8 -0.078442 L 313.8 -0.038504 L 312.8 0.036947 L 311.8 0.094942 L 310.8 0.132129 L 309.8 0.190656 L 308.8 0.293433 L 307.8 0.35016 L 306.8 0.421165 L 305.8 0.482934 L 304.8 0.520397 L 303.8 0.555683 L 302.8 0.599101 L 301.8 0.64096 L 300.8 0.668583 L 299.8 0.719698 L 298.8 0.753234 L 297.8 0.815297 L 296.8 0.834939 L 295.8 0.896712 L 294.8 0.919191 L 293.8 0.939414 L 292.8 0.960103 L 291.8 0.98653 L 290.8 0.997487 L 289.8 0.999269 L 288.8 0.996641 L 287.8 0.990091 L 286.8 0.968128 L 285.8 0.929128 L 284.8 0.908845 L 283.8 0.892196 L 282.8 0.830573 L 281.8 0.801989 L 280.8 0.778481 L 279.8 0.734033 L 278.8 0.70807 L 277.8 0.65771 L 276.8 0.581318 L 275.8 0.553797 L 274.8 0.521939 L 273.8 0.486315 L 272.8 0.398542 L 271.8 0.301531 L 270.8 0.221578 L 269.8 0.103903 L 268.8 0.031909 L 267.8 -0.072257 L 266.8 -0.183566 L 265.8 -0.278988 L 264.8 -0.373885 L 263.8 -0.440904 L 262.8 -0.501789 L 261.8 -0.54625 L 260.8 -0.581921 L 259.8 -0.661217 L 258.8 -0.691472 L 257.8 -0.765116 L 256.8 -0.797561 L 255.8 -0.842088 L 254.8 -0.863344 L 253.8 -0.891696 L 252.8 -0.920022 L 251.8 -0.954355 L 250.8 -0.967671 L 249.8 -0.984463 L 248.8 -0.995007 L 247.8 -0.998126 L 246.8 -0.999962 L 245.8 -0.994973 L 244.8 -0.989525 L 243.8 -0.97538 L 242.8 -0.940746 L 241.8 -0.921719 L 240.8 -0.879119 L 239.8 -0.861014 L 238.8 -0.816611 L 237.8 -0.794181 L 236.8 -0.753913 L 235.8 -0.721408 L 234.8 -0.658097 L 233.8 -0.569587 L 232.8 -0.483117 L 231.8 -0.403482 L 230.8 -0.349696 L 229.8 -0.289585 L 228.8 -0.218544 L 227.8 -0.098423 L 226.8 0.006039 L 225.8 0.116842 L 224.8 0.170115 L 223.8 0.243365 L 222.8 0.281948 L 221.8 0.357711 L 220.8 0.435272 L 219.8 0.521412 L 218.8 0.548855 L 217.8 0.644831 L 216.8 0.720941 L 215.8 0.771105 L 214.8 0.825458 L 213.8 0.853129 L 212.8 0.889151 L 211.8 0.920712 L 210.8 0.938819 L 209.8 0.955558 L 208.8 0.972565 L 207.8 0.989619 L 206.8 0.99403 L 205.8 0.998289 L 204.8 0.999886 L 203.8 0.998359 L 202.8 0.995935 L 201.8 0.992476 L 200.8 0.982211 L 199.8 0.962483 L 198.8 0.950784 L 197.8 0.90804 L 196.8 0.88236 L 195.8 0.838178 L 194.8 0.782063 L 193.8 0.725365 L 192.8 0.693505 L 191.8 0.656796 L 190.8 0.628663 L 189.8 0.572864 L 188.8 0.538147 L 187.8 0.46646 L 186.8 0.410402 L 185.8 0.328747 L 184.8 0.273173 L 183.8 0.188865 L 182.8 0.14624 L 181.8 0.055234 L 180.8 -0.005051 L 179.8 -0.110128 L 178.8 -0.174313 L 177.8 -0.253509 L 176.8 -0.319736 L 175.8 -0.374012 L 174.8 -0.407139 L 173.8 -0.463853 L 172.8 -0.50741 L 171.8 -0.604653 L 170.8 -0.678599 L 169.8 -0.740393 L 168.8 -0.768808 L 167.8 -0.794142 L 166.8 -0.860397 L 165.8 -0.903414 L 164.8 -0.931921 L 163.8 -0.943915 L 162.8 -0.957989 L 161.8 -0.968817 L 160.8 -0.984115 L 159.8 -0.993971 L 158.8 -0.999784 L 157.8 -0.998949 L 156.8 -0.996987 L 155.8 -0.993379 L 154.8 -0.976068 L 153.8 -0.966337 L 152.8 -0.932307 L 151.8 -0.907236 L 150.8 -0.868539 L 149.8 -0.802605 L 148.8 -0.761617 L 147.8 -0.686776 L 146.8 -0.654849 L 145.8 -0.630635 L 144.8 -0.604815 L 143.8 -0.545775 L 142.8 -0.491063 L 141.8 -0.384861 L 140.8 -0.304585 L 139.8 -0.187843 L 138.8 -0.08788 L 137.8 -0.035566 L 136.8 0.003007 L 135.8 0.039368 L 134.8 0.160354 L 133.8 0.191539 L 132.8 0.227915 L 131.8 0.290066 L 130.8 0.378077 L 129.8 0.42247 L 128.8 0.470988 L 127.8 0.569778 L 126.8 0.611246 L 125.8 0.653898 L 124.8 0.718748 L 123.8 0.785183 L 122.8 0.805272 L 121.8 0.829751 L 120.8 0.870359 L 119.8 0.894905 L 118.8 0.911852 L 117.8 0.942871 L 116.8 0.965923 L 115.8 0.985366 L 114.8 0.992773 L 113.8 0.996995 L 112.8 0.999656 L 111.8 0.999239 L 110.8 0.993894 L 109.8 0.984738 L 108.8 0.972213 L 107.8 0.945446 L 106.8 0.91655 L 105.8 0.86624 L 104.8 0.837897 L 103.8 0.782994 L 102.8 0.745187 L 101.8 0.692498 L 100.8 0.662794 L 99.8 0.631793 L 98.8 0.601321 L 97.8 0.559084 L 96.8 0.531062 L 95.8 0.433515 L 94.8 0.35707 L 93.8 0.301773 L 92.8 0.220903 L 91.8 0.143522 L 90.8 0.062112 L 89.8 0.005147 L 88.8 -0.117966 L 87.8 -0.149535 L 86.8 -0.216766 L 85.8 -0.295058 L 84.8 -0.387611 L 83.8 -0.421765 L 82.8 -0.452679 L 81.8 -0.503004 L 80.8 -0.547822 L 79.8 -0.588823 L 78.8 -0.618678 L 77.8 -0.663526 L 76.8 -0.74679 L 75.8 -0.76885 L 74.8 -0.812967 L 73.8 -0.833129 L 72.8 -0.893251 L 71.8 -0.93548 L 70.8 -0.958737 L 69.8 -0.976732 L 68.8 -0.983734 L 67.8 -0.995973 L 66.8 -0.999442 L 65.8 -0.998259 L 64.8 -0.994084 L 63.8 -0.980354 L 62.8 -0.972703 L 61.8 -0.958263 L 60.8 -0.927611 L 59.8 -0.902922 L 58.8 -0.882675 L 57.8 -0.864202 L 56.8 -0.845248 L 55.8 -0.810642 L 54.8 -0.743359 L 53.8 -0.695131 L 52.8 -0.665749 L 51.8 -0.633906 L 50.8 -0.555682 L 49.8 -0.45647 L 48.8 -0.412576 L 47.8 -0.301816 L 46.8 -0.248043 L 45.8 -0.189835 L 44.8 -0.153658 L 43.8 -0.098867 L 42.8 -0.015916 L 41.8 0.031754 L 40.8 0.120599 L 39.8 0.168247 L 38.8 0.248469 L 37.8 0.337896 L 36.8 0.382122 L 35.8 0.441179 L 34.8 0.539628 L 33.8 0.57467 L 32.8 0.620434 L 31.8 0.673635 L 30.8 0.709483 L 29.8 0.751738 L 28.8 0.793097 L 27.8 0.820445 L 26.8 0.88147 L 25.8 0.904483 L 24.8 0.919261 L 23.8 0.934284 L 22.8 0.947208 L 21.8 0.979534 L 20.8 0.996802 L 19.8 0.999844 L 18.8 0.997823 L 17.8 0.99401 L 16.8 0.978994 L 15.8 0.970072 L 14.8 0.95778 L 13.8 0.929404 L 12.8 0.901094 L 11.8 0.866107 L 10.8 0.813717 L 9.8 0.765101 L 8.8 0.721134 L 7.8 0.682742 L 6.8 0.590438 L 5.8 0.563187 L 4.8 0.517238 L 3.8 0.475854 L 2.8 0.436431 L 1.8 0.377515 L 0 0.273593 L 0.227262 1 L 0.140289 2 L 0.091558 3 L 0.053928 4 L 0.017733 5 L -0.06793 6 L -0.161753 7 L -0.273189 8 L -0.360274 9 L -0.40709 10 L -0.463838 11 L -0.531601 12 L -0.573508 13 L -0.625352 14 L -0.650645 15 L -0.724163 16 L -0.770317 17 L -0.791479 18 L -0.851149 19 L -0.887991 20 L -0.917061 21 L -0.941292 22 L -0.951546 23 L -0.981839 24 L -0.994579 25 L -0.999784 26 L -0.999825 27 L -0.998417 28 L -0.992654 29 L -0.986301 30 L -0.967662 31 L -0.943214 32 L -0.912437 33 L -0.895086 34 L -0.880479 35 L -0.851999 36 L -0.833049 37 L -0.804776 38 L -0.736949 39 L -0.694852 40 L -0.659088 41 L -0.608192 42 L -0.546144 43 L -0.469078 44 L -0.390646 45 L -0.314256 46 L -0.272519 47 L -0.174586 48 L -0.104796 49 L -0.033939 50 L 0.084549 51 L 0.122597 52 L 0.158643 53 L 0.20132 54 L 0.299241 55 L 0.371531 56 L 0.414118 57 L 0.451421 58 L 0.546295 59 L 0.588994 60 L 0.621715 61 L 0.647784 62 L 0.677809 63 L 0.707013 64 L 0.742447 65 L 0.763133 66 L 0.785911 67 L 0.848282 68 L 0.876933 69 L 0.89743 70 L 0.932584 71 L 0.952705 72 L 0.963835 73 L 0.983785 74 L 0.997162 75 L 0.998974 76 L 0.993744 77 L 0.987133 78 L 0.961107 79 L 0.93948 80 L 0.917584 81 L 0.899066 82 L 0.868853 83 L 0.826455 84 L 0.799415 85 L 0.778893 86 L 0.743514 87 L 0.655618 88 L 0.618638 89 L 0.545793 90 L 0.443104 91 L 0.409892 92 L 0.309442 93 L 0.277702 94 L 0.234758 95 L 0.200953 96 L 0.120665 97 L 0.086322 98 L 0.0144 99 L -0.061467 100 L -0.117562 101 L -0.207304 102 L -0.24726 103 L -0.314957 104 L -0.42911 105 L -0.460269 106 L -0.525752 107 L -0.557786 108 L -0.642979 109 L -0.673037 110 L -0.719408 111 L -0.749116 112 L -0.778759 113 L -0.843855 114 L -0.877651 115 L -0.902804 116 L -0.918897 117 L -0.955058 118 L -0.973964 119 L -0.984187 120 L -0.992492 121 L -0.999215 122 L -0.996501 123 L -0.988797 124 L -0.971166 125 L -0.940938 126 L -0.912341 127 L -0.885031 128 L -0.825603 129 L -0.77009 130 L -0.688452 131 L -0.647196 132 L -0.60259 133 L -0.511042 134 L -0.430427 135 L -0.384469 136 L -0.292923 137 L -0.225967 138 L -0.179248 139 L -0.136118 140 L -0.077875 141 L -0.030604 142 L 0.026452 143 L 0.080989 144 L 0.196427 145 L 0.315576 146 L 0.370627 147 L 0.40698 148 L 0.502034 149 L 0.546466 150 L 0.575573 151 L 0.667237 152 L 0.714029 153 L 0.749742 154 L 0.795559 155 L 0.859505 156 L 0.892455 157 L 0.917515 158 L 0.933607 159 L 0.970088 160 L 0.979122 161 L 0.985274 162 L 0.990848 163 L 0.99806 164 L 0.99889 165 L 0.994277 166 L 0.981883 167 L 0.973583 168 L 0.937803 169 L 0.919049 170 L 0.901448 171 L 0.87707 172 L 0.844234 173 L 0.771924 174 L 0.735339 175 L 0.713128 176 L 0.683072 177 L 0.643552 178 L 0.614091 179 L 0.569454 180 L 0.500184 181 L 0.392301 182 L 0.355195 183 L 0.247165 184 L 0.140245 185 L 0.103559 186 L 0.051805 187 L -0.035129 188 L -0.106027 189 L -0.227181 190 L -0.260107 191 L -0.313632 192 L -0.359984 193 L -0.401339 194 L -0.450067 195 L -0.490327 196 L -0.533979 197 L -0.560575 198 L -0.651745 199 L -0.691652 200 L -0.720319 201 L -0.762616 202 L -0.811738 203 L -0.865675 204 L -0.918013 205 L -0.952001 206 L -0.967156 207 L -0.980387 208 L -0.992416 209 L -0.998222 210 L -0.99846 211 L -0.995029 212 L -0.978361 213 L -0.950969 214 L -0.910428 215 L -0.890133 216 L -0.872536 217 L -0.847806 218 L -0.794595 219 L -0.753623 220 L -0.693228 221 L -0.609661 222 L -0.563669 223 L -0.532753 224 L -0.502298 225 L -0.455614 226 L -0.387673 227 L -0.355756 228 L -0.30615 229 L -0.205734 230 L -0.170513 231 L -0.129026 232 L -0.0754 233 L -0.035334 234 L 0.07453 235 L 0.195709 236 L 0.233871 237 L 0.303602 238 L 0.362359 239 L 0.415477 240 L 0.479944 241 L 0.522985 242 L 0.587131 243 L 0.631929 244 L 0.71055 245 L 0.733761 246 L 0.756219 247 L 0.826066 248 L 0.846169 249 L 0.872053 250 L 0.895656 251 L 0.909427 252 L 0.933238 253 L 0.968289 254 L 0.987905 255 L 0.997925 256 L 0.999511 257 L 0.997397 258 L 0.994191 259 L 0.987806 260 L 0.972822 261 L 0.963505 262 L 0.943913 263 L 0.912031 264 L 0.858743 265 L 0.824485 266 L 0.803278 267 L 0.770858 268 L 0.745139 269 L 0.704247 270 L 0.679944 271 L 0.652386 272 L 0.613312 273 L 0.574818 274 L 0.521172 275 L 0.478431 276 L 0.446006 277 L 0.408082 278 L 0.378531 279 L 0.304491 280 L 0.26975 281 L 0.198648 282 L 0.140692 283 L 0.106477 284 L 0.001931 285 L -0.031948 286 L -0.139586 287 L -0.197401 288 L -0.263521 289 L -0.338446 290 L -0.397233 291 L -0.504686 292 L -0.600611 293 L -0.660743 294 L -0.694963 295 L -0.772666 296 L -0.810252 297 L -0.853431 298 L -0.881952 299 L -0.917155 300 L -0.941985 301 L -0.967909 302 L -0.983386 303 L -0.988682 304 L -0.999195 305 L -0.999894 306 L -0.998307 307 L -0.983759 308 L -0.976299 309 L -0.949036 310 L -0.904736 311 L -0.887316 312 L -0.847912 313 L -0.811558 314 L -0.773772 315 L -0.719976 316 L -0.6736 317 L -0.625248 318 L -0.57127 319 L -0.507815 320 L -0.41649 321 L -0.374633 322 L -0.343546 323 L -0.27172 324 L -0.238363 325 L -0.204546 326 L -0.16887 327 L -0.085534 328 L -0.053624 329 L 0.040791 330 L 0.163353 331 L 0.248217 332 L 0.307634 333 L 0.341295 334 L 0.436499 335 L 0.466063 336 L 0.500969 337 L 0.532344 338 L 0.629809 339 L 0.655764 340 L 0.706154 341 L 0.736458 342 L 0.792812 343 L 0.811609 344 L 0.857562 345.6 z " + style="fill: #ffffff" + id="path2" /> + </g> + <g + id="axes_1"> + <g + id="patch_2"> + <path + d="M 57.6 307.584 L 58.6 307.615436 L 59.6 307.652377 L 60.6 307.750123 L 61.6 307.782645 L 62.6 307.85627 L 63.6 307.894835 L 64.6 307.930248 L 65.6 307.987888 L 66.6 308.058274 L 67.6 308.110239 L 68.6 308.169328 L 69.6 308.257649 L 70.6 308.303794 L 71.6 308.346205 L 72.6 308.376697 L 73.6 308.402742 L 74.6 308.423942 L 75.6 308.478243 L 76.6 308.506181 L 77.6 308.535905 L 78.6 308.5613 L 79.6 308.5725 L 80.6 308.582624 L 81.6 308.58242 L 82.6 308.57291 L 83.6 308.561256 L 84.6 308.530227 L 85.6 308.519059 L 86.6 308.488942 L 87.6 308.429165 L 88.6 308.391973 L 89.6 308.352877 L 90.6 308.310437 L 91.6 308.277672 L 92.6 308.210246 L 93.6 308.17112 L 94.6 308.128445 L 95.6 308.057865 L 96.6 308.021474 L 97.6 307.963071 L 98.6 307.852118 L 99.6 307.78146 L 100.6 307.66852 L 101.6 307.622747 L 102.6 307.561464 L 103.6 307.512965 L 104.6 307.432142 L 105.6 307.313623 L 106.6 307.243412 L 107.6 307.16015 L 108.6 307.127008 L 109.6 307.075771 L 110.6 307.007372 L 111.6 306.941157 L 112.6 306.86424 L 113.6 306.836924 L 114.6 306.810447 L 115.6 306.787796 L 116.6 306.768265 L 117.6 306.741871 L 118.6 306.6921 L 119.6 306.657027 L 120.6 306.621161 L 121.6 306.605794 L 122.6 306.590025 L 123.6 306.586612 L 124.6 306.584195 L 125.6 306.584681 L 126.6 306.58661 L 127.6 306.599867 L 128.6 306.608258 L 129.6 306.629794 L 130.6 306.652827 L 131.6 306.67006 L 132.6 306.688523 L 133.6 306.708975 L 134.6 306.725575 L 135.6 306.788354 L 136.6 306.863619 L 137.6 306.896258 L 138.6 306.963822 L 139.6 307.017869 L 140.6 307.051573 L 141.6 307.141699 L 142.6 307.170234 L 143.6 307.20172 L 144.6 307.232731 L 145.6 307.287539 L 146.6 307.352126 L 147.6 307.390322 L 148.6 307.486256 L 149.6 307.535514 L 150.6 307.579583 L 151.6 307.619707 L 152.6 307.728074 L 153.6 307.769702 L 154.6 307.831844 L 155.6 307.901806 L 156.6 308.00631 L 157.6 308.043298 L 158.6 308.089175 L 159.6 308.15767 L 160.6 308.206416 L 161.6 308.284013 L 162.6 308.314554 L 163.6 308.384068 L 164.6 308.408041 L 165.6 308.436663 L 166.6 308.478456 L 167.6 308.500032 L 168.6 308.51398 L 169.6 308.540702 L 170.6 308.550012 L 171.6 308.562459 L 172.6 308.573514 L 173.6 308.579178 L 174.6 308.583942 L 175.6 308.578394 L 176.6 308.565106 L 177.6 308.557589 L 178.6 308.532804 L 179.6 308.509235 L 180.6 308.473055 L 181.6 308.447093 L 182.6 308.424771 L 183.6 308.356011 L 184.6 308.281476 L 185.6 308.187497 L 186.6 308.136445 L 187.6 308.082511 L 188.6 308.04726 L 189.6 307.941172 L 190.6 307.888908 L 191.6 307.852001 L 192.6 307.82097 L 193.6 307.759815 L 194.6 307.692395 L 195.6 307.643489 L 196.6 307.578297 L 197.6 307.540109 L 198.6 307.498113 L 199.6 307.456096 L 200.6 307.39658 L 201.6 307.28342 L 202.6 307.231169 L 203.6 307.191751 L 204.6 307.14465 L 205.6 307.08787 L 206.6 307.055207 L 207.6 307.019029 L 208.6 306.986939 L 209.6 306.952659 L 210.6 306.894281 L 211.6 306.849096 L 212.6 306.819472 L 213.6 306.769086 L 214.6 306.743889 L 215.6 306.722838 L 216.6 306.68787 L 217.6 306.66358 L 218.6 306.649513 L 219.6 306.630571 L 220.6 306.61491 L 221.6 306.602358 L 222.6 306.596522 L 223.6 306.58964 L 224.6 306.584466 L 225.6 306.586249 L 226.6 306.588974 L 227.6 306.600128 L 228.6 306.628363 L 229.6 306.672151 L 230.6 306.69284 L 231.6 306.733813 L 232.6 306.773888 L 233.6 306.792998 L 234.6 306.815507 L 235.6 306.882158 L 236.6 306.931868 L 237.6 307.005574 L 238.6 307.036888 L 239.6 307.11351 L 240.6 307.151808 L 241.6 307.225925 L 242.6 307.329983 L 243.6 307.399814 L 244.6 307.505048 L 245.6 307.560063 L 246.6 307.683538 L 247.6 307.754097 L 248.6 307.869936 L 249.6 307.920117 L 250.6 307.955721 L 251.6 308.047128 L 252.6 308.100636 L 253.6 308.188544 L 254.6 308.257729 L 255.6 308.304493 L 256.6 308.376537 L 257.6 308.426679 L 258.6 308.444069 L 259.6 308.471072 L 260.6 308.490499 L 261.6 308.509837 L 262.6 308.548086 L 263.6 308.564519 L 264.6 308.572888 L 265.6 308.577207 L 266.6 308.583762 L 267.6 308.581216 L 268.6 308.575757 L 269.6 308.559329 L 270.6 308.527394 L 271.6 308.489414 L 272.6 308.45461 L 273.6 308.391538 L 274.6 308.370111 L 275.6 308.319493 L 276.6 308.294536 L 277.6 308.238902 L 278.6 308.207673 L 279.6 308.157529 L 280.6 308.125036 L 281.6 308.044624 L 282.6 307.975698 L 283.6 307.860001 L 284.6 307.784522 L 285.6 307.668997 L 286.6 307.589513 L 287.6 307.481072 L 288.6 307.441704 L 289.6 307.338836 L 290.6 307.239038 L 291.6 307.193541 L 292.6 307.159219 L 293.6 307.107263 L 294.6 307.067616 L 295.6 307.032102 L 296.6 306.964457 L 297.6 306.925375 L 298.6 306.874894 L 299.6 306.825588 L 300.6 306.774518 L 301.6 306.730279 L 302.6 306.708259 L 303.6 306.692703 L 304.6 306.650256 L 305.6 306.635388 L 306.6 306.61266 L 307.6 306.592344 L 308.6 306.586547 L 309.6 306.584065 L 310.6 306.587122 L 311.6 306.598718 L 312.6 306.615638 L 313.6 306.647299 L 314.6 306.661382 L 315.6 306.714054 L 316.6 306.763143 L 317.6 306.817844 L 318.6 306.862192 L 319.6 306.932184 L 320.6 306.982567 L 321.6 307.036474 L 322.6 307.105913 L 323.6 307.163301 L 324.6 307.213466 L 325.6 307.290628 L 326.6 307.348818 L 327.6 307.409456 L 328.6 307.446657 L 329.6 307.511749 L 330.6 307.616879 L 331.6 307.677181 L 332.6 307.773503 L 333.6 307.805506 L 334.6 307.856523 L 335.6 307.973315 L 336.6 308.008762 L 337.6 308.064642 L 338.6 308.095018 L 339.6 308.183404 L 340.6 308.228168 L 341.6 308.309056 L 342.6 308.369202 L 343.6 308.432288 L 344.6 308.455236 L 345.6 308.471406 L 346.6 308.500335 L 347.6 308.530687 L 348.6 308.543261 L 349.6 308.56814 L 350.6 308.580224 L 351.6 308.583986 L 352.6 308.57955 L 353.6 308.567211 L 354.6 308.552798 L 355.6 308.536725 L 356.6 308.501204 L 357.6 308.48127 L 358.6 308.424681 L 359.6 308.357487 L 360.6 308.330117 L 361.6 308.295969 L 362.6 308.247289 L 363.6 308.199004 L 364.6 308.139927 L 365.6 308.044322 L 366.6 308.001182 L 367.6 307.951334 L 368.6 307.8928 L 369.6 307.845214 L 370.6 307.784086 L 371.6 307.728001 L 372.6 307.65383 L 373.6 307.536592 L 374.6 307.480868 L 375.6 307.372642 L 376.6 307.266492 L 377.6 307.15892 L 378.6 307.124412 L 379.6 307.021105 L 380.6 306.945381 L 381.6 306.905946 L 382.6 306.866562 L 383.6 306.84408 L 384.6 306.788267 L 385.6 306.762215 L 386.6 306.73198 L 387.6 306.681209 L 388.6 306.662558 L 389.6 306.640849 L 390.6 306.628203 L 391.6 306.60921 L 392.6 306.59182 L 393.6 306.584782 L 394.6 306.585806 L 395.6 306.59281 L 396.6 306.60218 L 397.6 306.625578 L 398.6 306.650661 L 399.6 306.66306 L 400.6 306.696153 L 401.6 306.71252 L 402.6 306.730925 L 403.6 306.780062 L 404.6 306.823875 L 405.6 306.86696 L 406.6 306.889901 L 407.6 306.930164 L 408.6 307.015024 L 409.6 307.057416 L 410.6 307.121802 L 411.6 307.166091 L 412.6 307.273937 L 413.6 307.350877 L 414.72 307.387319 L 414.578206 306.584 L 414.653307 305.584 L 414.711902 304.584 L 414.748477 303.584 L 414.860524 302.584 L 414.922209 301.584 L 414.972729 300.584 L 415.071514 299.584 L 415.109536 298.584 L 415.144984 297.584 L 415.236618 296.584 L 415.27989 295.584 L 415.333219 294.584 L 415.366084 293.584 L 415.428978 292.584 L 415.482832 291.584 L 415.539958 290.584 L 415.562048 289.584 L 415.605787 288.584 L 415.652881 287.584 L 415.669728 286.584 L 415.697802 285.584 L 415.708798 284.584 L 415.713367 283.584 L 415.719015 282.584 L 415.719066 281.584 L 415.715976 280.584 L 415.712463 279.584 L 415.706641 278.584 L 415.693789 277.584 L 415.670164 276.584 L 415.65528 275.584 L 415.631708 274.584 L 415.595389 273.584 L 415.563806 272.584 L 415.533913 271.584 L 415.455221 270.584 L 415.41867 269.584 L 415.392947 268.584 L 415.322274 267.584 L 415.231172 266.584 L 415.169215 265.584 L 415.135602 264.584 L 415.101102 263.584 L 415.003662 262.584 L 414.956072 261.584 L 414.924566 260.584 L 414.880881 259.584 L 414.810712 258.584 L 414.760845 257.584 L 414.726168 256.584 L 414.61652 255.584 L 414.583049 254.584 L 414.545707 253.584 L 414.465462 252.584 L 414.426968 251.584 L 414.385191 250.584 L 414.342766 249.584 L 414.233038 248.584 L 414.144753 247.584 L 414.070107 246.584 L 413.98165 245.584 L 413.907588 244.584 L 413.858423 243.584 L 413.802806 242.584 L 413.768106 241.584 L 413.756235 240.584 L 413.734012 239.584 L 413.722033 238.584 L 413.720281 237.584 L 413.725698 236.584 L 413.741896 235.584 L 413.758396 234.584 L 413.789579 233.584 L 413.802944 232.584 L 413.832587 231.584 L 413.89561 230.584 L 413.944931 229.584 L 413.99102 228.584 L 414.073247 227.584 L 414.11915 226.584 L 414.153475 225.584 L 414.207014 224.584 L 414.295901 223.584 L 414.327039 222.584 L 414.435088 221.584 L 414.54716 220.584 L 414.582598 219.584 L 414.667384 218.584 L 414.732991 217.584 L 414.835045 216.584 L 414.95126 215.584 L 414.991951 214.584 L 415.03304 213.584 L 415.069681 212.584 L 415.110677 211.584 L 415.186746 210.584 L 415.262812 209.584 L 415.2935 208.584 L 415.319991 207.584 L 415.376572 206.584 L 415.421088 205.584 L 415.451106 204.584 L 415.478162 203.584 L 415.520727 202.584 L 415.573592 201.584 L 415.604513 200.584 L 415.630788 199.584 L 415.645721 198.584 L 415.67601 197.584 L 415.697339 196.584 L 415.714228 195.584 L 415.718943 194.584 L 415.719553 193.584 L 415.717507 192.584 L 415.711646 191.584 L 415.692999 190.584 L 415.660942 189.584 L 415.614502 188.584 L 415.572556 187.584 L 415.505851 186.584 L 415.436785 185.584 L 415.38941 184.584 L 415.337891 183.584 L 415.298191 182.584 L 415.228771 181.584 L 415.16224 180.584 L 415.053331 179.584 L 414.988083 178.584 L 414.879875 177.584 L 414.818871 176.584 L 414.770186 175.584 L 414.693952 174.584 L 414.634421 173.584 L 414.559793 172.584 L 414.440966 171.584 L 414.343021 170.584 L 414.263973 169.584 L 414.218226 168.584 L 414.190954 167.584 L 414.147292 166.584 L 414.098708 165.584 L 414.066974 164.584 L 413.986744 163.584 L 413.920251 162.584 L 413.896226 161.584 L 413.835727 160.584 L 413.813495 159.584 L 413.794895 158.584 L 413.765569 157.584 L 413.749868 156.584 L 413.741569 155.584 L 413.731333 154.584 L 413.72099 153.584 L 413.721668 152.584 L 413.725448 151.584 L 413.741889 150.584 L 413.754023 149.584 L 413.764618 148.584 L 413.795995 147.584 L 413.821768 146.584 L 413.853177 145.584 L 413.875986 144.584 L 413.89358 143.584 L 413.943392 142.584 L 413.991052 141.584 L 414.062761 140.584 L 414.118524 139.584 L 414.144722 138.584 L 414.17549 137.584 L 414.265248 136.584 L 414.350042 135.584 L 414.415636 134.584 L 414.461461 133.584 L 414.504458 132.584 L 414.565971 131.584 L 414.665796 130.584 L 414.710226 129.584 L 414.760276 128.584 L 414.882117 127.584 L 414.94181 126.584 L 414.973376 125.584 L 415.005719 124.584 L 415.060279 123.584 L 415.102779 122.584 L 415.154251 121.584 L 415.242636 120.584 L 415.276833 119.584 L 415.320767 118.584 L 415.38448 117.584 L 415.459677 116.584 L 415.488491 115.584 L 415.530695 114.584 L 415.57328 113.584 L 415.590172 112.584 L 415.612653 111.584 L 415.65499 110.584 L 415.68495 109.584 L 415.703583 108.584 L 415.713375 107.584 L 415.717138 106.584 L 415.719976 105.584 L 415.718227 104.584 L 415.708871 103.584 L 415.698174 102.584 L 415.688304 101.584 L 415.669446 100.584 L 415.639107 99.584 L 415.600716 98.584 L 415.54123 97.584 L 415.497941 96.584 L 415.437203 95.584 L 415.353129 94.584 L 415.304836 93.584 L 415.261259 92.584 L 415.234378 91.584 L 415.202448 90.584 L 415.135256 89.584 L 415.054435 88.584 L 414.97889 87.584 L 414.93516 86.584 L 414.855265 85.584 L 414.793786 84.584 L 414.730161 83.584 L 414.622912 82.584 L 414.504202 81.584 L 414.462296 80.584 L 414.419342 79.584 L 414.357143 78.584 L 414.327006 77.584 L 414.294488 76.584 L 414.242553 75.584 L 414.137003 74.584 L 414.088557 73.584 L 414.042233 72.584 L 414.008417 71.584 L 413.96054 70.584 L 413.905662 69.584 L 413.881751 68.584 L 413.855714 67.584 L 413.799597 66.584 L 413.785723 65.584 L 413.759689 64.584 L 413.732943 63.584 L 413.725197 62.584 L 413.720044 61.584 L 413.726242 60.584 L 413.732549 59.584 L 413.74013 58.584 L 413.767636 57.584 L 413.811869 56.584 L 413.841407 55.584 L 413.883254 54.584 L 413.942428 53.584 L 413.965138 52.584 L 414.00177 51.584 L 414.058558 50.584 L 414.083728 49.584 L 414.166424 48.584 L 414.253356 47.584 L 414.30404 46.584 L 414.341434 45.584 L 414.425814 44.584 L 414.460325 43.584 L 414.552316 42.584 L 414.639341 41.472 L 413.72 41.429519 L 412.72 41.39165 L 411.72 41.344175 L 410.72 41.238649 L 409.72 41.141188 L 408.72 41.064551 L 407.72 41.032624 L 406.72 40.978384 L 405.72 40.939533 L 404.72 40.865828 L 403.72 40.833832 L 402.72 40.777293 L 401.72 40.741177 L 400.72 40.672575 L 399.72 40.641159 L 398.72 40.586492 L 397.72 40.567721 L 396.72 40.522092 L 395.72 40.499189 L 394.72 40.490648 L 393.72 40.483307 L 392.72 40.477012 L 391.72 40.473835 L 390.72 40.472249 L 389.72 40.473712 L 388.72 40.486666 L 387.72 40.501288 L 386.72 40.513144 L 385.72 40.531169 L 384.72 40.551547 L 383.72 40.574946 L 382.72 40.589855 L 381.72 40.644569 L 380.72 40.678166 L 379.72 40.740862 L 378.72 40.768237 L 377.72 40.812217 L 376.72 40.891164 L 375.72 40.948692 L 374.72 40.998671 L 373.72 41.070655 L 372.72 41.107187 L 371.72 41.1755 L 370.72 41.263706 L 369.72 41.385053 L 368.72 41.450734 L 367.72 41.484352 L 366.72 41.548629 L 365.72 41.5946 L 364.72 41.666757 L 363.72 41.706583 L 362.72 41.749213 L 361.72 41.855172 L 360.72 41.907957 L 359.72 41.987234 L 358.72 42.029638 L 357.72 42.061904 L 356.72 42.09677 L 355.72 42.139428 L 354.72 42.171001 L 353.72 42.23858 L 352.72 42.275465 L 351.72 42.303421 L 350.72 42.324269 L 349.72 42.349882 L 348.72 42.3875 L 347.72 42.402342 L 346.72 42.427072 L 345.72 42.445302 L 344.72 42.456709 L 343.72 42.462344 L 342.72 42.467098 L 341.72 42.471707 L 340.72 42.470034 L 339.72 42.464252 L 338.72 42.444256 L 337.72 42.432604 L 336.72 42.421615 L 335.72 42.408648 L 334.72 42.358234 L 333.72 42.337412 L 332.72 42.309465 L 331.72 42.25272 L 330.72 42.230076 L 329.72 42.178673 L 328.72 42.137537 L 327.72 42.054768 L 326.72 42.006308 L 325.72 41.954881 L 324.72 41.903721 L 323.72 41.836422 L 322.72 41.803268 L 321.72 41.73721 L 320.72 41.681025 L 319.72 41.619746 L 318.72 41.579763 L 317.72 41.48334 L 316.72 41.37158 L 315.72 41.332661 L 314.72 41.234812 L 313.72 41.200158 L 312.72 41.116476 L 311.72 41.06597 L 310.72 40.996927 L 309.72 40.895824 L 308.72 40.843378 L 307.72 40.75407 L 306.72 40.689062 L 305.72 40.647517 L 304.72 40.605177 L 303.72 40.583157 L 302.72 40.54567 L 301.72 40.528418 L 300.72 40.50501 L 299.72 40.496443 L 298.72 40.487354 L 297.72 40.480286 L 296.72 40.473259 L 295.72 40.472151 L 294.72 40.472137 L 293.72 40.474811 L 292.72 40.477837 L 291.72 40.483304 L 290.72 40.503299 L 289.72 40.51527 L 288.72 40.542389 L 287.72 40.569401 L 286.72 40.596567 L 285.72 40.651042 L 284.72 40.680658 L 283.72 40.722414 L 282.72 40.795523 L 281.72 40.838961 L 280.72 40.909652 L 279.72 40.948059 L 278.72 41.008398 L 277.72 41.039153 L 276.72 41.069651 L 275.72 41.128561 L 274.72 41.171738 L 273.72 41.21335 L 272.72 41.262465 L 271.72 41.327552 L 270.72 41.393947 L 269.72 41.51871 L 268.72 41.562525 L 267.72 41.616853 L 266.72 41.723557 L 265.72 41.766057 L 264.72 41.803551 L 263.72 41.893047 L 262.72 41.95027 L 261.72 42.019913 L 260.72 42.068932 L 259.72 42.124877 L 258.72 42.172002 L 257.72 42.21089 L 256.72 42.264582 L 255.72 42.310153 L 254.72 42.34709 L 253.72 42.369166 L 252.72 42.402049 L 251.72 42.431769 L 250.72 42.444319 L 249.72 42.456218 L 248.72 42.461336 L 247.72 42.469225 L 246.72 42.471856 L 245.72 42.471058 L 244.72 42.467817 L 243.72 42.452679 L 242.72 42.445742 L 241.72 42.429365 L 240.72 42.410952 L 239.72 42.38136 L 238.72 42.359278 L 237.72 42.301584 L 236.72 42.276393 L 235.72 42.20808 L 234.72 42.160954 L 233.72 42.123606 L 232.72 42.068397 L 231.72 41.978966 L 230.72 41.875856 L 229.72 41.821882 L 228.72 41.791162 L 227.72 41.735621 L 226.72 41.697886 L 225.72 41.629632 L 224.72 41.593803 L 223.72 41.524019 L 222.72 41.464725 L 221.72 41.426118 L 220.72 41.392122 L 219.72 41.349542 L 218.72 41.302893 L 217.72 41.248327 L 216.72 41.162426 L 215.72 41.11575 L 214.72 41.058435 L 213.72 41.028021 L 212.72 40.94297 L 211.72 40.909295 L 210.72 40.821371 L 209.72 40.766386 L 208.72 40.727697 L 207.72 40.657666 L 206.72 40.62722 L 205.72 40.569495 L 204.72 40.552351 L 203.72 40.527616 L 202.72 40.512116 L 201.72 40.488664 L 200.72 40.48185 L 199.72 40.477917 L 198.72 40.474185 L 197.72 40.472152 L 196.72 40.480538 L 195.72 40.496924 L 194.72 40.523194 L 193.72 40.536523 L 192.72 40.566477 L 191.72 40.600728 L 190.72 40.621398 L 189.72 40.66241 L 188.72 40.735728 L 187.72 40.758946 L 186.72 40.799312 L 185.72 40.826563 L 184.72 40.907101 L 183.72 40.960579 L 182.72 41.03915 L 181.72 41.087618 L 180.72 41.201648 L 179.72 41.302333 L 178.72 41.386757 L 177.72 41.478297 L 176.72 41.58071 L 175.72 41.621518 L 174.72 41.664661 L 173.72 41.703962 L 172.72 41.737385 L 171.72 41.780493 L 170.72 41.886072 L 169.72 41.941773 L 168.72 42.0471 L 167.72 42.144097 L 166.72 42.167117 L 165.72 42.194104 L 164.72 42.224205 L 163.72 42.297447 L 162.72 42.334839 L 161.72 42.369798 L 160.72 42.388374 L 159.72 42.41888 L 158.72 42.431092 L 157.72 42.440868 L 156.72 42.450437 L 155.72 42.458646 L 154.72 42.469922 L 153.72 42.471784 L 152.72 42.465482 L 151.72 42.459469 L 150.72 42.454012 L 149.72 42.43382 L 148.72 42.423931 L 147.72 42.396178 L 146.72 42.377171 L 145.72 42.361772 L 144.72 42.332507 L 143.72 42.268703 L 142.72 42.21965 L 141.72 42.149461 L 140.72 42.120352 L 139.72 42.060782 L 138.72 42.013833 L 137.72 41.962711 L 136.72 41.908658 L 135.72 41.826971 L 134.72 41.748314 L 133.72 41.711654 L 132.72 41.59 L 131.72 41.511058 L 130.72 41.446567 L 129.72 41.400939 L 128.72 41.28529 L 127.72 41.237015 L 126.72 41.201492 L 125.72 41.157914 L 124.72 41.122138 L 123.72 41.051313 L 122.72 41.014909 L 121.72 40.917433 L 120.72 40.848369 L 119.72 40.782403 L 118.72 40.717873 L 117.72 40.694451 L 116.72 40.667046 L 115.72 40.618552 L 114.72 40.588559 L 113.72 40.556021 L 112.72 40.541278 L 111.72 40.527738 L 110.72 40.504303 L 109.72 40.491823 L 108.72 40.484685 L 107.72 40.479087 L 106.72 40.473481 L 105.72 40.472 L 104.72 40.477993 L 103.72 40.483958 L 102.72 40.49547 L 101.72 40.519277 L 100.72 40.52941 L 99.72 40.571368 L 98.72 40.61344 L 97.72 40.644656 L 96.72 40.714514 L 95.72 40.75877 L 94.72 40.84124 L 93.72 40.929427 L 92.72 40.974347 L 91.72 41.070077 L 90.72 41.142181 L 89.72 41.237171 L 88.72 41.293545 L 87.72 41.337742 L 86.72 41.393558 L 85.72 41.433496 L 84.72 41.508947 L 83.72 41.566942 L 82.72 41.604129 L 81.72 41.662656 L 80.72 41.765433 L 79.72 41.82216 L 78.72 41.893165 L 77.72 41.954934 L 76.72 41.992397 L 75.72 42.027683 L 74.72 42.071101 L 73.72 42.11296 L 72.72 42.140583 L 71.72 42.191698 L 70.72 42.225234 L 69.72 42.287297 L 68.72 42.306939 L 67.72 42.368712 L 66.72 42.391191 L 65.72 42.411414 L 64.72 42.432103 L 63.72 42.45853 L 62.72 42.469487 L 61.72 42.471269 L 60.72 42.468641 L 59.72 42.462091 L 58.72 42.440128 L 57.6 42.401128 L 58.508845 42.472 L 58.492196 43.472 L 58.430573 44.472 L 58.401989 45.472 L 58.378481 46.472 L 58.334033 47.472 L 58.30807 48.472 L 58.25771 49.472 L 58.181318 50.472 L 58.153797 51.472 L 58.121939 52.472 L 58.086315 53.472 L 57.998542 54.472 L 57.901531 55.472 L 57.821578 56.472 L 57.703903 57.472 L 57.631909 58.472 L 57.527743 59.472 L 57.416434 60.472 L 57.321012 61.472 L 57.226115 62.472 L 57.159096 63.472 L 57.098211 64.472 L 57.05375 65.472 L 57.018079 66.472 L 56.938783 67.472 L 56.908528 68.472 L 56.834884 69.472 L 56.802439 70.472 L 56.757912 71.472 L 56.736656 72.472 L 56.708304 73.472 L 56.679978 74.472 L 56.645645 75.472 L 56.632329 76.472 L 56.615537 77.472 L 56.604993 78.472 L 56.601874 79.472 L 56.600038 80.472 L 56.605027 81.472 L 56.610475 82.472 L 56.62462 83.472 L 56.659254 84.472 L 56.678281 85.472 L 56.720881 86.472 L 56.738986 87.472 L 56.783389 88.472 L 56.805819 89.472 L 56.846087 90.472 L 56.878592 91.472 L 56.941903 92.472 L 57.030413 93.472 L 57.116883 94.472 L 57.196518 95.472 L 57.250304 96.472 L 57.310415 97.472 L 57.381456 98.472 L 57.501577 99.472 L 57.606039 100.472 L 57.716842 101.472 L 57.770115 102.472 L 57.843365 103.472 L 57.881948 104.472 L 57.957711 105.472 L 58.035272 106.472 L 58.121412 107.472 L 58.148855 108.472 L 58.244831 109.472 L 58.320941 110.472 L 58.371105 111.472 L 58.425458 112.472 L 58.453129 113.472 L 58.489151 114.472 L 58.520712 115.472 L 58.538819 116.472 L 58.555558 117.472 L 58.572565 118.472 L 58.589619 119.472 L 58.59403 120.472 L 58.598289 121.472 L 58.599886 122.472 L 58.598359 123.472 L 58.595935 124.472 L 58.592476 125.472 L 58.582211 126.472 L 58.562483 127.472 L 58.550784 128.472 L 58.50804 129.472 L 58.48236 130.472 L 58.438178 131.472 L 58.382063 132.472 L 58.325365 133.472 L 58.293505 134.472 L 58.256796 135.472 L 58.228663 136.472 L 58.172864 137.472 L 58.138147 138.472 L 58.06646 139.472 L 58.010402 140.472 L 57.928747 141.472 L 57.873173 142.472 L 57.788865 143.472 L 57.74624 144.472 L 57.655234 145.472 L 57.594949 146.472 L 57.489872 147.472 L 57.425687 148.472 L 57.346491 149.472 L 57.280264 150.472 L 57.225988 151.472 L 57.192861 152.472 L 57.136147 153.472 L 57.09259 154.472 L 56.995347 155.472 L 56.921401 156.472 L 56.859607 157.472 L 56.831192 158.472 L 56.805858 159.472 L 56.739603 160.472 L 56.696586 161.472 L 56.668079 162.472 L 56.656085 163.472 L 56.642011 164.472 L 56.631183 165.472 L 56.615885 166.472 L 56.606029 167.472 L 56.600216 168.472 L 56.601051 169.472 L 56.603013 170.472 L 56.606621 171.472 L 56.623932 172.472 L 56.633663 173.472 L 56.667693 174.472 L 56.692764 175.472 L 56.731461 176.472 L 56.797395 177.472 L 56.838383 178.472 L 56.913224 179.472 L 56.945151 180.472 L 56.969365 181.472 L 56.995185 182.472 L 57.054225 183.472 L 57.108937 184.472 L 57.215139 185.472 L 57.295415 186.472 L 57.412157 187.472 L 57.51212 188.472 L 57.564434 189.472 L 57.603007 190.472 L 57.639368 191.472 L 57.760354 192.472 L 57.791539 193.472 L 57.827915 194.472 L 57.890066 195.472 L 57.978077 196.472 L 58.02247 197.472 L 58.070988 198.472 L 58.169778 199.472 L 58.211246 200.472 L 58.253898 201.472 L 58.318748 202.472 L 58.385183 203.472 L 58.405272 204.472 L 58.429751 205.472 L 58.470359 206.472 L 58.494905 207.472 L 58.511852 208.472 L 58.542871 209.472 L 58.565923 210.472 L 58.585366 211.472 L 58.592773 212.472 L 58.596995 213.472 L 58.599656 214.472 L 58.599239 215.472 L 58.593894 216.472 L 58.584738 217.472 L 58.572213 218.472 L 58.545446 219.472 L 58.51655 220.472 L 58.46624 221.472 L 58.437897 222.472 L 58.382994 223.472 L 58.345187 224.472 L 58.292498 225.472 L 58.262794 226.472 L 58.231793 227.472 L 58.201321 228.472 L 58.159084 229.472 L 58.131062 230.472 L 58.033515 231.472 L 57.95707 232.472 L 57.901773 233.472 L 57.820903 234.472 L 57.743522 235.472 L 57.662112 236.472 L 57.605147 237.472 L 57.482034 238.472 L 57.450465 239.472 L 57.383234 240.472 L 57.304942 241.472 L 57.212389 242.472 L 57.178235 243.472 L 57.147321 244.472 L 57.096996 245.472 L 57.052178 246.472 L 57.011177 247.472 L 56.981322 248.472 L 56.936474 249.472 L 56.85321 250.472 L 56.83115 251.472 L 56.787033 252.472 L 56.766871 253.472 L 56.706749 254.472 L 56.66452 255.472 L 56.641263 256.472 L 56.623268 257.472 L 56.616266 258.472 L 56.604027 259.472 L 56.600558 260.472 L 56.601741 261.472 L 56.605916 262.472 L 56.619646 263.472 L 56.627297 264.472 L 56.641737 265.472 L 56.672389 266.472 L 56.697078 267.472 L 56.717325 268.472 L 56.735798 269.472 L 56.754752 270.472 L 56.789358 271.472 L 56.856641 272.472 L 56.904869 273.472 L 56.934251 274.472 L 56.966094 275.472 L 57.044318 276.472 L 57.14353 277.472 L 57.187424 278.472 L 57.298184 279.472 L 57.351957 280.472 L 57.410165 281.472 L 57.446342 282.472 L 57.501133 283.472 L 57.584084 284.472 L 57.631754 285.472 L 57.720599 286.472 L 57.768247 287.472 L 57.848469 288.472 L 57.937896 289.472 L 57.982122 290.472 L 58.041179 291.472 L 58.139628 292.472 L 58.17467 293.472 L 58.220434 294.472 L 58.273635 295.472 L 58.309483 296.472 L 58.351738 297.472 L 58.393097 298.472 L 58.420445 299.472 L 58.48147 300.472 L 58.504483 301.472 L 58.519261 302.472 L 58.534284 303.472 L 58.547208 304.472 L 58.579534 305.472 L 58.596802 306.472 L 58.599844 307.584 z " + style="fill: #ffffff; stroke: #ffffff; stroke-width: 4; stroke-linejoin: miter" + id="path3" /> + <path + d="M 57.6 307.584 L 58.6 307.615436 L 59.6 307.652377 L 60.6 307.750123 L 61.6 307.782645 L 62.6 307.85627 L 63.6 307.894835 L 64.6 307.930248 L 65.6 307.987888 L 66.6 308.058274 L 67.6 308.110239 L 68.6 308.169328 L 69.6 308.257649 L 70.6 308.303794 L 71.6 308.346205 L 72.6 308.376697 L 73.6 308.402742 L 74.6 308.423942 L 75.6 308.478243 L 76.6 308.506181 L 77.6 308.535905 L 78.6 308.5613 L 79.6 308.5725 L 80.6 308.582624 L 81.6 308.58242 L 82.6 308.57291 L 83.6 308.561256 L 84.6 308.530227 L 85.6 308.519059 L 86.6 308.488942 L 87.6 308.429165 L 88.6 308.391973 L 89.6 308.352877 L 90.6 308.310437 L 91.6 308.277672 L 92.6 308.210246 L 93.6 308.17112 L 94.6 308.128445 L 95.6 308.057865 L 96.6 308.021474 L 97.6 307.963071 L 98.6 307.852118 L 99.6 307.78146 L 100.6 307.66852 L 101.6 307.622747 L 102.6 307.561464 L 103.6 307.512965 L 104.6 307.432142 L 105.6 307.313623 L 106.6 307.243412 L 107.6 307.16015 L 108.6 307.127008 L 109.6 307.075771 L 110.6 307.007372 L 111.6 306.941157 L 112.6 306.86424 L 113.6 306.836924 L 114.6 306.810447 L 115.6 306.787796 L 116.6 306.768265 L 117.6 306.741871 L 118.6 306.6921 L 119.6 306.657027 L 120.6 306.621161 L 121.6 306.605794 L 122.6 306.590025 L 123.6 306.586612 L 124.6 306.584195 L 125.6 306.584681 L 126.6 306.58661 L 127.6 306.599867 L 128.6 306.608258 L 129.6 306.629794 L 130.6 306.652827 L 131.6 306.67006 L 132.6 306.688523 L 133.6 306.708975 L 134.6 306.725575 L 135.6 306.788354 L 136.6 306.863619 L 137.6 306.896258 L 138.6 306.963822 L 139.6 307.017869 L 140.6 307.051573 L 141.6 307.141699 L 142.6 307.170234 L 143.6 307.20172 L 144.6 307.232731 L 145.6 307.287539 L 146.6 307.352126 L 147.6 307.390322 L 148.6 307.486256 L 149.6 307.535514 L 150.6 307.579583 L 151.6 307.619707 L 152.6 307.728074 L 153.6 307.769702 L 154.6 307.831844 L 155.6 307.901806 L 156.6 308.00631 L 157.6 308.043298 L 158.6 308.089175 L 159.6 308.15767 L 160.6 308.206416 L 161.6 308.284013 L 162.6 308.314554 L 163.6 308.384068 L 164.6 308.408041 L 165.6 308.436663 L 166.6 308.478456 L 167.6 308.500032 L 168.6 308.51398 L 169.6 308.540702 L 170.6 308.550012 L 171.6 308.562459 L 172.6 308.573514 L 173.6 308.579178 L 174.6 308.583942 L 175.6 308.578394 L 176.6 308.565106 L 177.6 308.557589 L 178.6 308.532804 L 179.6 308.509235 L 180.6 308.473055 L 181.6 308.447093 L 182.6 308.424771 L 183.6 308.356011 L 184.6 308.281476 L 185.6 308.187497 L 186.6 308.136445 L 187.6 308.082511 L 188.6 308.04726 L 189.6 307.941172 L 190.6 307.888908 L 191.6 307.852001 L 192.6 307.82097 L 193.6 307.759815 L 194.6 307.692395 L 195.6 307.643489 L 196.6 307.578297 L 197.6 307.540109 L 198.6 307.498113 L 199.6 307.456096 L 200.6 307.39658 L 201.6 307.28342 L 202.6 307.231169 L 203.6 307.191751 L 204.6 307.14465 L 205.6 307.08787 L 206.6 307.055207 L 207.6 307.019029 L 208.6 306.986939 L 209.6 306.952659 L 210.6 306.894281 L 211.6 306.849096 L 212.6 306.819472 L 213.6 306.769086 L 214.6 306.743889 L 215.6 306.722838 L 216.6 306.68787 L 217.6 306.66358 L 218.6 306.649513 L 219.6 306.630571 L 220.6 306.61491 L 221.6 306.602358 L 222.6 306.596522 L 223.6 306.58964 L 224.6 306.584466 L 225.6 306.586249 L 226.6 306.588974 L 227.6 306.600128 L 228.6 306.628363 L 229.6 306.672151 L 230.6 306.69284 L 231.6 306.733813 L 232.6 306.773888 L 233.6 306.792998 L 234.6 306.815507 L 235.6 306.882158 L 236.6 306.931868 L 237.6 307.005574 L 238.6 307.036888 L 239.6 307.11351 L 240.6 307.151808 L 241.6 307.225925 L 242.6 307.329983 L 243.6 307.399814 L 244.6 307.505048 L 245.6 307.560063 L 246.6 307.683538 L 247.6 307.754097 L 248.6 307.869936 L 249.6 307.920117 L 250.6 307.955721 L 251.6 308.047128 L 252.6 308.100636 L 253.6 308.188544 L 254.6 308.257729 L 255.6 308.304493 L 256.6 308.376537 L 257.6 308.426679 L 258.6 308.444069 L 259.6 308.471072 L 260.6 308.490499 L 261.6 308.509837 L 262.6 308.548086 L 263.6 308.564519 L 264.6 308.572888 L 265.6 308.577207 L 266.6 308.583762 L 267.6 308.581216 L 268.6 308.575757 L 269.6 308.559329 L 270.6 308.527394 L 271.6 308.489414 L 272.6 308.45461 L 273.6 308.391538 L 274.6 308.370111 L 275.6 308.319493 L 276.6 308.294536 L 277.6 308.238902 L 278.6 308.207673 L 279.6 308.157529 L 280.6 308.125036 L 281.6 308.044624 L 282.6 307.975698 L 283.6 307.860001 L 284.6 307.784522 L 285.6 307.668997 L 286.6 307.589513 L 287.6 307.481072 L 288.6 307.441704 L 289.6 307.338836 L 290.6 307.239038 L 291.6 307.193541 L 292.6 307.159219 L 293.6 307.107263 L 294.6 307.067616 L 295.6 307.032102 L 296.6 306.964457 L 297.6 306.925375 L 298.6 306.874894 L 299.6 306.825588 L 300.6 306.774518 L 301.6 306.730279 L 302.6 306.708259 L 303.6 306.692703 L 304.6 306.650256 L 305.6 306.635388 L 306.6 306.61266 L 307.6 306.592344 L 308.6 306.586547 L 309.6 306.584065 L 310.6 306.587122 L 311.6 306.598718 L 312.6 306.615638 L 313.6 306.647299 L 314.6 306.661382 L 315.6 306.714054 L 316.6 306.763143 L 317.6 306.817844 L 318.6 306.862192 L 319.6 306.932184 L 320.6 306.982567 L 321.6 307.036474 L 322.6 307.105913 L 323.6 307.163301 L 324.6 307.213466 L 325.6 307.290628 L 326.6 307.348818 L 327.6 307.409456 L 328.6 307.446657 L 329.6 307.511749 L 330.6 307.616879 L 331.6 307.677181 L 332.6 307.773503 L 333.6 307.805506 L 334.6 307.856523 L 335.6 307.973315 L 336.6 308.008762 L 337.6 308.064642 L 338.6 308.095018 L 339.6 308.183404 L 340.6 308.228168 L 341.6 308.309056 L 342.6 308.369202 L 343.6 308.432288 L 344.6 308.455236 L 345.6 308.471406 L 346.6 308.500335 L 347.6 308.530687 L 348.6 308.543261 L 349.6 308.56814 L 350.6 308.580224 L 351.6 308.583986 L 352.6 308.57955 L 353.6 308.567211 L 354.6 308.552798 L 355.6 308.536725 L 356.6 308.501204 L 357.6 308.48127 L 358.6 308.424681 L 359.6 308.357487 L 360.6 308.330117 L 361.6 308.295969 L 362.6 308.247289 L 363.6 308.199004 L 364.6 308.139927 L 365.6 308.044322 L 366.6 308.001182 L 367.6 307.951334 L 368.6 307.8928 L 369.6 307.845214 L 370.6 307.784086 L 371.6 307.728001 L 372.6 307.65383 L 373.6 307.536592 L 374.6 307.480868 L 375.6 307.372642 L 376.6 307.266492 L 377.6 307.15892 L 378.6 307.124412 L 379.6 307.021105 L 380.6 306.945381 L 381.6 306.905946 L 382.6 306.866562 L 383.6 306.84408 L 384.6 306.788267 L 385.6 306.762215 L 386.6 306.73198 L 387.6 306.681209 L 388.6 306.662558 L 389.6 306.640849 L 390.6 306.628203 L 391.6 306.60921 L 392.6 306.59182 L 393.6 306.584782 L 394.6 306.585806 L 395.6 306.59281 L 396.6 306.60218 L 397.6 306.625578 L 398.6 306.650661 L 399.6 306.66306 L 400.6 306.696153 L 401.6 306.71252 L 402.6 306.730925 L 403.6 306.780062 L 404.6 306.823875 L 405.6 306.86696 L 406.6 306.889901 L 407.6 306.930164 L 408.6 307.015024 L 409.6 307.057416 L 410.6 307.121802 L 411.6 307.166091 L 412.6 307.273937 L 413.6 307.350877 L 414.72 307.387319 L 414.578206 306.584 L 414.653307 305.584 L 414.711902 304.584 L 414.748477 303.584 L 414.860524 302.584 L 414.922209 301.584 L 414.972729 300.584 L 415.071514 299.584 L 415.109536 298.584 L 415.144984 297.584 L 415.236618 296.584 L 415.27989 295.584 L 415.333219 294.584 L 415.366084 293.584 L 415.428978 292.584 L 415.482832 291.584 L 415.539958 290.584 L 415.562048 289.584 L 415.605787 288.584 L 415.652881 287.584 L 415.669728 286.584 L 415.697802 285.584 L 415.708798 284.584 L 415.713367 283.584 L 415.719015 282.584 L 415.719066 281.584 L 415.715976 280.584 L 415.712463 279.584 L 415.706641 278.584 L 415.693789 277.584 L 415.670164 276.584 L 415.65528 275.584 L 415.631708 274.584 L 415.595389 273.584 L 415.563806 272.584 L 415.533913 271.584 L 415.455221 270.584 L 415.41867 269.584 L 415.392947 268.584 L 415.322274 267.584 L 415.231172 266.584 L 415.169215 265.584 L 415.135602 264.584 L 415.101102 263.584 L 415.003662 262.584 L 414.956072 261.584 L 414.924566 260.584 L 414.880881 259.584 L 414.810712 258.584 L 414.760845 257.584 L 414.726168 256.584 L 414.61652 255.584 L 414.583049 254.584 L 414.545707 253.584 L 414.465462 252.584 L 414.426968 251.584 L 414.385191 250.584 L 414.342766 249.584 L 414.233038 248.584 L 414.144753 247.584 L 414.070107 246.584 L 413.98165 245.584 L 413.907588 244.584 L 413.858423 243.584 L 413.802806 242.584 L 413.768106 241.584 L 413.756235 240.584 L 413.734012 239.584 L 413.722033 238.584 L 413.720281 237.584 L 413.725698 236.584 L 413.741896 235.584 L 413.758396 234.584 L 413.789579 233.584 L 413.802944 232.584 L 413.832587 231.584 L 413.89561 230.584 L 413.944931 229.584 L 413.99102 228.584 L 414.073247 227.584 L 414.11915 226.584 L 414.153475 225.584 L 414.207014 224.584 L 414.295901 223.584 L 414.327039 222.584 L 414.435088 221.584 L 414.54716 220.584 L 414.582598 219.584 L 414.667384 218.584 L 414.732991 217.584 L 414.835045 216.584 L 414.95126 215.584 L 414.991951 214.584 L 415.03304 213.584 L 415.069681 212.584 L 415.110677 211.584 L 415.186746 210.584 L 415.262812 209.584 L 415.2935 208.584 L 415.319991 207.584 L 415.376572 206.584 L 415.421088 205.584 L 415.451106 204.584 L 415.478162 203.584 L 415.520727 202.584 L 415.573592 201.584 L 415.604513 200.584 L 415.630788 199.584 L 415.645721 198.584 L 415.67601 197.584 L 415.697339 196.584 L 415.714228 195.584 L 415.718943 194.584 L 415.719553 193.584 L 415.717507 192.584 L 415.711646 191.584 L 415.692999 190.584 L 415.660942 189.584 L 415.614502 188.584 L 415.572556 187.584 L 415.505851 186.584 L 415.436785 185.584 L 415.38941 184.584 L 415.337891 183.584 L 415.298191 182.584 L 415.228771 181.584 L 415.16224 180.584 L 415.053331 179.584 L 414.988083 178.584 L 414.879875 177.584 L 414.818871 176.584 L 414.770186 175.584 L 414.693952 174.584 L 414.634421 173.584 L 414.559793 172.584 L 414.440966 171.584 L 414.343021 170.584 L 414.263973 169.584 L 414.218226 168.584 L 414.190954 167.584 L 414.147292 166.584 L 414.098708 165.584 L 414.066974 164.584 L 413.986744 163.584 L 413.920251 162.584 L 413.896226 161.584 L 413.835727 160.584 L 413.813495 159.584 L 413.794895 158.584 L 413.765569 157.584 L 413.749868 156.584 L 413.741569 155.584 L 413.731333 154.584 L 413.72099 153.584 L 413.721668 152.584 L 413.725448 151.584 L 413.741889 150.584 L 413.754023 149.584 L 413.764618 148.584 L 413.795995 147.584 L 413.821768 146.584 L 413.853177 145.584 L 413.875986 144.584 L 413.89358 143.584 L 413.943392 142.584 L 413.991052 141.584 L 414.062761 140.584 L 414.118524 139.584 L 414.144722 138.584 L 414.17549 137.584 L 414.265248 136.584 L 414.350042 135.584 L 414.415636 134.584 L 414.461461 133.584 L 414.504458 132.584 L 414.565971 131.584 L 414.665796 130.584 L 414.710226 129.584 L 414.760276 128.584 L 414.882117 127.584 L 414.94181 126.584 L 414.973376 125.584 L 415.005719 124.584 L 415.060279 123.584 L 415.102779 122.584 L 415.154251 121.584 L 415.242636 120.584 L 415.276833 119.584 L 415.320767 118.584 L 415.38448 117.584 L 415.459677 116.584 L 415.488491 115.584 L 415.530695 114.584 L 415.57328 113.584 L 415.590172 112.584 L 415.612653 111.584 L 415.65499 110.584 L 415.68495 109.584 L 415.703583 108.584 L 415.713375 107.584 L 415.717138 106.584 L 415.719976 105.584 L 415.718227 104.584 L 415.708871 103.584 L 415.698174 102.584 L 415.688304 101.584 L 415.669446 100.584 L 415.639107 99.584 L 415.600716 98.584 L 415.54123 97.584 L 415.497941 96.584 L 415.437203 95.584 L 415.353129 94.584 L 415.304836 93.584 L 415.261259 92.584 L 415.234378 91.584 L 415.202448 90.584 L 415.135256 89.584 L 415.054435 88.584 L 414.97889 87.584 L 414.93516 86.584 L 414.855265 85.584 L 414.793786 84.584 L 414.730161 83.584 L 414.622912 82.584 L 414.504202 81.584 L 414.462296 80.584 L 414.419342 79.584 L 414.357143 78.584 L 414.327006 77.584 L 414.294488 76.584 L 414.242553 75.584 L 414.137003 74.584 L 414.088557 73.584 L 414.042233 72.584 L 414.008417 71.584 L 413.96054 70.584 L 413.905662 69.584 L 413.881751 68.584 L 413.855714 67.584 L 413.799597 66.584 L 413.785723 65.584 L 413.759689 64.584 L 413.732943 63.584 L 413.725197 62.584 L 413.720044 61.584 L 413.726242 60.584 L 413.732549 59.584 L 413.74013 58.584 L 413.767636 57.584 L 413.811869 56.584 L 413.841407 55.584 L 413.883254 54.584 L 413.942428 53.584 L 413.965138 52.584 L 414.00177 51.584 L 414.058558 50.584 L 414.083728 49.584 L 414.166424 48.584 L 414.253356 47.584 L 414.30404 46.584 L 414.341434 45.584 L 414.425814 44.584 L 414.460325 43.584 L 414.552316 42.584 L 414.639341 41.472 L 413.72 41.429519 L 412.72 41.39165 L 411.72 41.344175 L 410.72 41.238649 L 409.72 41.141188 L 408.72 41.064551 L 407.72 41.032624 L 406.72 40.978384 L 405.72 40.939533 L 404.72 40.865828 L 403.72 40.833832 L 402.72 40.777293 L 401.72 40.741177 L 400.72 40.672575 L 399.72 40.641159 L 398.72 40.586492 L 397.72 40.567721 L 396.72 40.522092 L 395.72 40.499189 L 394.72 40.490648 L 393.72 40.483307 L 392.72 40.477012 L 391.72 40.473835 L 390.72 40.472249 L 389.72 40.473712 L 388.72 40.486666 L 387.72 40.501288 L 386.72 40.513144 L 385.72 40.531169 L 384.72 40.551547 L 383.72 40.574946 L 382.72 40.589855 L 381.72 40.644569 L 380.72 40.678166 L 379.72 40.740862 L 378.72 40.768237 L 377.72 40.812217 L 376.72 40.891164 L 375.72 40.948692 L 374.72 40.998671 L 373.72 41.070655 L 372.72 41.107187 L 371.72 41.1755 L 370.72 41.263706 L 369.72 41.385053 L 368.72 41.450734 L 367.72 41.484352 L 366.72 41.548629 L 365.72 41.5946 L 364.72 41.666757 L 363.72 41.706583 L 362.72 41.749213 L 361.72 41.855172 L 360.72 41.907957 L 359.72 41.987234 L 358.72 42.029638 L 357.72 42.061904 L 356.72 42.09677 L 355.72 42.139428 L 354.72 42.171001 L 353.72 42.23858 L 352.72 42.275465 L 351.72 42.303421 L 350.72 42.324269 L 349.72 42.349882 L 348.72 42.3875 L 347.72 42.402342 L 346.72 42.427072 L 345.72 42.445302 L 344.72 42.456709 L 343.72 42.462344 L 342.72 42.467098 L 341.72 42.471707 L 340.72 42.470034 L 339.72 42.464252 L 338.72 42.444256 L 337.72 42.432604 L 336.72 42.421615 L 335.72 42.408648 L 334.72 42.358234 L 333.72 42.337412 L 332.72 42.309465 L 331.72 42.25272 L 330.72 42.230076 L 329.72 42.178673 L 328.72 42.137537 L 327.72 42.054768 L 326.72 42.006308 L 325.72 41.954881 L 324.72 41.903721 L 323.72 41.836422 L 322.72 41.803268 L 321.72 41.73721 L 320.72 41.681025 L 319.72 41.619746 L 318.72 41.579763 L 317.72 41.48334 L 316.72 41.37158 L 315.72 41.332661 L 314.72 41.234812 L 313.72 41.200158 L 312.72 41.116476 L 311.72 41.06597 L 310.72 40.996927 L 309.72 40.895824 L 308.72 40.843378 L 307.72 40.75407 L 306.72 40.689062 L 305.72 40.647517 L 304.72 40.605177 L 303.72 40.583157 L 302.72 40.54567 L 301.72 40.528418 L 300.72 40.50501 L 299.72 40.496443 L 298.72 40.487354 L 297.72 40.480286 L 296.72 40.473259 L 295.72 40.472151 L 294.72 40.472137 L 293.72 40.474811 L 292.72 40.477837 L 291.72 40.483304 L 290.72 40.503299 L 289.72 40.51527 L 288.72 40.542389 L 287.72 40.569401 L 286.72 40.596567 L 285.72 40.651042 L 284.72 40.680658 L 283.72 40.722414 L 282.72 40.795523 L 281.72 40.838961 L 280.72 40.909652 L 279.72 40.948059 L 278.72 41.008398 L 277.72 41.039153 L 276.72 41.069651 L 275.72 41.128561 L 274.72 41.171738 L 273.72 41.21335 L 272.72 41.262465 L 271.72 41.327552 L 270.72 41.393947 L 269.72 41.51871 L 268.72 41.562525 L 267.72 41.616853 L 266.72 41.723557 L 265.72 41.766057 L 264.72 41.803551 L 263.72 41.893047 L 262.72 41.95027 L 261.72 42.019913 L 260.72 42.068932 L 259.72 42.124877 L 258.72 42.172002 L 257.72 42.21089 L 256.72 42.264582 L 255.72 42.310153 L 254.72 42.34709 L 253.72 42.369166 L 252.72 42.402049 L 251.72 42.431769 L 250.72 42.444319 L 249.72 42.456218 L 248.72 42.461336 L 247.72 42.469225 L 246.72 42.471856 L 245.72 42.471058 L 244.72 42.467817 L 243.72 42.452679 L 242.72 42.445742 L 241.72 42.429365 L 240.72 42.410952 L 239.72 42.38136 L 238.72 42.359278 L 237.72 42.301584 L 236.72 42.276393 L 235.72 42.20808 L 234.72 42.160954 L 233.72 42.123606 L 232.72 42.068397 L 231.72 41.978966 L 230.72 41.875856 L 229.72 41.821882 L 228.72 41.791162 L 227.72 41.735621 L 226.72 41.697886 L 225.72 41.629632 L 224.72 41.593803 L 223.72 41.524019 L 222.72 41.464725 L 221.72 41.426118 L 220.72 41.392122 L 219.72 41.349542 L 218.72 41.302893 L 217.72 41.248327 L 216.72 41.162426 L 215.72 41.11575 L 214.72 41.058435 L 213.72 41.028021 L 212.72 40.94297 L 211.72 40.909295 L 210.72 40.821371 L 209.72 40.766386 L 208.72 40.727697 L 207.72 40.657666 L 206.72 40.62722 L 205.72 40.569495 L 204.72 40.552351 L 203.72 40.527616 L 202.72 40.512116 L 201.72 40.488664 L 200.72 40.48185 L 199.72 40.477917 L 198.72 40.474185 L 197.72 40.472152 L 196.72 40.480538 L 195.72 40.496924 L 194.72 40.523194 L 193.72 40.536523 L 192.72 40.566477 L 191.72 40.600728 L 190.72 40.621398 L 189.72 40.66241 L 188.72 40.735728 L 187.72 40.758946 L 186.72 40.799312 L 185.72 40.826563 L 184.72 40.907101 L 183.72 40.960579 L 182.72 41.03915 L 181.72 41.087618 L 180.72 41.201648 L 179.72 41.302333 L 178.72 41.386757 L 177.72 41.478297 L 176.72 41.58071 L 175.72 41.621518 L 174.72 41.664661 L 173.72 41.703962 L 172.72 41.737385 L 171.72 41.780493 L 170.72 41.886072 L 169.72 41.941773 L 168.72 42.0471 L 167.72 42.144097 L 166.72 42.167117 L 165.72 42.194104 L 164.72 42.224205 L 163.72 42.297447 L 162.72 42.334839 L 161.72 42.369798 L 160.72 42.388374 L 159.72 42.41888 L 158.72 42.431092 L 157.72 42.440868 L 156.72 42.450437 L 155.72 42.458646 L 154.72 42.469922 L 153.72 42.471784 L 152.72 42.465482 L 151.72 42.459469 L 150.72 42.454012 L 149.72 42.43382 L 148.72 42.423931 L 147.72 42.396178 L 146.72 42.377171 L 145.72 42.361772 L 144.72 42.332507 L 143.72 42.268703 L 142.72 42.21965 L 141.72 42.149461 L 140.72 42.120352 L 139.72 42.060782 L 138.72 42.013833 L 137.72 41.962711 L 136.72 41.908658 L 135.72 41.826971 L 134.72 41.748314 L 133.72 41.711654 L 132.72 41.59 L 131.72 41.511058 L 130.72 41.446567 L 129.72 41.400939 L 128.72 41.28529 L 127.72 41.237015 L 126.72 41.201492 L 125.72 41.157914 L 124.72 41.122138 L 123.72 41.051313 L 122.72 41.014909 L 121.72 40.917433 L 120.72 40.848369 L 119.72 40.782403 L 118.72 40.717873 L 117.72 40.694451 L 116.72 40.667046 L 115.72 40.618552 L 114.72 40.588559 L 113.72 40.556021 L 112.72 40.541278 L 111.72 40.527738 L 110.72 40.504303 L 109.72 40.491823 L 108.72 40.484685 L 107.72 40.479087 L 106.72 40.473481 L 105.72 40.472 L 104.72 40.477993 L 103.72 40.483958 L 102.72 40.49547 L 101.72 40.519277 L 100.72 40.52941 L 99.72 40.571368 L 98.72 40.61344 L 97.72 40.644656 L 96.72 40.714514 L 95.72 40.75877 L 94.72 40.84124 L 93.72 40.929427 L 92.72 40.974347 L 91.72 41.070077 L 90.72 41.142181 L 89.72 41.237171 L 88.72 41.293545 L 87.72 41.337742 L 86.72 41.393558 L 85.72 41.433496 L 84.72 41.508947 L 83.72 41.566942 L 82.72 41.604129 L 81.72 41.662656 L 80.72 41.765433 L 79.72 41.82216 L 78.72 41.893165 L 77.72 41.954934 L 76.72 41.992397 L 75.72 42.027683 L 74.72 42.071101 L 73.72 42.11296 L 72.72 42.140583 L 71.72 42.191698 L 70.72 42.225234 L 69.72 42.287297 L 68.72 42.306939 L 67.72 42.368712 L 66.72 42.391191 L 65.72 42.411414 L 64.72 42.432103 L 63.72 42.45853 L 62.72 42.469487 L 61.72 42.471269 L 60.72 42.468641 L 59.72 42.462091 L 58.72 42.440128 L 57.6 42.401128 L 58.508845 42.472 L 58.492196 43.472 L 58.430573 44.472 L 58.401989 45.472 L 58.378481 46.472 L 58.334033 47.472 L 58.30807 48.472 L 58.25771 49.472 L 58.181318 50.472 L 58.153797 51.472 L 58.121939 52.472 L 58.086315 53.472 L 57.998542 54.472 L 57.901531 55.472 L 57.821578 56.472 L 57.703903 57.472 L 57.631909 58.472 L 57.527743 59.472 L 57.416434 60.472 L 57.321012 61.472 L 57.226115 62.472 L 57.159096 63.472 L 57.098211 64.472 L 57.05375 65.472 L 57.018079 66.472 L 56.938783 67.472 L 56.908528 68.472 L 56.834884 69.472 L 56.802439 70.472 L 56.757912 71.472 L 56.736656 72.472 L 56.708304 73.472 L 56.679978 74.472 L 56.645645 75.472 L 56.632329 76.472 L 56.615537 77.472 L 56.604993 78.472 L 56.601874 79.472 L 56.600038 80.472 L 56.605027 81.472 L 56.610475 82.472 L 56.62462 83.472 L 56.659254 84.472 L 56.678281 85.472 L 56.720881 86.472 L 56.738986 87.472 L 56.783389 88.472 L 56.805819 89.472 L 56.846087 90.472 L 56.878592 91.472 L 56.941903 92.472 L 57.030413 93.472 L 57.116883 94.472 L 57.196518 95.472 L 57.250304 96.472 L 57.310415 97.472 L 57.381456 98.472 L 57.501577 99.472 L 57.606039 100.472 L 57.716842 101.472 L 57.770115 102.472 L 57.843365 103.472 L 57.881948 104.472 L 57.957711 105.472 L 58.035272 106.472 L 58.121412 107.472 L 58.148855 108.472 L 58.244831 109.472 L 58.320941 110.472 L 58.371105 111.472 L 58.425458 112.472 L 58.453129 113.472 L 58.489151 114.472 L 58.520712 115.472 L 58.538819 116.472 L 58.555558 117.472 L 58.572565 118.472 L 58.589619 119.472 L 58.59403 120.472 L 58.598289 121.472 L 58.599886 122.472 L 58.598359 123.472 L 58.595935 124.472 L 58.592476 125.472 L 58.582211 126.472 L 58.562483 127.472 L 58.550784 128.472 L 58.50804 129.472 L 58.48236 130.472 L 58.438178 131.472 L 58.382063 132.472 L 58.325365 133.472 L 58.293505 134.472 L 58.256796 135.472 L 58.228663 136.472 L 58.172864 137.472 L 58.138147 138.472 L 58.06646 139.472 L 58.010402 140.472 L 57.928747 141.472 L 57.873173 142.472 L 57.788865 143.472 L 57.74624 144.472 L 57.655234 145.472 L 57.594949 146.472 L 57.489872 147.472 L 57.425687 148.472 L 57.346491 149.472 L 57.280264 150.472 L 57.225988 151.472 L 57.192861 152.472 L 57.136147 153.472 L 57.09259 154.472 L 56.995347 155.472 L 56.921401 156.472 L 56.859607 157.472 L 56.831192 158.472 L 56.805858 159.472 L 56.739603 160.472 L 56.696586 161.472 L 56.668079 162.472 L 56.656085 163.472 L 56.642011 164.472 L 56.631183 165.472 L 56.615885 166.472 L 56.606029 167.472 L 56.600216 168.472 L 56.601051 169.472 L 56.603013 170.472 L 56.606621 171.472 L 56.623932 172.472 L 56.633663 173.472 L 56.667693 174.472 L 56.692764 175.472 L 56.731461 176.472 L 56.797395 177.472 L 56.838383 178.472 L 56.913224 179.472 L 56.945151 180.472 L 56.969365 181.472 L 56.995185 182.472 L 57.054225 183.472 L 57.108937 184.472 L 57.215139 185.472 L 57.295415 186.472 L 57.412157 187.472 L 57.51212 188.472 L 57.564434 189.472 L 57.603007 190.472 L 57.639368 191.472 L 57.760354 192.472 L 57.791539 193.472 L 57.827915 194.472 L 57.890066 195.472 L 57.978077 196.472 L 58.02247 197.472 L 58.070988 198.472 L 58.169778 199.472 L 58.211246 200.472 L 58.253898 201.472 L 58.318748 202.472 L 58.385183 203.472 L 58.405272 204.472 L 58.429751 205.472 L 58.470359 206.472 L 58.494905 207.472 L 58.511852 208.472 L 58.542871 209.472 L 58.565923 210.472 L 58.585366 211.472 L 58.592773 212.472 L 58.596995 213.472 L 58.599656 214.472 L 58.599239 215.472 L 58.593894 216.472 L 58.584738 217.472 L 58.572213 218.472 L 58.545446 219.472 L 58.51655 220.472 L 58.46624 221.472 L 58.437897 222.472 L 58.382994 223.472 L 58.345187 224.472 L 58.292498 225.472 L 58.262794 226.472 L 58.231793 227.472 L 58.201321 228.472 L 58.159084 229.472 L 58.131062 230.472 L 58.033515 231.472 L 57.95707 232.472 L 57.901773 233.472 L 57.820903 234.472 L 57.743522 235.472 L 57.662112 236.472 L 57.605147 237.472 L 57.482034 238.472 L 57.450465 239.472 L 57.383234 240.472 L 57.304942 241.472 L 57.212389 242.472 L 57.178235 243.472 L 57.147321 244.472 L 57.096996 245.472 L 57.052178 246.472 L 57.011177 247.472 L 56.981322 248.472 L 56.936474 249.472 L 56.85321 250.472 L 56.83115 251.472 L 56.787033 252.472 L 56.766871 253.472 L 56.706749 254.472 L 56.66452 255.472 L 56.641263 256.472 L 56.623268 257.472 L 56.616266 258.472 L 56.604027 259.472 L 56.600558 260.472 L 56.601741 261.472 L 56.605916 262.472 L 56.619646 263.472 L 56.627297 264.472 L 56.641737 265.472 L 56.672389 266.472 L 56.697078 267.472 L 56.717325 268.472 L 56.735798 269.472 L 56.754752 270.472 L 56.789358 271.472 L 56.856641 272.472 L 56.904869 273.472 L 56.934251 274.472 L 56.966094 275.472 L 57.044318 276.472 L 57.14353 277.472 L 57.187424 278.472 L 57.298184 279.472 L 57.351957 280.472 L 57.410165 281.472 L 57.446342 282.472 L 57.501133 283.472 L 57.584084 284.472 L 57.631754 285.472 L 57.720599 286.472 L 57.768247 287.472 L 57.848469 288.472 L 57.937896 289.472 L 57.982122 290.472 L 58.041179 291.472 L 58.139628 292.472 L 58.17467 293.472 L 58.220434 294.472 L 58.273635 295.472 L 58.309483 296.472 L 58.351738 297.472 L 58.393097 298.472 L 58.420445 299.472 L 58.48147 300.472 L 58.504483 301.472 L 58.519261 302.472 L 58.534284 303.472 L 58.547208 304.472 L 58.579534 305.472 L 58.596802 306.472 L 58.599844 307.584 z " + style="fill: #ffffff" + id="path4" /> + </g> + <g + id="matplotlib.axis_1"> + <g + id="text_1"> + <path + d="M 171.004219 322.974312 C 172.165781 322.974312 172.165781 320.854625 172.165781 320.143687 C 172.165781 319.15275 171.995156 318.168375 171.995156 317.162125 C 171.995156 316.013688 172.124219 314.86525 172.124219 313.703688 C 172.124219 313.581187 172.124219 313.095562 172.084844 312.631813 C 172.043281 312.200875 171.940469 311.708687 171.686719 311.708687 C 171.181406 311.708687 170.647656 311.885875 170.566719 312.487437 C 170.457344 313.34275 170.483594 314.279 170.483594 315.132125 L 170.498906 317.05275 C 170.512031 318.017437 170.737344 319.014937 170.737344 319.99275 C 170.737344 320.005875 170.737344 320.124 170.724219 320.218062 C 170.724219 320.314312 170.724219 320.410563 170.682656 320.410563 C 170.586406 320.410563 170.437656 320.060563 170.299844 319.71275 C 170.164219 319.349625 170.032969 318.966813 170.006719 318.885875 C 169.540781 317.599625 166.957344 312.568375 165.487344 312.568375 C 164.564219 312.568375 164.564219 314.559 164.564219 315.105875 C 164.564219 317.286812 164.673594 319.480875 164.673594 321.661812 C 164.673594 322.167125 165.139531 322.987437 165.725781 322.987437 C 166.382031 322.987437 166.436719 321.819313 166.436719 321.353375 C 166.436719 320.349312 166.287969 319.343062 166.287969 318.339 C 166.287969 317.389625 166.075781 316.444625 166.075781 315.482125 C 166.075781 315.466813 166.047344 315.208687 166.102031 315.208687 C 166.465156 315.208687 168.427344 319.391188 168.707344 320.034312 C 169.028906 320.8065 170.000156 322.974312 171.004219 322.974312 z M 174.988477 316.096812 C 174.367227 316.424937 174.209727 317.450875 174.058789 318.297438 C 173.691289 320.375563 173.697852 323.05525 176.261602 322.794938 C 177.230664 322.700875 178.256602 322.186812 178.845039 321.456187 C 179.144727 321.0865 179.433477 320.506813 179.520977 320.054 C 179.733164 318.966813 179.426914 317.881813 179.234414 317.05275 C 179.166602 316.766188 179.118477 316.4665 178.871289 316.383375 C 178.652539 316.309 178.236914 316.444625 178.147227 316.61525 C 178.005039 316.888688 178.324414 317.5865 178.407539 317.96275 C 178.510352 318.448375 178.571602 319.104625 178.536602 319.6165 C 178.455664 320.74525 177.410039 321.661812 176.261602 321.764625 C 175.988164 321.790875 175.625039 321.810563 175.406289 321.709938 C 175.132852 321.578688 174.997227 321.108375 174.942539 320.751812 C 174.675664 318.934 175.338477 317.846812 175.480664 316.357125 C 175.371289 316.21275 175.152539 316.17775 174.988477 316.096812 z M 186.200781 322.399 C 186.467656 321.749312 186.555156 320.764937 186.686406 319.83525 C 186.808906 318.947125 186.924844 317.969313 187.342656 317.444313 C 187.513281 317.232125 187.944219 316.904 188.278906 316.93025 C 188.838906 316.971812 189.234844 317.763688 189.221719 318.413375 C 189.215156 318.721812 189.051094 319.207438 188.906719 319.609938 C 188.703281 320.191813 188.462656 320.896187 188.510781 321.626812 C 188.539219 322.003062 188.729531 322.61775 189.051094 322.794938 C 189.385781 322.980875 189.864844 322.685563 189.932656 322.37275 C 189.993906 322.09275 189.652656 321.893687 189.617656 321.572125 C 189.597969 321.408062 189.639531 321.14775 189.672344 320.977125 C 189.823281 320.191813 190.295781 319.268687 190.357031 318.4965 C 190.411719 317.853375 190.157969 317.177437 189.851719 316.733375 C 189.420781 316.1165 188.639844 315.598062 187.710156 315.878062 C 187.130469 316.05525 186.767344 316.418375 186.342969 316.958687 C 186.310156 316.68525 186.097969 316.376812 185.914219 316.158062 C 185.120156 315.61775 183.794531 316.035563 183.241094 316.704937 C 183.061719 316.917125 183.007031 317.170875 182.810156 317.299937 C 182.823281 316.998063 182.816719 316.05525 182.530156 315.904313 C 182.331094 315.803688 182.022656 315.994 181.757969 316.022438 C 181.523906 316.389937 181.668281 316.875563 181.703281 317.389625 C 181.784219 318.52275 181.893594 319.979625 181.812656 321.06025 C 181.777656 321.482438 181.539219 321.919938 181.585156 322.256813 C 181.613594 322.466813 181.845469 322.630875 181.928594 322.768687 C 182.398906 322.93275 182.672344 322.685563 182.871406 322.256813 C 182.952344 320.5265 183.308906 318.831187 184.032969 317.499 C 184.341406 317.28025 184.586406 317.013375 185.148594 317.046187 C 185.640781 318.255875 184.975781 320.375563 185.148594 321.858687 C 185.181406 322.18025 185.380469 322.37275 185.516094 322.514937 C 185.782969 322.5215 185.995156 322.453688 186.200781 322.399 z M 192.483555 317.334938 C 192.49668 316.534312 192.55793 315.173687 192.483555 314.224312 C 192.455117 313.889625 192.40043 313.137125 192.100742 313.075875 C 191.92793 313.040875 191.763867 313.178688 191.615117 313.178688 C 191.28043 314.018687 191.62168 315.420875 191.512305 316.77275 C 191.435742 317.689312 191.36793 318.654 191.409492 319.55525 C 191.457617 320.568062 191.483867 322.105875 192.249492 321.90025 C 192.448555 321.845562 192.61918 321.810563 192.686992 321.62025 C 193.645117 322.193375 195.272617 322.18025 196.106055 321.491188 C 196.33793 321.298687 196.447305 321.053688 196.666055 320.880875 C 196.974492 320.191813 197.46668 319.200875 197.27418 318.249312 C 197.18668 317.80525 196.95918 317.422438 196.788555 317.05275 C 196.270117 316.499312 195.791055 316.048687 194.826367 316.035563 C 193.719492 316.022438 192.966992 316.704937 192.483555 317.334938 z M 194.34293 321.06025 C 193.699805 321.066813 193.17918 320.799937 192.763555 320.471812 C 192.74168 318.796187 193.207617 317.464 194.417305 317.081187 C 194.732305 316.978375 195.327305 317.100875 195.546055 317.232125 C 196.701055 317.9365 196.318242 320.178688 195.285742 320.826188 C 195.12168 320.929 194.58793 321.06025 194.34293 321.06025 z M 199.577617 319.522438 C 200.24918 319.631813 201.041055 319.535563 201.957617 319.459 C 202.955117 319.378062 203.816992 319.522438 204.21293 318.947125 C 204.547617 317.921187 204.261055 316.698375 203.49543 316.1165 C 202.941992 315.694313 201.935742 315.412125 201.170117 315.604625 C 200.658242 315.733687 199.831367 316.274 199.393867 316.814312 C 198.608555 317.779 197.998242 319.67775 198.615117 320.964 C 198.96293 321.517437 199.27793 321.983375 199.844492 322.289625 C 200.822305 322.823375 201.951055 322.563063 202.858867 322.263375 C 203.289805 322.119 203.77543 321.954937 204.061992 321.723063 C 204.241367 321.578688 204.425117 321.292125 204.363867 321.0865 C 204.315742 320.909312 203.904492 320.539625 203.646367 320.546187 C 203.421055 320.55275 203.24168 320.8415 203.009805 320.964 C 202.395117 321.298687 201.27293 321.668375 200.481055 321.333687 C 199.83793 321.06025 199.551367 320.355875 199.577617 319.522438 z M 202.55918 316.93025 C 202.86543 317.094313 203.235117 317.599625 203.160742 318.229625 C 201.99918 318.24275 200.96668 318.345562 199.818242 318.43525 C 200.172617 317.553688 201.294805 316.260875 202.55918 316.93025 z M 210.160742 316.827437 C 210.138867 316.978375 210.228555 317.019938 210.270117 317.107438 C 210.93293 317.56025 211.460117 317.068062 211.27418 316.376812 C 211.096992 316.103375 210.83668 315.913063 210.49543 315.794938 C 209.27918 315.385875 207.069805 315.768687 206.529492 316.575875 C 206.406992 316.383375 205.86668 316.350563 205.669805 316.49275 C 205.545117 316.582438 205.512305 316.882125 205.49918 317.135875 C 205.457617 317.827125 205.553867 318.702125 205.49918 319.364937 C 205.396367 320.607438 205.396367 321.797438 205.52543 322.549937 C 205.64793 322.679 205.792305 322.781813 205.943242 322.884625 C 206.14668 322.8365 206.133555 322.843062 206.36543 322.858375 C 206.483555 322.762125 206.564492 322.630875 206.673867 322.5215 C 206.577617 321.86525 206.667305 321.250563 206.728555 320.513375 C 206.824805 319.349625 206.818242 318.107125 207.31043 317.299937 C 207.850742 316.724625 209.128242 316.656813 210.160742 316.827437 z M 219.08793 315.2415 C 218.444805 315.269937 217.768867 315.733687 217.412305 316.096812 C 217.27668 316.232438 217.15418 316.479625 216.990117 316.691813 C 216.537305 317.286812 216.108555 318.271187 215.99918 319.124312 C 215.813242 320.546187 216.333867 321.954937 217.125742 322.475563 C 217.27668 322.569625 217.639805 322.749 217.865117 322.781813 C 218.569492 322.884625 219.457617 322.536812 219.96293 322.21525 C 220.58418 321.819313 221.220742 321.128062 221.49418 320.484938 C 221.999492 319.303688 221.780742 317.730875 221.268867 316.801188 C 221.098242 316.49275 220.844492 316.260875 220.58418 316.007125 C 220.14668 315.584938 219.70918 315.21525 219.08793 315.2415 z M 217.585117 317.737437 C 217.781992 317.374312 218.521367 316.37025 219.08793 316.350563 C 219.094492 316.350563 219.116367 316.309 219.142617 316.322125 C 220.02418 316.704937 220.673867 317.676188 220.673867 319.043375 C 220.673867 319.809 220.256055 320.498063 219.792305 320.944313 C 219.381055 321.34025 218.547617 321.784312 218.007305 321.6465 C 217.65293 321.559 217.412305 321.195875 217.296367 320.915875 C 216.928867 320.02775 217.132305 318.551188 217.585117 317.737437 z M 226.116367 312.8965 C 226.538555 313.082437 226.99793 313.334 227.483555 313.581187 C 227.912305 313.799937 228.522617 314.237437 228.883555 314.163063 C 229.178867 314.099625 229.533242 313.404 229.436992 313.191812 C 229.288242 312.87025 228.365117 312.644937 227.975742 312.439312 C 227.345742 312.111187 226.888555 311.796187 226.409492 311.59275 C 225.96543 311.55775 225.534492 311.647438 225.206367 311.885875 C 224.43418 312.828688 224.33793 314.237437 224.228555 315.727125 C 223.292305 315.646187 222.636055 315.823375 222.92918 316.834 C 223.169805 317.107438 223.83918 316.936812 224.228555 317.0615 C 224.167305 318.345562 224.427617 319.343062 224.427617 320.539625 C 224.427617 321.388375 224.228555 322.289625 224.65293 322.788375 C 224.913242 322.788375 225.18668 322.803688 225.40543 322.755562 C 225.521367 322.5915 225.637305 322.392437 225.663555 322.202125 C 225.910742 320.629313 225.425117 318.693375 225.569492 317.129313 C 226.18418 317.013375 227.091992 317.081187 227.448555 316.669938 C 227.74168 316.33525 227.544805 315.891188 227.256055 315.694313 C 226.86668 315.420875 226.696055 315.61775 226.348242 315.727125 C 226.094492 315.81025 225.84293 315.794938 225.534492 315.858375 C 225.541055 315.324625 225.602305 314.784312 225.691992 314.263688 C 225.779492 313.758375 225.74668 313.178688 226.116367 312.8965 z M 237.258125 314.928688 C 237.496562 313.915875 237.721875 312.706187 237.518438 311.728375 C 237.299688 311.584 236.971563 311.551187 236.83375 311.632125 C 236.129375 312.049937 236.245312 314.073375 235.952187 314.928688 C 235.254375 315.029313 234.504062 314.764625 233.99 315.029313 C 233.941875 315.30275 233.784375 315.788375 233.99 316.007125 C 234.407812 316.241188 235.077187 316.219313 235.720312 316.232438 C 235.691875 316.7115 235.5825 317.422438 235.55625 317.9365 C 235.473125 319.548687 235.466562 321.600563 236.376562 322.405562 C 237.010937 322.974312 238.249062 322.81025 239.0825 322.536812 C 239.3625 322.447125 239.690625 322.399 239.835 322.2765 C 240.121562 322.029313 239.93125 321.469313 239.73875 321.202437 C 239.089062 320.977125 238.010625 321.825875 237.354375 321.49775 C 236.95625 321.298687 236.901562 320.382125 236.862188 319.828688 C 236.779062 318.673687 236.916875 317.232125 237.02625 316.232438 C 237.84 316.1865 238.638437 316.3965 239.506875 316.267437 C 239.786875 316.042125 239.684062 315.427437 239.506875 315.125563 C 238.850625 314.968062 237.98875 315.009625 237.258125 314.928688 z M 245.728125 316.827437 C 245.70625 316.978375 245.795937 317.019938 245.8375 317.107438 C 246.500313 317.56025 247.0275 317.068062 246.841562 316.376812 C 246.664375 316.103375 246.404062 315.913063 246.062813 315.794938 C 244.846563 315.385875 242.637187 315.768687 242.096875 316.575875 C 241.974375 316.383375 241.434062 316.350563 241.237188 316.49275 C 241.1125 316.582438 241.079687 316.882125 241.066562 317.135875 C 241.025 317.827125 241.12125 318.702125 241.066562 319.364937 C 240.96375 320.607438 240.96375 321.797438 241.092812 322.549937 C 241.215312 322.679 241.359688 322.781813 241.510625 322.884625 C 241.714062 322.8365 241.700937 322.843062 241.932812 322.858375 C 242.050937 322.762125 242.131875 322.630875 242.24125 322.5215 C 242.145 321.86525 242.234688 321.250563 242.295937 320.513375 C 242.392187 319.349625 242.385625 318.107125 242.877813 317.299937 C 243.418125 316.724625 244.695625 316.656813 245.728125 316.827437 z M 253.574687 317.162125 C 253.526562 317.0615 253.349375 317.100875 253.246562 317.05275 C 252.844063 316.514625 252.214062 316.068375 251.284375 316.096812 C 249.015938 316.158062 247.80625 318.68025 247.812813 320.880875 C 247.812813 321.257125 247.887187 321.755875 248.1125 322.077437 C 248.394687 322.475563 248.816875 322.685563 249.234688 322.816813 C 251.155312 322.823375 251.98875 321.749312 252.8375 320.690562 C 253.104375 321.62025 253.506875 323.029 254.532812 322.762125 C 254.887187 322.482125 254.812813 321.764625 254.36875 321.694625 C 254.005625 321.018687 253.754062 320.069313 253.684062 319.104625 C 253.644687 318.448375 253.8 317.750563 253.574687 317.162125 z M 250.328438 317.435563 C 250.984688 317.019938 252.065313 317.074625 252.564062 317.573375 C 252.49625 317.9365 252.605625 318.428688 252.564062 318.748063 C 252.474375 319.452437 251.86625 320.327437 251.284375 320.90275 C 250.83375 321.353375 249.761875 322.09275 249.015938 321.530562 C 248.626562 320.089 249.260937 318.12025 250.328438 317.435563 z M 261.306953 322.727125 C 261.628516 322.659312 262.031016 322.727125 262.181953 322.536812 C 262.304453 322.379313 262.216953 322.070875 262.216953 321.819313 C 262.223516 319.951188 262.722266 317.544938 261.586953 316.007125 C 261.223828 315.514937 260.451641 314.989937 259.679453 315.009625 C 258.434766 315.038063 257.868203 315.919625 257.308203 316.724625 C 257.295078 316.438063 257.253516 316.171187 257.150703 315.974312 C 256.912266 315.849625 256.459453 315.974312 256.240703 316.068375 C 256.056953 317.264937 256.146641 319.343062 256.091953 320.848063 C 256.076641 321.21775 255.851328 322.447125 256.179453 322.727125 C 256.404766 322.919625 257.076328 322.858375 257.211953 322.694313 C 257.349766 322.5215 257.286328 322.228375 257.308203 321.941813 C 257.395703 320.635875 257.382578 319.609938 257.868203 318.413375 C 258.170078 317.676188 258.926953 315.803688 260.116953 316.350563 C 261.114453 316.80775 261.191016 318.702125 261.088203 320.163375 C 261.020391 321.128062 260.760078 322.18025 261.306953 322.727125 z M 265.278086 322.768687 C 265.525273 322.679 265.750586 322.816813 265.975898 322.816813 C 266.577461 322.816813 267.179023 322.49525 267.581523 322.186812 C 267.931523 321.919938 268.334023 321.545875 268.484961 321.163063 C 268.697148 320.616188 268.655586 319.780562 268.504648 319.288375 C 268.408398 318.975563 268.012461 318.503062 267.658086 318.43525 C 267.472148 318.40025 267.095898 318.406813 266.850898 318.483375 C 266.358711 318.638688 265.100898 319.500563 265.100898 318.43525 C 265.100898 317.811812 265.647773 317.21025 266.126836 317.129313 C 266.509648 317.068062 266.986523 317.258375 267.179023 317.380875 C 267.336523 317.483687 267.356211 317.695875 267.555273 317.709 C 267.719336 317.724312 268.108711 317.396187 268.128398 317.203688 C 268.134961 317.107438 268.073711 316.943375 268.034336 316.882125 C 267.760898 316.459938 266.899023 316.171187 266.378398 316.103375 C 265.792148 316.022438 265.017773 316.575875 264.753086 316.93025 C 264.595586 317.142437 264.383398 317.396187 264.300273 317.634625 C 264.013711 318.483375 264.116523 319.249 264.676523 319.760875 C 265.531836 320.259625 266.522773 319.664625 267.301523 319.384625 C 267.651523 319.638375 267.745586 320.382125 267.555273 320.8415 C 267.507148 320.950875 267.314648 321.154313 267.227148 321.237437 C 267.069648 321.381813 266.741523 321.6465 266.454961 321.74275 C 266.111523 321.852125 265.409336 321.86525 265.175273 321.537125 C 264.971836 321.250563 264.991523 320.764937 264.724648 320.690562 C 264.534336 320.635875 264.306836 320.880875 264.074961 320.964 C 263.952461 321.784312 264.444648 322.193375 264.827461 322.5915 C 264.998086 322.624312 265.149023 322.685563 265.278086 322.768687 z M 271.759922 321.674937 C 271.116797 320.089 271.423047 317.991188 271.506172 316.164625 C 271.567422 314.845562 271.779609 313.506813 271.814609 312.27525 C 271.731484 312.124312 271.676797 311.947125 271.608984 311.789625 C 271.403359 311.702125 271.197734 311.605875 270.917734 311.584 C 270.618047 311.625563 270.001172 311.831187 269.994609 312.194313 C 269.988047 312.43275 270.138984 312.74775 270.351172 312.787125 C 270.548047 312.828688 270.624609 312.658062 270.788672 312.706187 C 270.747109 313.266188 270.650859 313.880875 270.611484 314.524 C 270.569922 315.132125 270.576484 315.77525 270.508672 316.3965 C 270.309609 318.1815 270.219922 319.6515 270.583047 321.163063 C 270.727422 321.755875 270.821484 322.366188 271.197734 322.646187 C 271.615547 322.952437 272.381172 322.685563 272.477422 322.234938 C 272.551797 321.874 272.101172 321.517437 271.759922 321.674937 z M 279.127422 317.162125 C 279.079297 317.0615 278.902109 317.100875 278.799297 317.05275 C 278.396797 316.514625 277.766797 316.068375 276.837109 316.096812 C 274.568672 316.158062 273.358984 318.68025 273.365547 320.880875 C 273.365547 321.257125 273.439922 321.755875 273.665234 322.077437 C 273.947422 322.475563 274.369609 322.685563 274.787422 322.816813 C 276.708047 322.823375 277.541484 321.749312 278.390234 320.690562 C 278.657109 321.62025 279.059609 323.029 280.085547 322.762125 C 280.439922 322.482125 280.365547 321.764625 279.921484 321.694625 C 279.558359 321.018687 279.306797 320.069313 279.236797 319.104625 C 279.197422 318.448375 279.352734 317.750563 279.127422 317.162125 z M 275.881172 317.435563 C 276.537422 317.019938 277.618047 317.074625 278.116797 317.573375 C 278.048984 317.9365 278.158359 318.428688 278.116797 318.748063 C 278.027109 319.452437 277.418984 320.327437 276.837109 320.90275 C 276.386484 321.353375 275.314609 322.09275 274.568672 321.530562 C 274.179297 320.089 274.813672 318.12025 275.881172 317.435563 z M 284.508125 314.928688 C 284.746562 313.915875 284.971875 312.706187 284.768438 311.728375 C 284.549688 311.584 284.221563 311.551187 284.08375 311.632125 C 283.379375 312.049937 283.495313 314.073375 283.202187 314.928688 C 282.504375 315.029313 281.754062 314.764625 281.24 315.029313 C 281.191875 315.30275 281.034375 315.788375 281.24 316.007125 C 281.657812 316.241188 282.327187 316.219313 282.970312 316.232438 C 282.941875 316.7115 282.8325 317.422438 282.80625 317.9365 C 282.723125 319.548687 282.716563 321.600563 283.626562 322.405562 C 284.260938 322.974312 285.499062 322.81025 286.3325 322.536812 C 286.6125 322.447125 286.940625 322.399 287.085 322.2765 C 287.371562 322.029313 287.18125 321.469313 286.98875 321.202437 C 286.339063 320.977125 285.260625 321.825875 284.604375 321.49775 C 284.20625 321.298687 284.151563 320.382125 284.112188 319.828688 C 284.029063 318.673687 284.166875 317.232125 284.27625 316.232438 C 285.09 316.1865 285.888438 316.3965 286.756875 316.267437 C 287.036875 316.042125 286.934062 315.427437 286.756875 315.125563 C 286.100625 314.968062 285.23875 315.009625 284.508125 314.928688 z M 291.405312 315.2415 C 290.762187 315.269937 290.08625 315.733687 289.729688 316.096812 C 289.594063 316.232438 289.471563 316.479625 289.3075 316.691813 C 288.854688 317.286812 288.425937 318.271187 288.316562 319.124312 C 288.130625 320.546187 288.65125 321.954937 289.443125 322.475563 C 289.594063 322.569625 289.957187 322.749 290.1825 322.781813 C 290.886875 322.884625 291.775 322.536812 292.280312 322.21525 C 292.901562 321.819313 293.538125 321.128062 293.811562 320.484938 C 294.316875 319.303688 294.098125 317.730875 293.58625 316.801188 C 293.415625 316.49275 293.161875 316.260875 292.901562 316.007125 C 292.464062 315.584938 292.026563 315.21525 291.405312 315.2415 z M 289.9025 317.737437 C 290.099375 317.374312 290.83875 316.37025 291.405312 316.350563 C 291.411875 316.350563 291.43375 316.309 291.46 316.322125 C 292.341563 316.704937 292.99125 317.676188 292.99125 319.043375 C 292.99125 319.809 292.573437 320.498063 292.109688 320.944313 C 291.698438 321.34025 290.865 321.784312 290.324687 321.6465 C 289.970312 321.559 289.729688 321.195875 289.61375 320.915875 C 289.24625 320.02775 289.449687 318.551188 289.9025 317.737437 z M 299.978125 316.827437 C 299.95625 316.978375 300.045937 317.019938 300.0875 317.107438 C 300.750312 317.56025 301.2775 317.068062 301.091563 316.376812 C 300.914375 316.103375 300.654063 315.913063 300.312812 315.794938 C 299.096563 315.385875 296.887187 315.768687 296.346875 316.575875 C 296.224375 316.383375 295.684062 316.350563 295.487188 316.49275 C 295.3625 316.582438 295.329687 316.882125 295.316563 317.135875 C 295.275 317.827125 295.37125 318.702125 295.316563 319.364937 C 295.21375 320.607438 295.21375 321.797438 295.342812 322.549937 C 295.465312 322.679 295.609687 322.781813 295.760625 322.884625 C 295.964062 322.8365 295.950938 322.843062 296.182812 322.858375 C 296.300938 322.762125 296.381875 322.630875 296.49125 322.5215 C 296.395 321.86525 296.484687 321.250563 296.545937 320.513375 C 296.642187 319.349625 296.635625 318.107125 297.127813 317.299937 C 297.668125 316.724625 298.945625 316.656813 299.978125 316.827437 z M 303.77125 322.768687 C 304.018438 322.679 304.24375 322.816813 304.469063 322.816813 C 305.070625 322.816813 305.672188 322.49525 306.074687 322.186812 C 306.424688 321.919938 306.827187 321.545875 306.978125 321.163063 C 307.190313 320.616188 307.14875 319.780562 306.997813 319.288375 C 306.901562 318.975563 306.505625 318.503062 306.15125 318.43525 C 305.965312 318.40025 305.589062 318.406813 305.344063 318.483375 C 304.851875 318.638688 303.594063 319.500563 303.594063 318.43525 C 303.594063 317.811812 304.140938 317.21025 304.62 317.129313 C 305.002813 317.068062 305.479687 317.258375 305.672188 317.380875 C 305.829687 317.483687 305.849375 317.695875 306.048437 317.709 C 306.2125 317.724312 306.601875 317.396187 306.621562 317.203688 C 306.628125 317.107438 306.566875 316.943375 306.5275 316.882125 C 306.254063 316.459938 305.392187 316.171187 304.871562 316.103375 C 304.285313 316.022438 303.510937 316.575875 303.24625 316.93025 C 303.08875 317.142437 302.876562 317.396187 302.793437 317.634625 C 302.506875 318.483375 302.609688 319.249 303.169688 319.760875 C 304.025 320.259625 305.015938 319.664625 305.794688 319.384625 C 306.144688 319.638375 306.23875 320.382125 306.048437 320.8415 C 306.000313 320.950875 305.807812 321.154313 305.720312 321.237437 C 305.562813 321.381813 305.234688 321.6465 304.948125 321.74275 C 304.604687 321.852125 303.9025 321.86525 303.668437 321.537125 C 303.465 321.250563 303.484688 320.764937 303.217812 320.690562 C 303.0275 320.635875 302.8 320.880875 302.568125 320.964 C 302.445625 321.784312 302.937813 322.193375 303.320625 322.5915 C 303.49125 322.624312 303.642187 322.685563 303.77125 322.768687 z " + style="stroke: #ffffff; stroke-width: 4" + id="path5" /> + <path + d="M 171.004219 322.974312 C 172.165781 322.974312 172.165781 320.854625 172.165781 320.143687 C 172.165781 319.15275 171.995156 318.168375 171.995156 317.162125 C 171.995156 316.013688 172.124219 314.86525 172.124219 313.703688 C 172.124219 313.581187 172.124219 313.095562 172.084844 312.631813 C 172.043281 312.200875 171.940469 311.708687 171.686719 311.708687 C 171.181406 311.708687 170.647656 311.885875 170.566719 312.487437 C 170.457344 313.34275 170.483594 314.279 170.483594 315.132125 L 170.498906 317.05275 C 170.512031 318.017437 170.737344 319.014937 170.737344 319.99275 C 170.737344 320.005875 170.737344 320.124 170.724219 320.218062 C 170.724219 320.314312 170.724219 320.410563 170.682656 320.410563 C 170.586406 320.410563 170.437656 320.060563 170.299844 319.71275 C 170.164219 319.349625 170.032969 318.966813 170.006719 318.885875 C 169.540781 317.599625 166.957344 312.568375 165.487344 312.568375 C 164.564219 312.568375 164.564219 314.559 164.564219 315.105875 C 164.564219 317.286812 164.673594 319.480875 164.673594 321.661812 C 164.673594 322.167125 165.139531 322.987437 165.725781 322.987437 C 166.382031 322.987437 166.436719 321.819313 166.436719 321.353375 C 166.436719 320.349312 166.287969 319.343062 166.287969 318.339 C 166.287969 317.389625 166.075781 316.444625 166.075781 315.482125 C 166.075781 315.466813 166.047344 315.208687 166.102031 315.208687 C 166.465156 315.208687 168.427344 319.391188 168.707344 320.034312 C 169.028906 320.8065 170.000156 322.974312 171.004219 322.974312 z M 174.988477 316.096812 C 174.367227 316.424937 174.209727 317.450875 174.058789 318.297438 C 173.691289 320.375563 173.697852 323.05525 176.261602 322.794938 C 177.230664 322.700875 178.256602 322.186812 178.845039 321.456187 C 179.144727 321.0865 179.433477 320.506813 179.520977 320.054 C 179.733164 318.966813 179.426914 317.881813 179.234414 317.05275 C 179.166602 316.766188 179.118477 316.4665 178.871289 316.383375 C 178.652539 316.309 178.236914 316.444625 178.147227 316.61525 C 178.005039 316.888688 178.324414 317.5865 178.407539 317.96275 C 178.510352 318.448375 178.571602 319.104625 178.536602 319.6165 C 178.455664 320.74525 177.410039 321.661812 176.261602 321.764625 C 175.988164 321.790875 175.625039 321.810563 175.406289 321.709938 C 175.132852 321.578688 174.997227 321.108375 174.942539 320.751812 C 174.675664 318.934 175.338477 317.846812 175.480664 316.357125 C 175.371289 316.21275 175.152539 316.17775 174.988477 316.096812 z M 186.200781 322.399 C 186.467656 321.749312 186.555156 320.764937 186.686406 319.83525 C 186.808906 318.947125 186.924844 317.969313 187.342656 317.444313 C 187.513281 317.232125 187.944219 316.904 188.278906 316.93025 C 188.838906 316.971812 189.234844 317.763688 189.221719 318.413375 C 189.215156 318.721812 189.051094 319.207438 188.906719 319.609938 C 188.703281 320.191813 188.462656 320.896187 188.510781 321.626812 C 188.539219 322.003062 188.729531 322.61775 189.051094 322.794938 C 189.385781 322.980875 189.864844 322.685563 189.932656 322.37275 C 189.993906 322.09275 189.652656 321.893687 189.617656 321.572125 C 189.597969 321.408062 189.639531 321.14775 189.672344 320.977125 C 189.823281 320.191813 190.295781 319.268687 190.357031 318.4965 C 190.411719 317.853375 190.157969 317.177437 189.851719 316.733375 C 189.420781 316.1165 188.639844 315.598062 187.710156 315.878062 C 187.130469 316.05525 186.767344 316.418375 186.342969 316.958687 C 186.310156 316.68525 186.097969 316.376812 185.914219 316.158062 C 185.120156 315.61775 183.794531 316.035563 183.241094 316.704937 C 183.061719 316.917125 183.007031 317.170875 182.810156 317.299937 C 182.823281 316.998063 182.816719 316.05525 182.530156 315.904313 C 182.331094 315.803688 182.022656 315.994 181.757969 316.022438 C 181.523906 316.389937 181.668281 316.875563 181.703281 317.389625 C 181.784219 318.52275 181.893594 319.979625 181.812656 321.06025 C 181.777656 321.482438 181.539219 321.919938 181.585156 322.256813 C 181.613594 322.466813 181.845469 322.630875 181.928594 322.768687 C 182.398906 322.93275 182.672344 322.685563 182.871406 322.256813 C 182.952344 320.5265 183.308906 318.831187 184.032969 317.499 C 184.341406 317.28025 184.586406 317.013375 185.148594 317.046187 C 185.640781 318.255875 184.975781 320.375563 185.148594 321.858687 C 185.181406 322.18025 185.380469 322.37275 185.516094 322.514937 C 185.782969 322.5215 185.995156 322.453688 186.200781 322.399 z M 192.483555 317.334938 C 192.49668 316.534312 192.55793 315.173687 192.483555 314.224312 C 192.455117 313.889625 192.40043 313.137125 192.100742 313.075875 C 191.92793 313.040875 191.763867 313.178688 191.615117 313.178688 C 191.28043 314.018687 191.62168 315.420875 191.512305 316.77275 C 191.435742 317.689312 191.36793 318.654 191.409492 319.55525 C 191.457617 320.568062 191.483867 322.105875 192.249492 321.90025 C 192.448555 321.845562 192.61918 321.810563 192.686992 321.62025 C 193.645117 322.193375 195.272617 322.18025 196.106055 321.491188 C 196.33793 321.298687 196.447305 321.053688 196.666055 320.880875 C 196.974492 320.191813 197.46668 319.200875 197.27418 318.249312 C 197.18668 317.80525 196.95918 317.422438 196.788555 317.05275 C 196.270117 316.499312 195.791055 316.048687 194.826367 316.035563 C 193.719492 316.022438 192.966992 316.704937 192.483555 317.334938 z M 194.34293 321.06025 C 193.699805 321.066813 193.17918 320.799937 192.763555 320.471812 C 192.74168 318.796187 193.207617 317.464 194.417305 317.081187 C 194.732305 316.978375 195.327305 317.100875 195.546055 317.232125 C 196.701055 317.9365 196.318242 320.178688 195.285742 320.826188 C 195.12168 320.929 194.58793 321.06025 194.34293 321.06025 z M 199.577617 319.522438 C 200.24918 319.631813 201.041055 319.535563 201.957617 319.459 C 202.955117 319.378062 203.816992 319.522438 204.21293 318.947125 C 204.547617 317.921187 204.261055 316.698375 203.49543 316.1165 C 202.941992 315.694313 201.935742 315.412125 201.170117 315.604625 C 200.658242 315.733687 199.831367 316.274 199.393867 316.814312 C 198.608555 317.779 197.998242 319.67775 198.615117 320.964 C 198.96293 321.517437 199.27793 321.983375 199.844492 322.289625 C 200.822305 322.823375 201.951055 322.563063 202.858867 322.263375 C 203.289805 322.119 203.77543 321.954937 204.061992 321.723063 C 204.241367 321.578688 204.425117 321.292125 204.363867 321.0865 C 204.315742 320.909312 203.904492 320.539625 203.646367 320.546187 C 203.421055 320.55275 203.24168 320.8415 203.009805 320.964 C 202.395117 321.298687 201.27293 321.668375 200.481055 321.333687 C 199.83793 321.06025 199.551367 320.355875 199.577617 319.522438 z M 202.55918 316.93025 C 202.86543 317.094313 203.235117 317.599625 203.160742 318.229625 C 201.99918 318.24275 200.96668 318.345562 199.818242 318.43525 C 200.172617 317.553688 201.294805 316.260875 202.55918 316.93025 z M 210.160742 316.827437 C 210.138867 316.978375 210.228555 317.019938 210.270117 317.107438 C 210.93293 317.56025 211.460117 317.068062 211.27418 316.376812 C 211.096992 316.103375 210.83668 315.913063 210.49543 315.794938 C 209.27918 315.385875 207.069805 315.768687 206.529492 316.575875 C 206.406992 316.383375 205.86668 316.350563 205.669805 316.49275 C 205.545117 316.582438 205.512305 316.882125 205.49918 317.135875 C 205.457617 317.827125 205.553867 318.702125 205.49918 319.364937 C 205.396367 320.607438 205.396367 321.797438 205.52543 322.549937 C 205.64793 322.679 205.792305 322.781813 205.943242 322.884625 C 206.14668 322.8365 206.133555 322.843062 206.36543 322.858375 C 206.483555 322.762125 206.564492 322.630875 206.673867 322.5215 C 206.577617 321.86525 206.667305 321.250563 206.728555 320.513375 C 206.824805 319.349625 206.818242 318.107125 207.31043 317.299937 C 207.850742 316.724625 209.128242 316.656813 210.160742 316.827437 z M 219.08793 315.2415 C 218.444805 315.269937 217.768867 315.733687 217.412305 316.096812 C 217.27668 316.232438 217.15418 316.479625 216.990117 316.691813 C 216.537305 317.286812 216.108555 318.271187 215.99918 319.124312 C 215.813242 320.546187 216.333867 321.954937 217.125742 322.475563 C 217.27668 322.569625 217.639805 322.749 217.865117 322.781813 C 218.569492 322.884625 219.457617 322.536812 219.96293 322.21525 C 220.58418 321.819313 221.220742 321.128062 221.49418 320.484938 C 221.999492 319.303688 221.780742 317.730875 221.268867 316.801188 C 221.098242 316.49275 220.844492 316.260875 220.58418 316.007125 C 220.14668 315.584938 219.70918 315.21525 219.08793 315.2415 z M 217.585117 317.737437 C 217.781992 317.374312 218.521367 316.37025 219.08793 316.350563 C 219.094492 316.350563 219.116367 316.309 219.142617 316.322125 C 220.02418 316.704937 220.673867 317.676188 220.673867 319.043375 C 220.673867 319.809 220.256055 320.498063 219.792305 320.944313 C 219.381055 321.34025 218.547617 321.784312 218.007305 321.6465 C 217.65293 321.559 217.412305 321.195875 217.296367 320.915875 C 216.928867 320.02775 217.132305 318.551188 217.585117 317.737437 z M 226.116367 312.8965 C 226.538555 313.082437 226.99793 313.334 227.483555 313.581187 C 227.912305 313.799937 228.522617 314.237437 228.883555 314.163063 C 229.178867 314.099625 229.533242 313.404 229.436992 313.191812 C 229.288242 312.87025 228.365117 312.644937 227.975742 312.439312 C 227.345742 312.111187 226.888555 311.796187 226.409492 311.59275 C 225.96543 311.55775 225.534492 311.647438 225.206367 311.885875 C 224.43418 312.828688 224.33793 314.237437 224.228555 315.727125 C 223.292305 315.646187 222.636055 315.823375 222.92918 316.834 C 223.169805 317.107438 223.83918 316.936812 224.228555 317.0615 C 224.167305 318.345562 224.427617 319.343062 224.427617 320.539625 C 224.427617 321.388375 224.228555 322.289625 224.65293 322.788375 C 224.913242 322.788375 225.18668 322.803688 225.40543 322.755562 C 225.521367 322.5915 225.637305 322.392437 225.663555 322.202125 C 225.910742 320.629313 225.425117 318.693375 225.569492 317.129313 C 226.18418 317.013375 227.091992 317.081187 227.448555 316.669938 C 227.74168 316.33525 227.544805 315.891188 227.256055 315.694313 C 226.86668 315.420875 226.696055 315.61775 226.348242 315.727125 C 226.094492 315.81025 225.84293 315.794938 225.534492 315.858375 C 225.541055 315.324625 225.602305 314.784312 225.691992 314.263688 C 225.779492 313.758375 225.74668 313.178688 226.116367 312.8965 z M 237.258125 314.928688 C 237.496562 313.915875 237.721875 312.706187 237.518438 311.728375 C 237.299688 311.584 236.971563 311.551187 236.83375 311.632125 C 236.129375 312.049937 236.245312 314.073375 235.952187 314.928688 C 235.254375 315.029313 234.504062 314.764625 233.99 315.029313 C 233.941875 315.30275 233.784375 315.788375 233.99 316.007125 C 234.407812 316.241188 235.077187 316.219313 235.720312 316.232438 C 235.691875 316.7115 235.5825 317.422438 235.55625 317.9365 C 235.473125 319.548687 235.466562 321.600563 236.376562 322.405562 C 237.010937 322.974312 238.249062 322.81025 239.0825 322.536812 C 239.3625 322.447125 239.690625 322.399 239.835 322.2765 C 240.121562 322.029313 239.93125 321.469313 239.73875 321.202437 C 239.089062 320.977125 238.010625 321.825875 237.354375 321.49775 C 236.95625 321.298687 236.901562 320.382125 236.862188 319.828688 C 236.779062 318.673687 236.916875 317.232125 237.02625 316.232438 C 237.84 316.1865 238.638437 316.3965 239.506875 316.267437 C 239.786875 316.042125 239.684062 315.427437 239.506875 315.125563 C 238.850625 314.968062 237.98875 315.009625 237.258125 314.928688 z M 245.728125 316.827437 C 245.70625 316.978375 245.795937 317.019938 245.8375 317.107438 C 246.500313 317.56025 247.0275 317.068062 246.841562 316.376812 C 246.664375 316.103375 246.404062 315.913063 246.062813 315.794938 C 244.846563 315.385875 242.637187 315.768687 242.096875 316.575875 C 241.974375 316.383375 241.434062 316.350563 241.237188 316.49275 C 241.1125 316.582438 241.079687 316.882125 241.066562 317.135875 C 241.025 317.827125 241.12125 318.702125 241.066562 319.364937 C 240.96375 320.607438 240.96375 321.797438 241.092812 322.549937 C 241.215312 322.679 241.359688 322.781813 241.510625 322.884625 C 241.714062 322.8365 241.700937 322.843062 241.932812 322.858375 C 242.050937 322.762125 242.131875 322.630875 242.24125 322.5215 C 242.145 321.86525 242.234688 321.250563 242.295937 320.513375 C 242.392187 319.349625 242.385625 318.107125 242.877813 317.299937 C 243.418125 316.724625 244.695625 316.656813 245.728125 316.827437 z M 253.574687 317.162125 C 253.526562 317.0615 253.349375 317.100875 253.246562 317.05275 C 252.844063 316.514625 252.214062 316.068375 251.284375 316.096812 C 249.015938 316.158062 247.80625 318.68025 247.812813 320.880875 C 247.812813 321.257125 247.887187 321.755875 248.1125 322.077437 C 248.394687 322.475563 248.816875 322.685563 249.234688 322.816813 C 251.155312 322.823375 251.98875 321.749312 252.8375 320.690562 C 253.104375 321.62025 253.506875 323.029 254.532812 322.762125 C 254.887187 322.482125 254.812813 321.764625 254.36875 321.694625 C 254.005625 321.018687 253.754062 320.069313 253.684062 319.104625 C 253.644687 318.448375 253.8 317.750563 253.574687 317.162125 z M 250.328438 317.435563 C 250.984688 317.019938 252.065313 317.074625 252.564062 317.573375 C 252.49625 317.9365 252.605625 318.428688 252.564062 318.748063 C 252.474375 319.452437 251.86625 320.327437 251.284375 320.90275 C 250.83375 321.353375 249.761875 322.09275 249.015938 321.530562 C 248.626562 320.089 249.260937 318.12025 250.328438 317.435563 z M 261.306953 322.727125 C 261.628516 322.659312 262.031016 322.727125 262.181953 322.536812 C 262.304453 322.379313 262.216953 322.070875 262.216953 321.819313 C 262.223516 319.951188 262.722266 317.544938 261.586953 316.007125 C 261.223828 315.514937 260.451641 314.989937 259.679453 315.009625 C 258.434766 315.038063 257.868203 315.919625 257.308203 316.724625 C 257.295078 316.438063 257.253516 316.171187 257.150703 315.974312 C 256.912266 315.849625 256.459453 315.974312 256.240703 316.068375 C 256.056953 317.264937 256.146641 319.343062 256.091953 320.848063 C 256.076641 321.21775 255.851328 322.447125 256.179453 322.727125 C 256.404766 322.919625 257.076328 322.858375 257.211953 322.694313 C 257.349766 322.5215 257.286328 322.228375 257.308203 321.941813 C 257.395703 320.635875 257.382578 319.609938 257.868203 318.413375 C 258.170078 317.676188 258.926953 315.803688 260.116953 316.350563 C 261.114453 316.80775 261.191016 318.702125 261.088203 320.163375 C 261.020391 321.128062 260.760078 322.18025 261.306953 322.727125 z M 265.278086 322.768687 C 265.525273 322.679 265.750586 322.816813 265.975898 322.816813 C 266.577461 322.816813 267.179023 322.49525 267.581523 322.186812 C 267.931523 321.919938 268.334023 321.545875 268.484961 321.163063 C 268.697148 320.616188 268.655586 319.780562 268.504648 319.288375 C 268.408398 318.975563 268.012461 318.503062 267.658086 318.43525 C 267.472148 318.40025 267.095898 318.406813 266.850898 318.483375 C 266.358711 318.638688 265.100898 319.500563 265.100898 318.43525 C 265.100898 317.811812 265.647773 317.21025 266.126836 317.129313 C 266.509648 317.068062 266.986523 317.258375 267.179023 317.380875 C 267.336523 317.483687 267.356211 317.695875 267.555273 317.709 C 267.719336 317.724312 268.108711 317.396187 268.128398 317.203688 C 268.134961 317.107438 268.073711 316.943375 268.034336 316.882125 C 267.760898 316.459938 266.899023 316.171187 266.378398 316.103375 C 265.792148 316.022438 265.017773 316.575875 264.753086 316.93025 C 264.595586 317.142437 264.383398 317.396187 264.300273 317.634625 C 264.013711 318.483375 264.116523 319.249 264.676523 319.760875 C 265.531836 320.259625 266.522773 319.664625 267.301523 319.384625 C 267.651523 319.638375 267.745586 320.382125 267.555273 320.8415 C 267.507148 320.950875 267.314648 321.154313 267.227148 321.237437 C 267.069648 321.381813 266.741523 321.6465 266.454961 321.74275 C 266.111523 321.852125 265.409336 321.86525 265.175273 321.537125 C 264.971836 321.250563 264.991523 320.764937 264.724648 320.690562 C 264.534336 320.635875 264.306836 320.880875 264.074961 320.964 C 263.952461 321.784312 264.444648 322.193375 264.827461 322.5915 C 264.998086 322.624312 265.149023 322.685563 265.278086 322.768687 z M 271.759922 321.674937 C 271.116797 320.089 271.423047 317.991188 271.506172 316.164625 C 271.567422 314.845562 271.779609 313.506813 271.814609 312.27525 C 271.731484 312.124312 271.676797 311.947125 271.608984 311.789625 C 271.403359 311.702125 271.197734 311.605875 270.917734 311.584 C 270.618047 311.625563 270.001172 311.831187 269.994609 312.194313 C 269.988047 312.43275 270.138984 312.74775 270.351172 312.787125 C 270.548047 312.828688 270.624609 312.658062 270.788672 312.706187 C 270.747109 313.266188 270.650859 313.880875 270.611484 314.524 C 270.569922 315.132125 270.576484 315.77525 270.508672 316.3965 C 270.309609 318.1815 270.219922 319.6515 270.583047 321.163063 C 270.727422 321.755875 270.821484 322.366188 271.197734 322.646187 C 271.615547 322.952437 272.381172 322.685563 272.477422 322.234938 C 272.551797 321.874 272.101172 321.517437 271.759922 321.674937 z M 279.127422 317.162125 C 279.079297 317.0615 278.902109 317.100875 278.799297 317.05275 C 278.396797 316.514625 277.766797 316.068375 276.837109 316.096812 C 274.568672 316.158062 273.358984 318.68025 273.365547 320.880875 C 273.365547 321.257125 273.439922 321.755875 273.665234 322.077437 C 273.947422 322.475563 274.369609 322.685563 274.787422 322.816813 C 276.708047 322.823375 277.541484 321.749312 278.390234 320.690562 C 278.657109 321.62025 279.059609 323.029 280.085547 322.762125 C 280.439922 322.482125 280.365547 321.764625 279.921484 321.694625 C 279.558359 321.018687 279.306797 320.069313 279.236797 319.104625 C 279.197422 318.448375 279.352734 317.750563 279.127422 317.162125 z M 275.881172 317.435563 C 276.537422 317.019938 277.618047 317.074625 278.116797 317.573375 C 278.048984 317.9365 278.158359 318.428688 278.116797 318.748063 C 278.027109 319.452437 277.418984 320.327437 276.837109 320.90275 C 276.386484 321.353375 275.314609 322.09275 274.568672 321.530562 C 274.179297 320.089 274.813672 318.12025 275.881172 317.435563 z M 284.508125 314.928688 C 284.746562 313.915875 284.971875 312.706187 284.768438 311.728375 C 284.549688 311.584 284.221563 311.551187 284.08375 311.632125 C 283.379375 312.049937 283.495313 314.073375 283.202187 314.928688 C 282.504375 315.029313 281.754062 314.764625 281.24 315.029313 C 281.191875 315.30275 281.034375 315.788375 281.24 316.007125 C 281.657812 316.241188 282.327187 316.219313 282.970312 316.232438 C 282.941875 316.7115 282.8325 317.422438 282.80625 317.9365 C 282.723125 319.548687 282.716563 321.600563 283.626562 322.405562 C 284.260938 322.974312 285.499062 322.81025 286.3325 322.536812 C 286.6125 322.447125 286.940625 322.399 287.085 322.2765 C 287.371562 322.029313 287.18125 321.469313 286.98875 321.202437 C 286.339063 320.977125 285.260625 321.825875 284.604375 321.49775 C 284.20625 321.298687 284.151563 320.382125 284.112188 319.828688 C 284.029063 318.673687 284.166875 317.232125 284.27625 316.232438 C 285.09 316.1865 285.888438 316.3965 286.756875 316.267437 C 287.036875 316.042125 286.934062 315.427437 286.756875 315.125563 C 286.100625 314.968062 285.23875 315.009625 284.508125 314.928688 z M 291.405312 315.2415 C 290.762187 315.269937 290.08625 315.733687 289.729688 316.096812 C 289.594063 316.232438 289.471563 316.479625 289.3075 316.691813 C 288.854688 317.286812 288.425937 318.271187 288.316562 319.124312 C 288.130625 320.546187 288.65125 321.954937 289.443125 322.475563 C 289.594063 322.569625 289.957187 322.749 290.1825 322.781813 C 290.886875 322.884625 291.775 322.536812 292.280312 322.21525 C 292.901562 321.819313 293.538125 321.128062 293.811562 320.484938 C 294.316875 319.303688 294.098125 317.730875 293.58625 316.801188 C 293.415625 316.49275 293.161875 316.260875 292.901562 316.007125 C 292.464062 315.584938 292.026563 315.21525 291.405312 315.2415 z M 289.9025 317.737437 C 290.099375 317.374312 290.83875 316.37025 291.405312 316.350563 C 291.411875 316.350563 291.43375 316.309 291.46 316.322125 C 292.341563 316.704937 292.99125 317.676188 292.99125 319.043375 C 292.99125 319.809 292.573437 320.498063 292.109688 320.944313 C 291.698438 321.34025 290.865 321.784312 290.324687 321.6465 C 289.970312 321.559 289.729688 321.195875 289.61375 320.915875 C 289.24625 320.02775 289.449687 318.551188 289.9025 317.737437 z M 299.978125 316.827437 C 299.95625 316.978375 300.045937 317.019938 300.0875 317.107438 C 300.750312 317.56025 301.2775 317.068062 301.091563 316.376812 C 300.914375 316.103375 300.654063 315.913063 300.312812 315.794938 C 299.096563 315.385875 296.887187 315.768687 296.346875 316.575875 C 296.224375 316.383375 295.684062 316.350563 295.487188 316.49275 C 295.3625 316.582438 295.329687 316.882125 295.316563 317.135875 C 295.275 317.827125 295.37125 318.702125 295.316563 319.364937 C 295.21375 320.607438 295.21375 321.797438 295.342812 322.549937 C 295.465312 322.679 295.609687 322.781813 295.760625 322.884625 C 295.964062 322.8365 295.950938 322.843062 296.182812 322.858375 C 296.300938 322.762125 296.381875 322.630875 296.49125 322.5215 C 296.395 321.86525 296.484687 321.250563 296.545937 320.513375 C 296.642187 319.349625 296.635625 318.107125 297.127813 317.299937 C 297.668125 316.724625 298.945625 316.656813 299.978125 316.827437 z M 303.77125 322.768687 C 304.018438 322.679 304.24375 322.816813 304.469063 322.816813 C 305.070625 322.816813 305.672188 322.49525 306.074687 322.186812 C 306.424688 321.919938 306.827187 321.545875 306.978125 321.163063 C 307.190313 320.616188 307.14875 319.780562 306.997813 319.288375 C 306.901562 318.975563 306.505625 318.503062 306.15125 318.43525 C 305.965312 318.40025 305.589062 318.406813 305.344063 318.483375 C 304.851875 318.638688 303.594063 319.500563 303.594063 318.43525 C 303.594063 317.811812 304.140938 317.21025 304.62 317.129313 C 305.002813 317.068062 305.479687 317.258375 305.672188 317.380875 C 305.829687 317.483687 305.849375 317.695875 306.048437 317.709 C 306.2125 317.724312 306.601875 317.396187 306.621562 317.203688 C 306.628125 317.107438 306.566875 316.943375 306.5275 316.882125 C 306.254063 316.459938 305.392187 316.171187 304.871562 316.103375 C 304.285313 316.022438 303.510937 316.575875 303.24625 316.93025 C 303.08875 317.142437 302.876562 317.396187 302.793437 317.634625 C 302.506875 318.483375 302.609688 319.249 303.169688 319.760875 C 304.025 320.259625 305.015938 319.664625 305.794688 319.384625 C 306.144688 319.638375 306.23875 320.382125 306.048437 320.8415 C 306.000313 320.950875 305.807812 321.154313 305.720312 321.237437 C 305.562813 321.381813 305.234688 321.6465 304.948125 321.74275 C 304.604687 321.852125 303.9025 321.86525 303.668437 321.537125 C 303.465 321.250563 303.484688 320.764937 303.217812 320.690562 C 303.0275 320.635875 302.8 320.880875 302.568125 320.964 C 302.445625 321.784312 302.937813 322.193375 303.320625 322.5915 C 303.49125 322.624312 303.642187 322.685563 303.77125 322.768687 z " + id="path6" /> + </g> + </g> + <g + id="matplotlib.axis_2"> + <g + id="text_2"> + <path + d="M 40.645625 230.911906 C 40.523125 230.323469 40.262812 229.811594 39.621875 229.811594 C 39.114375 229.811594 38.937188 230.638469 38.937188 230.986281 C 38.937188 231.082531 38.950312 231.172219 38.965625 231.253156 C 39.020312 231.561594 39.053125 232.108469 39.081562 232.749406 C 39.107812 233.405656 39.120937 234.164719 39.149375 234.890969 C 39.204062 236.358781 39.313437 237.774094 39.635 238.082531 C 39.805625 238.253156 40.09875 238.513469 40.37875 238.513469 C 40.88625 238.513469 40.899375 237.535656 40.899375 237.214094 C 40.899375 236.531594 40.770312 235.853469 40.770312 235.184094 C 40.770312 235.155656 40.770312 235.087844 40.783437 235.074719 C 40.879687 234.965344 43.277187 234.917219 43.627187 234.917219 C 45.000937 234.917219 46.368125 235.013469 47.755 235.013469 L 48.44625 235.013469 C 48.72625 235.000344 49.034687 234.971906 49.314687 234.917219 C 49.887813 234.820969 50.38875 234.582531 50.38875 234.035656 C 50.38875 233.460344 49.588125 233.405656 49.183437 233.392531 L 48.739375 233.392531 C 47.496875 233.392531 46.245625 233.591594 44.987812 233.591594 L 44.78875 233.591594 C 44.399375 233.591594 44.016562 233.530344 43.627187 233.530344 C 43.386562 233.530344 42.771875 233.530344 42.183437 233.515031 C 41.581875 233.501906 41.015313 233.475656 40.857812 233.392531 C 40.79 233.366281 40.755 233.228469 40.72875 233.044719 C 40.715625 232.874094 40.72875 232.688156 40.72875 232.620344 C 40.72875 232.408156 40.741875 232.147844 40.72875 231.841594 C 40.72875 231.546281 40.700312 231.218156 40.645625 230.911906 z M 44.200313 224.423781 C 44.35125 224.445656 44.392812 224.355969 44.480312 224.314406 C 44.933125 223.651594 44.440937 223.124406 43.749688 223.310344 C 43.47625 223.487531 43.285938 223.747844 43.167812 224.089094 C 42.75875 225.305344 43.141562 227.514719 43.94875 228.055031 C 43.75625 228.177531 43.723438 228.717844 43.865625 228.914719 C 43.955312 229.039406 44.255 229.072219 44.50875 229.085344 C 45.2 229.126906 46.075 229.030656 46.737812 229.085344 C 47.980312 229.188156 49.170313 229.188156 49.922812 229.059094 C 50.051875 228.936594 50.154688 228.792219 50.2575 228.641281 C 50.209375 228.437844 50.215938 228.450969 50.23125 228.219094 C 50.135 228.100969 50.00375 228.020031 49.894375 227.910656 C 49.238125 228.006906 48.623438 227.917219 47.88625 227.855969 C 46.7225 227.759719 45.48 227.766281 44.672812 227.274094 C 44.0975 226.733781 44.029688 225.456281 44.200313 224.423781 z M 44.535 216.577219 C 44.434375 216.625344 44.47375 216.802531 44.425625 216.905344 C 43.8875 217.307844 43.44125 217.937844 43.469687 218.867531 C 43.530938 221.135969 46.053125 222.345656 48.25375 222.339094 C 48.63 222.339094 49.12875 222.264719 49.450313 222.039406 C 49.848438 221.757219 50.058438 221.335031 50.189687 220.917219 C 50.19625 218.996594 49.122188 218.163156 48.063437 217.314406 C 48.993125 217.047531 50.401875 216.645031 50.135 215.619094 C 49.855 215.264719 49.1375 215.339094 49.0675 215.783156 C 48.391562 216.146281 47.442188 216.397844 46.4775 216.467844 C 45.82125 216.507219 45.123438 216.351906 44.535 216.577219 z M 44.808437 219.823469 C 44.392812 219.167219 44.4475 218.086594 44.94625 217.587844 C 45.309375 217.655656 45.801563 217.546281 46.120937 217.587844 C 46.825313 217.677531 47.700313 218.285656 48.275625 218.867531 C 48.72625 219.318156 49.465625 220.390031 48.903438 221.135969 C 47.461875 221.525344 45.493125 220.890969 44.808437 219.823469 z M 50.1 208.844953 C 50.032187 208.523391 50.1 208.120891 49.909688 207.969953 C 49.752187 207.847453 49.44375 207.934953 49.192188 207.934953 C 47.324063 207.928391 44.917812 207.429641 43.38 208.564953 C 42.887813 208.928078 42.362813 209.700266 42.3825 210.472453 C 42.410938 211.717141 43.2925 212.283703 44.0975 212.843703 C 43.810938 212.856828 43.544063 212.898391 43.347188 213.001203 C 43.2225 213.239641 43.347188 213.692453 43.44125 213.911203 C 44.637813 214.094953 46.715938 214.005266 48.220937 214.059953 C 48.590625 214.075266 49.82 214.300578 50.1 213.972453 C 50.2925 213.747141 50.23125 213.075578 50.067188 212.939953 C 49.894375 212.802141 49.60125 212.865578 49.314687 212.843703 C 48.00875 212.756203 46.982813 212.769328 45.78625 212.283703 C 45.049062 211.981828 43.176563 211.224953 43.723438 210.034953 C 44.180625 209.037453 46.075 208.960891 47.53625 209.063703 C 48.500937 209.131516 49.553125 209.391828 50.1 208.844953 z M 50.141562 204.87382 C 50.051875 204.626633 50.189687 204.40132 50.189687 204.176008 C 50.189687 203.574445 49.868125 202.972883 49.559688 202.570383 C 49.292813 202.220383 48.91875 201.817883 48.535938 201.666945 C 47.989063 201.454758 47.153438 201.49632 46.66125 201.647258 C 46.348438 201.743508 45.875937 202.139445 45.808125 202.49382 C 45.773125 202.679758 45.779688 203.056008 45.85625 203.301008 C 46.011562 203.793195 46.873438 205.051008 45.808125 205.051008 C 45.184688 205.051008 44.583125 204.504133 44.502187 204.02507 C 44.440938 203.642258 44.63125 203.165383 44.75375 202.972883 C 44.856563 202.815383 45.06875 202.795695 45.081875 202.596633 C 45.097188 202.43257 44.769063 202.043195 44.576563 202.023508 C 44.480313 202.016945 44.31625 202.078195 44.255 202.11757 C 43.832813 202.391008 43.544063 203.252883 43.47625 203.773508 C 43.395313 204.359758 43.94875 205.134133 44.303125 205.39882 C 44.515313 205.55632 44.769063 205.768508 45.0075 205.851633 C 45.85625 206.138195 46.621875 206.035383 47.13375 205.475383 C 47.6325 204.62007 47.0375 203.629133 46.7575 202.850383 C 47.01125 202.500383 47.755 202.40632 48.214375 202.596633 C 48.32375 202.644758 48.527188 202.837258 48.610312 202.924758 C 48.754688 203.082258 49.019375 203.410383 49.115625 203.696945 C 49.225 204.040383 49.238125 204.74257 48.91 204.976633 C 48.623438 205.18007 48.137813 205.160383 48.063437 205.427258 C 48.00875 205.61757 48.25375 205.84507 48.336875 206.076945 C 49.157187 206.199445 49.56625 205.707258 49.964375 205.324445 C 49.997188 205.15382 50.058438 205.002883 50.141562 204.87382 z M 49.047812 198.391984 C 47.461875 199.035109 45.364063 198.728859 43.5375 198.645734 C 42.218438 198.584484 40.879688 198.372297 39.648125 198.337297 C 39.497188 198.420422 39.32 198.475109 39.1625 198.542922 C 39.075 198.748547 38.97875 198.954172 38.956875 199.234172 C 38.998438 199.533859 39.204062 200.150734 39.567188 200.157297 C 39.805625 200.163859 40.120625 200.012922 40.16 199.800734 C 40.201563 199.603859 40.030938 199.527297 40.079062 199.363234 C 40.639063 199.404797 41.25375 199.501047 41.896875 199.540422 C 42.505 199.581984 43.148125 199.575422 43.769375 199.643234 C 45.554375 199.842297 47.024375 199.931984 48.535938 199.568859 C 49.12875 199.424484 49.739063 199.330422 50.019063 198.954172 C 50.325313 198.536359 50.058438 197.770734 49.607813 197.674484 C 49.246875 197.600109 48.890313 198.050734 49.047812 198.391984 z M 44.535 191.024484 C 44.434375 191.072609 44.47375 191.249797 44.425625 191.352609 C 43.8875 191.755109 43.44125 192.385109 43.469687 193.314797 C 43.530938 195.583234 46.053125 196.792922 48.25375 196.786359 C 48.63 196.786359 49.12875 196.711984 49.450313 196.486672 C 49.848438 196.204484 50.058438 195.782297 50.189688 195.364484 C 50.19625 193.443859 49.122188 192.610422 48.063437 191.761672 C 48.993125 191.494797 50.401875 191.092297 50.135 190.066359 C 49.855 189.711984 49.1375 189.786359 49.0675 190.230422 C 48.391562 190.593547 47.442188 190.845109 46.4775 190.915109 C 45.82125 190.954484 45.123438 190.799172 44.535 191.024484 z M 44.808438 194.270734 C 44.392813 193.614484 44.4475 192.533859 44.94625 192.035109 C 45.309375 192.102922 45.801563 191.993547 46.120938 192.035109 C 46.825313 192.124797 47.700313 192.732922 48.275625 193.314797 C 48.72625 193.765422 49.465625 194.837297 48.903438 195.583234 C 47.461875 195.972609 45.493125 195.338234 44.808438 194.270734 z M 42.301563 185.643781 C 41.28875 185.405344 40.079062 185.180031 39.10125 185.383469 C 38.956875 185.602219 38.924063 185.930344 39.005 186.068156 C 39.422812 186.772531 41.44625 186.656594 42.301563 186.949719 C 42.402188 187.647531 42.1375 188.397844 42.402188 188.911906 C 42.675625 188.960031 43.16125 189.117531 43.38 188.911906 C 43.614063 188.494094 43.592188 187.824719 43.605313 187.181594 C 44.084375 187.210031 44.795313 187.319406 45.309375 187.345656 C 46.921563 187.428781 48.973438 187.435344 49.778438 186.525344 C 50.347188 185.890969 50.183125 184.652844 49.909688 183.819406 C 49.82 183.539406 49.771875 183.211281 49.649375 183.066906 C 49.402188 182.780344 48.842188 182.970656 48.575313 183.163156 C 48.35 183.812844 49.19875 184.891281 48.870625 185.547531 C 48.671563 185.945656 47.755 186.000344 47.201563 186.039719 C 46.046563 186.122844 44.605 185.985031 43.605313 185.875656 C 43.559375 185.061906 43.769375 184.263469 43.640313 183.395031 C 43.415 183.115031 42.800313 183.217844 42.498438 183.395031 C 42.340938 184.051281 42.3825 184.913156 42.301563 185.643781 z M 42.614375 178.746594 C 42.642813 179.389719 43.106563 180.065656 43.469687 180.422219 C 43.605313 180.557844 43.8525 180.680344 44.064688 180.844406 C 44.659688 181.297219 45.644063 181.725969 46.497188 181.835344 C 47.919063 182.021281 49.327813 181.500656 49.848438 180.708781 C 49.9425 180.557844 50.121875 180.194719 50.154688 179.969406 C 50.2575 179.265031 49.909688 178.376906 49.588125 177.871594 C 49.192188 177.250344 48.500938 176.613781 47.857813 176.340344 C 46.676563 175.835031 45.10375 176.053781 44.174063 176.565656 C 43.865625 176.736281 43.63375 176.990031 43.38 177.250344 C 42.957813 177.687844 42.588125 178.125344 42.614375 178.746594 z M 45.110312 180.249406 C 44.747188 180.052531 43.743125 179.313156 43.723438 178.746594 C 43.723438 178.740031 43.681875 178.718156 43.695 178.691906 C 44.077813 177.810344 45.049063 177.160656 46.41625 177.160656 C 47.181875 177.160656 47.870938 177.578469 48.317188 178.042219 C 48.713125 178.453469 49.157188 179.286906 49.019375 179.827219 C 48.931875 180.181594 48.56875 180.422219 48.28875 180.538156 C 47.400625 180.905656 45.924063 180.702219 45.110312 180.249406 z M 44.200313 170.173781 C 44.35125 170.195656 44.392813 170.105969 44.480313 170.064406 C 44.933125 169.401594 44.440938 168.874406 43.749688 169.060344 C 43.47625 169.237531 43.285938 169.497844 43.167813 169.839094 C 42.75875 171.055344 43.141563 173.264719 43.94875 173.805031 C 43.75625 173.927531 43.723438 174.467844 43.865625 174.664719 C 43.955313 174.789406 44.255 174.822219 44.50875 174.835344 C 45.2 174.876906 46.075 174.780656 46.737813 174.835344 C 47.980313 174.938156 49.170313 174.938156 49.922813 174.809094 C 50.051875 174.686594 50.154688 174.542219 50.2575 174.391281 C 50.209375 174.187844 50.215938 174.200969 50.23125 173.969094 C 50.135 173.850969 50.00375 173.770031 49.894375 173.660656 C 49.238125 173.756906 48.623438 173.667219 47.88625 173.605969 C 46.7225 173.509719 45.48 173.516281 44.672813 173.024094 C 44.0975 172.483781 44.029688 171.206281 44.200313 170.173781 z M 43.469688 164.125344 C 43.66 164.466594 44.241875 164.479719 44.7625 164.460031 C 45.342188 164.431594 46.10125 164.322219 46.901875 164.225969 C 47.989063 164.090344 49.32125 163.865031 49.874688 163.296281 C 50.544063 162.176281 48.999688 161.635969 48.378438 161.156906 C 49.19875 160.850656 50.093438 160.439406 50.183125 159.680344 C 50.237813 159.216594 49.949063 158.765969 49.642813 158.492531 C 49.4175 158.286906 49.054375 158.100969 48.713125 157.904094 C 48.391563 157.711594 48.015313 157.486281 47.680625 157.383469 C 47.030938 157.186594 46.230313 157.125344 45.50625 157.077219 C 44.843438 157.035656 44.042813 157.116594 43.859063 157.486281 C 43.723438 157.759719 44.077813 158.258469 44.325 158.286906 C 44.480313 158.300031 44.589688 158.142531 44.78875 158.109719 C 45.097188 158.055031 45.34875 158.087844 45.6375 158.109719 C 47.050625 158.219094 48.500938 158.601906 49.150625 159.551281 C 48.780938 160.214094 47.365625 160.111281 47.085625 160.844094 C 46.928125 161.259719 47.243125 161.664406 47.523125 161.874406 C 47.9475 162.195969 48.562188 162.395031 48.91875 162.758156 C 48.021875 163.099406 46.915 163.132219 45.82125 163.296281 C 45.06875 163.405656 44.338125 163.536906 43.59875 163.585031 C 43.504688 163.714094 43.51125 163.945969 43.469688 164.125344 z M 42.614375 152.852062 C 42.642813 153.495187 43.106563 154.171125 43.469688 154.527687 C 43.605313 154.663312 43.8525 154.785812 44.064688 154.949875 C 44.659688 155.402687 45.644063 155.831437 46.497188 155.940812 C 47.919063 156.12675 49.327813 155.606125 49.848438 154.81425 C 49.9425 154.663312 50.121875 154.300187 50.154688 154.074875 C 50.2575 153.3705 49.909688 152.482375 49.588125 151.977062 C 49.192188 151.355812 48.500938 150.71925 47.857813 150.445812 C 46.676563 149.9405 45.10375 150.15925 44.174063 150.671125 C 43.865625 150.84175 43.63375 151.0955 43.38 151.355812 C 42.957813 151.793312 42.588125 152.230812 42.614375 152.852062 z M 45.110313 154.354875 C 44.747188 154.158 43.743125 153.418625 43.723438 152.852062 C 43.723438 152.8455 43.681875 152.823625 43.695 152.797375 C 44.077813 151.915812 45.049063 151.266125 46.41625 151.266125 C 47.181875 151.266125 47.870938 151.683937 48.317188 152.147687 C 48.713125 152.558937 49.157188 153.392375 49.019375 153.932687 C 48.931875 154.287062 48.56875 154.527687 48.28875 154.643625 C 47.400625 155.011125 45.924063 154.807687 45.110313 154.354875 z M 44.200313 144.27925 C 44.35125 144.301125 44.392813 144.211437 44.480313 144.169875 C 44.933125 143.507062 44.440938 142.979875 43.749688 143.165812 C 43.47625 143.343 43.285938 143.603312 43.167813 143.944562 C 42.75875 145.160812 43.141563 147.370187 43.94875 147.9105 C 43.75625 148.033 43.723438 148.573312 43.865625 148.770187 C 43.955313 148.894875 44.255 148.927687 44.50875 148.940812 C 45.2 148.982375 46.075 148.886125 46.737813 148.940812 C 47.980313 149.043625 49.170313 149.043625 49.922813 148.914562 C 50.051875 148.792062 50.154688 148.647687 50.2575 148.49675 C 50.209375 148.293312 50.215938 148.306437 50.23125 148.074562 C 50.135 147.956437 50.00375 147.8755 49.894375 147.766125 C 49.238125 147.862375 48.623438 147.772687 47.88625 147.711437 C 46.7225 147.615187 45.48 147.62175 44.672813 147.129562 C 44.0975 146.58925 44.029688 145.31175 44.200313 144.27925 z M 39.449063 141.1555 C 39.368125 141.313 39.361563 141.730812 39.449063 141.886125 C 40.60625 142.290812 42.47875 142.037062 44.042813 141.96925 C 45.3225 141.914562 46.387813 141.975812 47.577813 141.96925 C 47.9475 141.96925 48.439688 141.956125 48.864063 141.96925 C 49.0675 141.975812 49.456875 141.9955 49.594688 141.940812 C 49.874688 141.824875 50.0125 141.203625 49.75875 140.991437 C 49.28625 140.5955 48.214375 141.011125 47.516563 140.820812 C 47.461875 140.615187 47.394063 140.431437 47.208125 140.348312 C 47.864375 139.337687 48.658438 137.723312 49.874688 137.292375 C 50.03875 137.237687 50.215938 137.237687 50.347188 137.150187 C 50.865625 136.800187 50.421563 136.1855 50.03875 136.028 C 49.6975 136.262062 49.060938 136.362687 48.69125 136.644875 C 48.610313 136.706125 48.575313 136.800187 48.44625 136.896437 C 48.317188 136.992687 48.13125 137.115187 48.021875 137.237687 C 47.420313 137.9355 46.873438 138.762375 46.394375 139.534562 C 45.315938 138.613625 44.38625 137.546125 43.312188 136.616437 C 43.16125 136.658 42.997188 136.623 42.778438 136.706125 C 42.739063 136.883312 42.520313 137.150187 42.559688 137.347062 C 42.588125 137.484875 42.848438 137.6555 42.9775 137.799875 C 43.421563 138.27675 43.894063 138.736125 44.296563 139.138625 C 44.959375 139.801437 45.644063 140.273937 46.114375 140.8755 C 45.081875 140.8755 44.10625 140.862375 43.23125 140.93675 C 41.986563 141.039562 40.372188 140.868937 39.449063 141.1555 z M 49.047813 133.300187 C 47.461875 133.943312 45.364063 133.637062 43.5375 133.553937 C 42.218438 133.492687 40.879688 133.2805 39.648125 133.2455 C 39.497188 133.328625 39.32 133.383312 39.1625 133.451125 C 39.075 133.65675 38.97875 133.862375 38.956875 134.142375 C 38.998438 134.442062 39.204063 135.058937 39.567188 135.0655 C 39.805625 135.072062 40.120625 134.921125 40.16 134.708937 C 40.201563 134.512062 40.030938 134.4355 40.079063 134.271437 C 40.639063 134.313 41.25375 134.40925 41.896875 134.448625 C 42.505 134.490187 43.148125 134.483625 43.769375 134.551437 C 45.554375 134.7505 47.024375 134.840187 48.535938 134.477062 C 49.12875 134.332687 49.739063 134.238625 50.019063 133.862375 C 50.325313 133.444562 50.058438 132.678937 49.607813 132.582687 C 49.246875 132.508312 48.890313 132.958937 49.047813 133.300187 z M 42.614375 128.352062 C 42.642813 128.995187 43.106563 129.671125 43.469688 130.027687 C 43.605313 130.163312 43.8525 130.285812 44.064688 130.449875 C 44.659688 130.902687 45.644063 131.331437 46.497188 131.440812 C 47.919063 131.62675 49.327813 131.106125 49.848438 130.31425 C 49.9425 130.163312 50.121875 129.800187 50.154688 129.574875 C 50.2575 128.8705 49.909688 127.982375 49.588125 127.477062 C 49.192188 126.855812 48.500938 126.21925 47.857813 125.945812 C 46.676563 125.4405 45.10375 125.65925 44.174063 126.171125 C 43.865625 126.34175 43.63375 126.5955 43.38 126.855812 C 42.957813 127.293312 42.588125 127.730812 42.614375 128.352062 z M 45.110313 129.854875 C 44.747188 129.658 43.743125 128.918625 43.723438 128.352062 C 43.723438 128.3455 43.681875 128.323625 43.695 128.297375 C 44.077813 127.415812 45.049063 126.766125 46.41625 126.766125 C 47.181875 126.766125 47.870938 127.183937 48.317188 127.647687 C 48.713125 128.058937 49.157188 128.892375 49.019375 129.432687 C 48.931875 129.787062 48.56875 130.027687 48.28875 130.143625 C 47.400625 130.511125 45.924063 130.307687 45.110313 129.854875 z M 44.535 118.932687 C 44.434375 118.980812 44.47375 119.158 44.425625 119.260812 C 43.8875 119.663312 43.44125 120.293312 43.469688 121.223 C 43.530938 123.491437 46.053125 124.701125 48.25375 124.694562 C 48.63 124.694562 49.12875 124.620187 49.450313 124.394875 C 49.848438 124.112687 50.058438 123.6905 50.189688 123.272687 C 50.19625 121.352062 49.122188 120.518625 48.063438 119.669875 C 48.993125 119.403 50.401875 119.0005 50.135 117.974562 C 49.855 117.620187 49.1375 117.694562 49.0675 118.138625 C 48.391563 118.50175 47.442188 118.753312 46.4775 118.823312 C 45.82125 118.862687 45.123438 118.707375 44.535 118.932687 z M 44.808438 122.178937 C 44.392813 121.522687 44.4475 120.442062 44.94625 119.943312 C 45.309375 120.011125 45.801563 119.90175 46.120938 119.943312 C 46.825313 120.033 47.700313 120.641125 48.275625 121.223 C 48.72625 121.673625 49.465625 122.7455 48.903438 123.491437 C 47.461875 123.880812 45.493125 123.246437 44.808438 122.178937 z M 39.667813 111.467297 C 39.635 111.611672 39.593438 111.946359 39.689688 112.049172 C 40.687188 112.361984 42.327813 112.033859 43.415 112.259172 C 42.710625 113.387922 43.121875 114.871047 43.942188 115.533859 C 45.027188 116.415422 46.53875 116.977609 48.083125 116.642922 C 48.658438 116.415422 49.122188 116.183547 49.430625 115.746047 C 50.277188 114.542922 48.986563 112.978859 48.5075 112.158547 C 48.7 112.116984 48.903438 112.165109 49.012813 112.020734 C 49.095938 111.911359 49.1025 111.480422 49.060938 111.338234 C 49.04125 111.261672 48.98 111.139172 48.931875 111.097609 C 47.892813 110.852609 46.785938 111.174172 45.62875 111.255109 C 45.014063 111.296672 44.296563 111.283547 43.653438 111.228859 C 42.935938 111.165422 42.047813 111.174172 41.301875 111.228859 C 40.722188 111.274797 40.16 111.316359 39.667813 111.467297 z M 45.950313 112.287609 C 46.41625 112.259172 46.895313 112.335734 47.345938 112.259172 C 47.72875 112.915422 48.378438 113.580422 48.616875 114.372297 C 48.671563 114.556047 48.732813 114.803234 48.69125 114.980422 C 48.575313 115.520734 47.639063 115.800734 46.95 115.774484 C 46.020313 115.739484 44.611563 115.028547 44.206875 114.291359 C 44.023125 113.954484 44.058125 113.455734 44.152188 113.024797 C 44.370938 112.574172 45.34875 112.322609 45.950313 112.287609 z " + style="stroke: #ffffff; stroke-width: 4" + id="path7" /> + <path + d="M 40.645625 230.911906 C 40.523125 230.323469 40.262812 229.811594 39.621875 229.811594 C 39.114375 229.811594 38.937188 230.638469 38.937188 230.986281 C 38.937188 231.082531 38.950312 231.172219 38.965625 231.253156 C 39.020312 231.561594 39.053125 232.108469 39.081562 232.749406 C 39.107812 233.405656 39.120937 234.164719 39.149375 234.890969 C 39.204062 236.358781 39.313437 237.774094 39.635 238.082531 C 39.805625 238.253156 40.09875 238.513469 40.37875 238.513469 C 40.88625 238.513469 40.899375 237.535656 40.899375 237.214094 C 40.899375 236.531594 40.770312 235.853469 40.770312 235.184094 C 40.770312 235.155656 40.770312 235.087844 40.783437 235.074719 C 40.879687 234.965344 43.277187 234.917219 43.627187 234.917219 C 45.000937 234.917219 46.368125 235.013469 47.755 235.013469 L 48.44625 235.013469 C 48.72625 235.000344 49.034687 234.971906 49.314687 234.917219 C 49.887813 234.820969 50.38875 234.582531 50.38875 234.035656 C 50.38875 233.460344 49.588125 233.405656 49.183437 233.392531 L 48.739375 233.392531 C 47.496875 233.392531 46.245625 233.591594 44.987812 233.591594 L 44.78875 233.591594 C 44.399375 233.591594 44.016562 233.530344 43.627187 233.530344 C 43.386562 233.530344 42.771875 233.530344 42.183437 233.515031 C 41.581875 233.501906 41.015313 233.475656 40.857812 233.392531 C 40.79 233.366281 40.755 233.228469 40.72875 233.044719 C 40.715625 232.874094 40.72875 232.688156 40.72875 232.620344 C 40.72875 232.408156 40.741875 232.147844 40.72875 231.841594 C 40.72875 231.546281 40.700312 231.218156 40.645625 230.911906 z M 44.200313 224.423781 C 44.35125 224.445656 44.392812 224.355969 44.480312 224.314406 C 44.933125 223.651594 44.440937 223.124406 43.749688 223.310344 C 43.47625 223.487531 43.285938 223.747844 43.167812 224.089094 C 42.75875 225.305344 43.141562 227.514719 43.94875 228.055031 C 43.75625 228.177531 43.723438 228.717844 43.865625 228.914719 C 43.955312 229.039406 44.255 229.072219 44.50875 229.085344 C 45.2 229.126906 46.075 229.030656 46.737812 229.085344 C 47.980312 229.188156 49.170313 229.188156 49.922812 229.059094 C 50.051875 228.936594 50.154688 228.792219 50.2575 228.641281 C 50.209375 228.437844 50.215938 228.450969 50.23125 228.219094 C 50.135 228.100969 50.00375 228.020031 49.894375 227.910656 C 49.238125 228.006906 48.623438 227.917219 47.88625 227.855969 C 46.7225 227.759719 45.48 227.766281 44.672812 227.274094 C 44.0975 226.733781 44.029688 225.456281 44.200313 224.423781 z M 44.535 216.577219 C 44.434375 216.625344 44.47375 216.802531 44.425625 216.905344 C 43.8875 217.307844 43.44125 217.937844 43.469687 218.867531 C 43.530938 221.135969 46.053125 222.345656 48.25375 222.339094 C 48.63 222.339094 49.12875 222.264719 49.450313 222.039406 C 49.848438 221.757219 50.058438 221.335031 50.189687 220.917219 C 50.19625 218.996594 49.122188 218.163156 48.063437 217.314406 C 48.993125 217.047531 50.401875 216.645031 50.135 215.619094 C 49.855 215.264719 49.1375 215.339094 49.0675 215.783156 C 48.391562 216.146281 47.442188 216.397844 46.4775 216.467844 C 45.82125 216.507219 45.123438 216.351906 44.535 216.577219 z M 44.808437 219.823469 C 44.392812 219.167219 44.4475 218.086594 44.94625 217.587844 C 45.309375 217.655656 45.801563 217.546281 46.120937 217.587844 C 46.825313 217.677531 47.700313 218.285656 48.275625 218.867531 C 48.72625 219.318156 49.465625 220.390031 48.903438 221.135969 C 47.461875 221.525344 45.493125 220.890969 44.808437 219.823469 z M 50.1 208.844953 C 50.032187 208.523391 50.1 208.120891 49.909688 207.969953 C 49.752187 207.847453 49.44375 207.934953 49.192188 207.934953 C 47.324063 207.928391 44.917812 207.429641 43.38 208.564953 C 42.887813 208.928078 42.362813 209.700266 42.3825 210.472453 C 42.410938 211.717141 43.2925 212.283703 44.0975 212.843703 C 43.810938 212.856828 43.544063 212.898391 43.347188 213.001203 C 43.2225 213.239641 43.347188 213.692453 43.44125 213.911203 C 44.637813 214.094953 46.715938 214.005266 48.220937 214.059953 C 48.590625 214.075266 49.82 214.300578 50.1 213.972453 C 50.2925 213.747141 50.23125 213.075578 50.067188 212.939953 C 49.894375 212.802141 49.60125 212.865578 49.314687 212.843703 C 48.00875 212.756203 46.982813 212.769328 45.78625 212.283703 C 45.049062 211.981828 43.176563 211.224953 43.723438 210.034953 C 44.180625 209.037453 46.075 208.960891 47.53625 209.063703 C 48.500937 209.131516 49.553125 209.391828 50.1 208.844953 z M 50.141562 204.87382 C 50.051875 204.626633 50.189687 204.40132 50.189687 204.176008 C 50.189687 203.574445 49.868125 202.972883 49.559688 202.570383 C 49.292813 202.220383 48.91875 201.817883 48.535938 201.666945 C 47.989063 201.454758 47.153438 201.49632 46.66125 201.647258 C 46.348438 201.743508 45.875937 202.139445 45.808125 202.49382 C 45.773125 202.679758 45.779688 203.056008 45.85625 203.301008 C 46.011562 203.793195 46.873438 205.051008 45.808125 205.051008 C 45.184688 205.051008 44.583125 204.504133 44.502187 204.02507 C 44.440938 203.642258 44.63125 203.165383 44.75375 202.972883 C 44.856563 202.815383 45.06875 202.795695 45.081875 202.596633 C 45.097188 202.43257 44.769063 202.043195 44.576563 202.023508 C 44.480313 202.016945 44.31625 202.078195 44.255 202.11757 C 43.832813 202.391008 43.544063 203.252883 43.47625 203.773508 C 43.395313 204.359758 43.94875 205.134133 44.303125 205.39882 C 44.515313 205.55632 44.769063 205.768508 45.0075 205.851633 C 45.85625 206.138195 46.621875 206.035383 47.13375 205.475383 C 47.6325 204.62007 47.0375 203.629133 46.7575 202.850383 C 47.01125 202.500383 47.755 202.40632 48.214375 202.596633 C 48.32375 202.644758 48.527188 202.837258 48.610312 202.924758 C 48.754688 203.082258 49.019375 203.410383 49.115625 203.696945 C 49.225 204.040383 49.238125 204.74257 48.91 204.976633 C 48.623438 205.18007 48.137813 205.160383 48.063437 205.427258 C 48.00875 205.61757 48.25375 205.84507 48.336875 206.076945 C 49.157187 206.199445 49.56625 205.707258 49.964375 205.324445 C 49.997188 205.15382 50.058438 205.002883 50.141562 204.87382 z M 49.047812 198.391984 C 47.461875 199.035109 45.364063 198.728859 43.5375 198.645734 C 42.218438 198.584484 40.879688 198.372297 39.648125 198.337297 C 39.497188 198.420422 39.32 198.475109 39.1625 198.542922 C 39.075 198.748547 38.97875 198.954172 38.956875 199.234172 C 38.998438 199.533859 39.204062 200.150734 39.567188 200.157297 C 39.805625 200.163859 40.120625 200.012922 40.16 199.800734 C 40.201563 199.603859 40.030938 199.527297 40.079062 199.363234 C 40.639063 199.404797 41.25375 199.501047 41.896875 199.540422 C 42.505 199.581984 43.148125 199.575422 43.769375 199.643234 C 45.554375 199.842297 47.024375 199.931984 48.535938 199.568859 C 49.12875 199.424484 49.739063 199.330422 50.019063 198.954172 C 50.325313 198.536359 50.058438 197.770734 49.607813 197.674484 C 49.246875 197.600109 48.890313 198.050734 49.047812 198.391984 z M 44.535 191.024484 C 44.434375 191.072609 44.47375 191.249797 44.425625 191.352609 C 43.8875 191.755109 43.44125 192.385109 43.469687 193.314797 C 43.530938 195.583234 46.053125 196.792922 48.25375 196.786359 C 48.63 196.786359 49.12875 196.711984 49.450313 196.486672 C 49.848438 196.204484 50.058438 195.782297 50.189688 195.364484 C 50.19625 193.443859 49.122188 192.610422 48.063437 191.761672 C 48.993125 191.494797 50.401875 191.092297 50.135 190.066359 C 49.855 189.711984 49.1375 189.786359 49.0675 190.230422 C 48.391562 190.593547 47.442188 190.845109 46.4775 190.915109 C 45.82125 190.954484 45.123438 190.799172 44.535 191.024484 z M 44.808438 194.270734 C 44.392813 193.614484 44.4475 192.533859 44.94625 192.035109 C 45.309375 192.102922 45.801563 191.993547 46.120938 192.035109 C 46.825313 192.124797 47.700313 192.732922 48.275625 193.314797 C 48.72625 193.765422 49.465625 194.837297 48.903438 195.583234 C 47.461875 195.972609 45.493125 195.338234 44.808438 194.270734 z M 42.301563 185.643781 C 41.28875 185.405344 40.079062 185.180031 39.10125 185.383469 C 38.956875 185.602219 38.924063 185.930344 39.005 186.068156 C 39.422812 186.772531 41.44625 186.656594 42.301563 186.949719 C 42.402188 187.647531 42.1375 188.397844 42.402188 188.911906 C 42.675625 188.960031 43.16125 189.117531 43.38 188.911906 C 43.614063 188.494094 43.592188 187.824719 43.605313 187.181594 C 44.084375 187.210031 44.795313 187.319406 45.309375 187.345656 C 46.921563 187.428781 48.973438 187.435344 49.778438 186.525344 C 50.347188 185.890969 50.183125 184.652844 49.909688 183.819406 C 49.82 183.539406 49.771875 183.211281 49.649375 183.066906 C 49.402188 182.780344 48.842188 182.970656 48.575313 183.163156 C 48.35 183.812844 49.19875 184.891281 48.870625 185.547531 C 48.671563 185.945656 47.755 186.000344 47.201563 186.039719 C 46.046563 186.122844 44.605 185.985031 43.605313 185.875656 C 43.559375 185.061906 43.769375 184.263469 43.640313 183.395031 C 43.415 183.115031 42.800313 183.217844 42.498438 183.395031 C 42.340938 184.051281 42.3825 184.913156 42.301563 185.643781 z M 42.614375 178.746594 C 42.642813 179.389719 43.106563 180.065656 43.469687 180.422219 C 43.605313 180.557844 43.8525 180.680344 44.064688 180.844406 C 44.659688 181.297219 45.644063 181.725969 46.497188 181.835344 C 47.919063 182.021281 49.327813 181.500656 49.848438 180.708781 C 49.9425 180.557844 50.121875 180.194719 50.154688 179.969406 C 50.2575 179.265031 49.909688 178.376906 49.588125 177.871594 C 49.192188 177.250344 48.500938 176.613781 47.857813 176.340344 C 46.676563 175.835031 45.10375 176.053781 44.174063 176.565656 C 43.865625 176.736281 43.63375 176.990031 43.38 177.250344 C 42.957813 177.687844 42.588125 178.125344 42.614375 178.746594 z M 45.110312 180.249406 C 44.747188 180.052531 43.743125 179.313156 43.723438 178.746594 C 43.723438 178.740031 43.681875 178.718156 43.695 178.691906 C 44.077813 177.810344 45.049063 177.160656 46.41625 177.160656 C 47.181875 177.160656 47.870938 177.578469 48.317188 178.042219 C 48.713125 178.453469 49.157188 179.286906 49.019375 179.827219 C 48.931875 180.181594 48.56875 180.422219 48.28875 180.538156 C 47.400625 180.905656 45.924063 180.702219 45.110312 180.249406 z M 44.200313 170.173781 C 44.35125 170.195656 44.392813 170.105969 44.480313 170.064406 C 44.933125 169.401594 44.440938 168.874406 43.749688 169.060344 C 43.47625 169.237531 43.285938 169.497844 43.167813 169.839094 C 42.75875 171.055344 43.141563 173.264719 43.94875 173.805031 C 43.75625 173.927531 43.723438 174.467844 43.865625 174.664719 C 43.955313 174.789406 44.255 174.822219 44.50875 174.835344 C 45.2 174.876906 46.075 174.780656 46.737813 174.835344 C 47.980313 174.938156 49.170313 174.938156 49.922813 174.809094 C 50.051875 174.686594 50.154688 174.542219 50.2575 174.391281 C 50.209375 174.187844 50.215938 174.200969 50.23125 173.969094 C 50.135 173.850969 50.00375 173.770031 49.894375 173.660656 C 49.238125 173.756906 48.623438 173.667219 47.88625 173.605969 C 46.7225 173.509719 45.48 173.516281 44.672813 173.024094 C 44.0975 172.483781 44.029688 171.206281 44.200313 170.173781 z M 43.469688 164.125344 C 43.66 164.466594 44.241875 164.479719 44.7625 164.460031 C 45.342188 164.431594 46.10125 164.322219 46.901875 164.225969 C 47.989063 164.090344 49.32125 163.865031 49.874688 163.296281 C 50.544063 162.176281 48.999688 161.635969 48.378438 161.156906 C 49.19875 160.850656 50.093438 160.439406 50.183125 159.680344 C 50.237813 159.216594 49.949063 158.765969 49.642813 158.492531 C 49.4175 158.286906 49.054375 158.100969 48.713125 157.904094 C 48.391563 157.711594 48.015313 157.486281 47.680625 157.383469 C 47.030938 157.186594 46.230313 157.125344 45.50625 157.077219 C 44.843438 157.035656 44.042813 157.116594 43.859063 157.486281 C 43.723438 157.759719 44.077813 158.258469 44.325 158.286906 C 44.480313 158.300031 44.589688 158.142531 44.78875 158.109719 C 45.097188 158.055031 45.34875 158.087844 45.6375 158.109719 C 47.050625 158.219094 48.500938 158.601906 49.150625 159.551281 C 48.780938 160.214094 47.365625 160.111281 47.085625 160.844094 C 46.928125 161.259719 47.243125 161.664406 47.523125 161.874406 C 47.9475 162.195969 48.562188 162.395031 48.91875 162.758156 C 48.021875 163.099406 46.915 163.132219 45.82125 163.296281 C 45.06875 163.405656 44.338125 163.536906 43.59875 163.585031 C 43.504688 163.714094 43.51125 163.945969 43.469688 164.125344 z M 42.614375 152.852062 C 42.642813 153.495187 43.106563 154.171125 43.469688 154.527687 C 43.605313 154.663312 43.8525 154.785812 44.064688 154.949875 C 44.659688 155.402687 45.644063 155.831437 46.497188 155.940812 C 47.919063 156.12675 49.327813 155.606125 49.848438 154.81425 C 49.9425 154.663312 50.121875 154.300187 50.154688 154.074875 C 50.2575 153.3705 49.909688 152.482375 49.588125 151.977062 C 49.192188 151.355812 48.500938 150.71925 47.857813 150.445812 C 46.676563 149.9405 45.10375 150.15925 44.174063 150.671125 C 43.865625 150.84175 43.63375 151.0955 43.38 151.355812 C 42.957813 151.793312 42.588125 152.230812 42.614375 152.852062 z M 45.110313 154.354875 C 44.747188 154.158 43.743125 153.418625 43.723438 152.852062 C 43.723438 152.8455 43.681875 152.823625 43.695 152.797375 C 44.077813 151.915812 45.049063 151.266125 46.41625 151.266125 C 47.181875 151.266125 47.870938 151.683937 48.317188 152.147687 C 48.713125 152.558937 49.157188 153.392375 49.019375 153.932687 C 48.931875 154.287062 48.56875 154.527687 48.28875 154.643625 C 47.400625 155.011125 45.924063 154.807687 45.110313 154.354875 z M 44.200313 144.27925 C 44.35125 144.301125 44.392813 144.211437 44.480313 144.169875 C 44.933125 143.507062 44.440938 142.979875 43.749688 143.165812 C 43.47625 143.343 43.285938 143.603312 43.167813 143.944562 C 42.75875 145.160812 43.141563 147.370187 43.94875 147.9105 C 43.75625 148.033 43.723438 148.573312 43.865625 148.770187 C 43.955313 148.894875 44.255 148.927687 44.50875 148.940812 C 45.2 148.982375 46.075 148.886125 46.737813 148.940812 C 47.980313 149.043625 49.170313 149.043625 49.922813 148.914562 C 50.051875 148.792062 50.154688 148.647687 50.2575 148.49675 C 50.209375 148.293312 50.215938 148.306437 50.23125 148.074562 C 50.135 147.956437 50.00375 147.8755 49.894375 147.766125 C 49.238125 147.862375 48.623438 147.772687 47.88625 147.711437 C 46.7225 147.615187 45.48 147.62175 44.672813 147.129562 C 44.0975 146.58925 44.029688 145.31175 44.200313 144.27925 z M 39.449063 141.1555 C 39.368125 141.313 39.361563 141.730812 39.449063 141.886125 C 40.60625 142.290812 42.47875 142.037062 44.042813 141.96925 C 45.3225 141.914562 46.387813 141.975812 47.577813 141.96925 C 47.9475 141.96925 48.439688 141.956125 48.864063 141.96925 C 49.0675 141.975812 49.456875 141.9955 49.594688 141.940812 C 49.874688 141.824875 50.0125 141.203625 49.75875 140.991437 C 49.28625 140.5955 48.214375 141.011125 47.516563 140.820812 C 47.461875 140.615187 47.394063 140.431437 47.208125 140.348312 C 47.864375 139.337687 48.658438 137.723312 49.874688 137.292375 C 50.03875 137.237687 50.215938 137.237687 50.347188 137.150187 C 50.865625 136.800187 50.421563 136.1855 50.03875 136.028 C 49.6975 136.262062 49.060938 136.362687 48.69125 136.644875 C 48.610313 136.706125 48.575313 136.800187 48.44625 136.896437 C 48.317188 136.992687 48.13125 137.115187 48.021875 137.237687 C 47.420313 137.9355 46.873438 138.762375 46.394375 139.534562 C 45.315938 138.613625 44.38625 137.546125 43.312188 136.616437 C 43.16125 136.658 42.997188 136.623 42.778438 136.706125 C 42.739063 136.883312 42.520313 137.150187 42.559688 137.347062 C 42.588125 137.484875 42.848438 137.6555 42.9775 137.799875 C 43.421563 138.27675 43.894063 138.736125 44.296563 139.138625 C 44.959375 139.801437 45.644063 140.273937 46.114375 140.8755 C 45.081875 140.8755 44.10625 140.862375 43.23125 140.93675 C 41.986563 141.039562 40.372188 140.868937 39.449063 141.1555 z M 49.047813 133.300187 C 47.461875 133.943312 45.364063 133.637062 43.5375 133.553937 C 42.218438 133.492687 40.879688 133.2805 39.648125 133.2455 C 39.497188 133.328625 39.32 133.383312 39.1625 133.451125 C 39.075 133.65675 38.97875 133.862375 38.956875 134.142375 C 38.998438 134.442062 39.204063 135.058937 39.567188 135.0655 C 39.805625 135.072062 40.120625 134.921125 40.16 134.708937 C 40.201563 134.512062 40.030938 134.4355 40.079063 134.271437 C 40.639063 134.313 41.25375 134.40925 41.896875 134.448625 C 42.505 134.490187 43.148125 134.483625 43.769375 134.551437 C 45.554375 134.7505 47.024375 134.840187 48.535938 134.477062 C 49.12875 134.332687 49.739063 134.238625 50.019063 133.862375 C 50.325313 133.444562 50.058438 132.678937 49.607813 132.582687 C 49.246875 132.508312 48.890313 132.958937 49.047813 133.300187 z M 42.614375 128.352062 C 42.642813 128.995187 43.106563 129.671125 43.469688 130.027687 C 43.605313 130.163312 43.8525 130.285812 44.064688 130.449875 C 44.659688 130.902687 45.644063 131.331437 46.497188 131.440812 C 47.919063 131.62675 49.327813 131.106125 49.848438 130.31425 C 49.9425 130.163312 50.121875 129.800187 50.154688 129.574875 C 50.2575 128.8705 49.909688 127.982375 49.588125 127.477062 C 49.192188 126.855812 48.500938 126.21925 47.857813 125.945812 C 46.676563 125.4405 45.10375 125.65925 44.174063 126.171125 C 43.865625 126.34175 43.63375 126.5955 43.38 126.855812 C 42.957813 127.293312 42.588125 127.730812 42.614375 128.352062 z M 45.110313 129.854875 C 44.747188 129.658 43.743125 128.918625 43.723438 128.352062 C 43.723438 128.3455 43.681875 128.323625 43.695 128.297375 C 44.077813 127.415812 45.049063 126.766125 46.41625 126.766125 C 47.181875 126.766125 47.870938 127.183937 48.317188 127.647687 C 48.713125 128.058937 49.157188 128.892375 49.019375 129.432687 C 48.931875 129.787062 48.56875 130.027687 48.28875 130.143625 C 47.400625 130.511125 45.924063 130.307687 45.110313 129.854875 z M 44.535 118.932687 C 44.434375 118.980812 44.47375 119.158 44.425625 119.260812 C 43.8875 119.663312 43.44125 120.293312 43.469688 121.223 C 43.530938 123.491437 46.053125 124.701125 48.25375 124.694562 C 48.63 124.694562 49.12875 124.620187 49.450313 124.394875 C 49.848438 124.112687 50.058438 123.6905 50.189688 123.272687 C 50.19625 121.352062 49.122188 120.518625 48.063438 119.669875 C 48.993125 119.403 50.401875 119.0005 50.135 117.974562 C 49.855 117.620187 49.1375 117.694562 49.0675 118.138625 C 48.391563 118.50175 47.442188 118.753312 46.4775 118.823312 C 45.82125 118.862687 45.123438 118.707375 44.535 118.932687 z M 44.808438 122.178937 C 44.392813 121.522687 44.4475 120.442062 44.94625 119.943312 C 45.309375 120.011125 45.801563 119.90175 46.120938 119.943312 C 46.825313 120.033 47.700313 120.641125 48.275625 121.223 C 48.72625 121.673625 49.465625 122.7455 48.903438 123.491437 C 47.461875 123.880812 45.493125 123.246437 44.808438 122.178937 z M 39.667813 111.467297 C 39.635 111.611672 39.593438 111.946359 39.689688 112.049172 C 40.687188 112.361984 42.327813 112.033859 43.415 112.259172 C 42.710625 113.387922 43.121875 114.871047 43.942188 115.533859 C 45.027188 116.415422 46.53875 116.977609 48.083125 116.642922 C 48.658438 116.415422 49.122188 116.183547 49.430625 115.746047 C 50.277188 114.542922 48.986563 112.978859 48.5075 112.158547 C 48.7 112.116984 48.903438 112.165109 49.012813 112.020734 C 49.095938 111.911359 49.1025 111.480422 49.060938 111.338234 C 49.04125 111.261672 48.98 111.139172 48.931875 111.097609 C 47.892813 110.852609 46.785938 111.174172 45.62875 111.255109 C 45.014063 111.296672 44.296563 111.283547 43.653438 111.228859 C 42.935938 111.165422 42.047813 111.174172 41.301875 111.228859 C 40.722188 111.274797 40.16 111.316359 39.667813 111.467297 z M 45.950313 112.287609 C 46.41625 112.259172 46.895313 112.335734 47.345938 112.259172 C 47.72875 112.915422 48.378438 113.580422 48.616875 114.372297 C 48.671563 114.556047 48.732813 114.803234 48.69125 114.980422 C 48.575313 115.520734 47.639063 115.800734 46.95 115.774484 C 46.020313 115.739484 44.611563 115.028547 44.206875 114.291359 C 44.023125 113.954484 44.058125 113.455734 44.152188 113.024797 C 44.370938 112.574172 45.34875 112.322609 45.950313 112.287609 z " + id="path8" /> + </g> + </g> + <g + id="line2d_1"> + <path + d="M 65.62632 -1 L 65.623625 0.00049 L 65.615428 1.001139 L 65.54645 2.003534 L 65.542671 3.004056 L 65.497805 4.005758 L 65.487983 5.006453 L 65.481313 6.007058 L 65.452425 7.008301 L 65.410796 8.00991 L 65.387582 9.010991 L 65.357245 10.012275 L 65.297688 11.0144 L 65.280291 12.015313 L 65.266626 13.016118 L 65.264874 14.016582 L 65.267569 15.016917 L 65.275105 16.017113 L 65.249555 17.018261 L 65.250357 18.018651 L 65.249374 19.019092 L 65.252718 20.019409 L 65.27025 21.019318 L 65.288859 22.019196 L 65.317792 23.018777 L 65.356026 24.018091 L 65.396403 25.017344 L 65.456148 26.016039 L 65.496039 27.015306 L 65.554873 28.014028 L 65.643353 29.011898 L 65.709257 30.010417 L 65.777066 31.008881 L 65.875969 32.972894 L 65.946725 33.977527 L 66.051898 34.974264 L 66.12879 35.972071 L 66.209229 36.969744 L 66.317554 37.966362 L 66.391713 38.964272 L 66.487869 39.96135 L 66.636537 40.956442 L 66.74494 41.953057 L 66.895594 42.948074 L 66.979128 43.94563 L 67.078163 44.942599 L 67.164422 45.940052 L 67.282982 46.936282 L 67.43921 47.931089 L 67.547166 48.927721 L 67.668163 49.923859 L 67.739076 50.921892 L 67.828071 51.919241 L 67.934216 52.915942 L 68.038178 53.912725 L 68.152835 54.909103 L 68.217926 55.907356 L 68.282179 56.905641 L 68.342608 57.90407 L 68.39992 58.902618 L 68.46409 59.900906 L 68.55162 60.89831 L 68.624463 61.89627 L 68.698097 62.8942 L 68.751248 63.892905 L 68.804801 64.891594 L 68.846006 65.890751 L 68.886216 66.889945 L 68.923525 67.889249 L 68.983723 69.531925 L 69.019376 70.519785 L 69.060395 71.518979 L 69.088283 72.518822 L 69.114678 73.518739 L 69.146864 74.518369 L 69.177823 75.518061 L 69.206794 76.51785 L 69.239613 77.517449 L 69.22631 78.51933 L 69.200535 79.521827 L 69.217335 80.522218 L 69.199252 81.524335 L 69.19467 82.525784 L 69.210406 83.526228 L 69.169788 84.529459 L 69.190687 85.529648 L 69.208638 86.529982 L 69.227064 87.530293 L 69.221722 88.53178 L 69.206612 89.53375 L 69.217862 90.534416 L 69.171443 91.537934 L 69.171644 92.539146 L 69.177027 93.540102 L 69.186351 94.540864 L 69.127516 95.544996 L 69.135337 96.545831 L 69.124445 97.583556 L 69.117327 98.589227 L 69.075553 99.593805 L 69.101163 100.594161 L 69.117901 101.595073 L 69.112067 102.597399 L 69.125942 103.59849 L 69.111022 104.601385 L 69.143067 105.601338 L 69.136214 106.603728 L 69.174813 107.60327 L 69.208773 108.603103 L 69.229588 109.60376 L 69.27058 110.603152 L 69.319185 111.602067 L 69.35504 112.601782 L 69.408274 113.600407 L 69.458378 114.599229 L 69.50987 115.597963 L 69.566742 116.596361 L 69.624513 117.594702 L 69.692576 118.592399 L 69.777738 119.739256 L 69.863397 120.750051 L 69.965266 121.745157 L 70.065923 122.740358 L 70.179154 123.734585 L 70.282197 124.729601 L 70.38161 125.724897 L 70.527323 126.716611 L 70.678794 127.707878 L 70.849652 128.697646 L 70.97771 129.690726 L 71.108641 130.683583 L 71.220945 131.677882 L 71.403875 132.666715 L 71.533142 133.659702 L 71.647097 134.653873 L 71.755194 135.648497 L 71.966574 137.587295 L 72.127215 138.57948 L 72.269181 139.570559 L 72.427362 140.560119 L 72.558656 141.552198 L 72.693742 142.543921 L 72.828849 143.535643 L 72.981379 144.525732 L 73.187319 145.510818 L 73.332615 146.501585 L 73.465133 147.493549 L 73.605303 148.484796 L 73.755107 149.475141 L 73.880901 150.467735 L 74.089312 152.304535 L 74.231025 153.284892 L 74.375932 154.274931 L 74.544788 155.262299 L 74.700533 156.25113 L 74.840813 157.241685 L 75.001726 158.229938 L 75.137607 159.220984 L 75.269367 160.212489 L 75.414957 161.202452 L 75.549936 162.193598 L 75.674755 163.185877 L 75.859298 164.669696 L 76.002447 165.64111 L 76.144706 166.631019 L 76.280306 167.6218 L 76.416944 168.612445 L 76.551887 169.603312 L 76.679933 170.595082 L 76.807044 171.586974 L 76.925798 172.57996 L 77.027615 173.575164 L 77.200817 175.235419 L 77.327888 176.208648 L 77.437526 177.203464 L 77.548052 178.198145 L 77.679306 179.189678 L 77.8072 180.181721 L 77.89145 181.180392 L 77.992452 182.17652 L 78.069727 183.17625 L 78.222532 184.390967 L 78.316895 185.377432 L 78.450942 186.369146 L 78.549703 187.367014 L 78.618967 188.370025 L 78.72195 189.367156 L 78.790057 190.370369 L 78.907635 191.364955 L 78.968504 192.43285 L 79.094342 193.429735 L 79.175342 194.433158 L 79.320745 195.423802 L 79.480446 196.41161 L 79.585411 197.410278 L 79.727551 198.401569 L 79.858518 199.513305 L 80.01267 200.518739 L 80.185639 201.504776 L 80.333941 202.496339 L 80.503614 203.483114 L 80.705247 204.462729 L 80.970823 205.771754 L 81.208463 206.77257 L 81.439524 207.745701 L 81.652274 208.723556 L 81.886148 209.695962 L 82.12783 210.666353 L 82.373435 211.635733 L 82.616873 212.605672 L 82.948245 213.880046 L 83.253759 214.875087 L 83.558752 215.827583 L 83.878588 216.775594 L 84.204211 217.721856 L 84.526794 218.669037 L 84.876436 219.608041 L 85.238755 220.732965 L 85.627302 221.692365 L 85.981124 222.62801 L 86.363902 223.553525 L 86.723644 224.487099 L 87.10124 225.414426 L 87.557991 226.62142 L 88.013427 227.542336 L 88.449672 228.444799 L 88.929327 229.329851 L 89.371655 230.229875 L 90.06719 231.653606 L 90.55581 232.534187 L 91.069233 233.399147 L 91.519804 234.292755 L 92.028156 235.160027 L 92.53738 236.036614 L 93.027897 236.890589 L 93.515562 237.764294 L 94.018909 238.629939 L 94.760166 239.985381 L 95.278107 240.812752 L 95.835637 241.645661 L 96.368411 242.49282 L 96.992857 243.476372 L 97.556404 244.262897 L 98.138955 245.077295 L 99.174507 246.611243 L 99.750898 247.370904 L 100.348324 248.172979 L 100.967562 248.959328 L 101.995082 250.359155 L 102.610655 251.072353 L 103.259851 251.833246 L 103.897811 252.603337 L 104.769185 253.663765 L 105.406249 254.356161 L 106.075839 255.098982 L 106.741516 255.845414 L 107.453787 256.664083 L 108.125554 257.332034 L 108.807346 258.065474 L 110.106217 259.391396 L 110.792544 260.059592 L 111.517811 260.749487 L 112.732987 261.89968 L 113.463779 262.529989 L 114.220378 263.186086 L 114.967448 263.854448 L 116.025569 264.749217 L 116.801037 265.344128 L 117.580448 265.975376 L 118.37063 266.591005 L 119.3289 267.32553 L 120.153183 267.876943 L 120.970352 268.457005 L 121.766514 269.071152 L 122.643268 269.682309 L 123.4778 270.250033 L 124.339185 270.758992 L 125.191427 271.284622 L 126.659752 272.223185 L 127.560452 272.701216 L 128.435278 273.188866 L 129.32126 273.653579 L 130.739614 274.441745 L 131.665634 274.88977 L 132.552177 275.359434 L 133.446921 275.810045 L 134.340502 276.263358 L 135.504623 276.789422 L 136.468415 277.17404 L 137.392849 277.556477 L 138.316778 277.940244 L 139.247024 278.307394 L 140.346608 278.752094 L 141.327375 279.094856 L 142.274197 279.416637 L 143.223627 279.730645 L 144.175573 280.037162 L 145.927841 280.610129 L 146.926783 280.8878 L 147.896196 281.135793 L 148.861212 281.39874 L 149.836567 281.626521 L 150.814914 281.844128 L 152.257896 282.239851 L 153.258992 282.46307 L 154.239491 282.665534 L 155.219891 282.868382 L 156.202985 283.060778 L 157.195196 283.217804 L 158.596452 283.534445 L 159.594804 283.70952 L 160.583051 283.873212 L 161.56888 284.047583 L 162.557699 284.208747 L 163.545404 284.374828 L 164.537103 284.52327 L 165.635746 284.651764 L 166.626275 284.79097 L 167.62826 284.878941 L 168.629842 284.968949 L 169.631701 285.05756 L 170.619374 285.217848 L 171.620404 285.310643 L 173.366427 285.578994 L 174.342678 285.706215 L 175.334943 285.836446 L 176.324352 285.983334 L 177.319395 286.097372 L 178.309407 286.240743 L 179.300126 286.37999 L 180.294316 286.498997 L 181.283077 286.649662 L 182.40399 286.819892 L 183.373434 286.949984 L 184.365484 287.077256 L 185.357299 287.206115 L 186.347603 287.345213 L 187.336728 287.492289 L 188.324981 287.64528 L 189.312888 287.800611 L 190.298746 287.969819 L 192.075455 288.257497 L 193.046842 288.392725 L 194.034774 288.551108 L 195.024806 288.692897 L 196.014583 288.836709 L 197.000501 289.011008 L 197.987087 289.180026 L 198.973765 289.348322 L 199.962971 289.496633 L 200.950003 289.662129 L 201.931436 289.871869 L 203.084759 290.060556 L 204.062382 290.230494 L 205.051892 290.38159 L 206.034598 290.595879 L 207.020613 290.779439 L 208.010964 290.922733 L 208.99934 291.084367 L 209.985552 291.266098 L 210.973531 291.431419 L 211.963867 291.574846 L 212.946124 291.793311 L 213.933772 291.961704 L 215.456043 292.176435 L 216.44705 292.366026 L 217.439466 292.494696 L 218.432116 292.620802 L 219.419664 292.802862 L 220.411603 292.936761 L 221.40263 293.080674 L 222.395514 293.204208 L 223.385672 293.357647 L 224.37665 293.502084 L 225.367331 293.649779 L 226.361194 293.762582 L 227.353091 293.896946 L 229.247785 294.116996 L 230.256922 294.211404 L 231.251845 294.315884 L 232.248075 294.403337 L 233.244796 294.484382 L 234.241434 294.566502 L 235.2385 294.643042 L 236.235807 294.71645 L 237.233146 294.789436 L 238.230662 294.86012 L 239.228716 294.923795 L 240.227593 294.976728 L 241.225802 295.038376 L 242.224675 295.091362 L 243.224524 295.131639 L 245.194758 295.251106 L 246.205224 295.285947 L 247.208209 295.271342 L 248.2085 295.298792 L 249.208099 295.337047 L 250.210571 295.330445 L 251.21435 295.303456 L 252.216265 295.305552 L 253.216369 295.335934 L 254.216529 295.36543 L 255.220712 295.332116 L 256.221709 295.34855 L 257.221678 295.381034 L 258.222425 295.401365 L 259.224865 295.395266 L 260.226008 295.409427 L 261.226179 295.438747 L 262.231143 295.393249 L 263.272267 295.426401 L 264.271346 295.442036 L 265.274194 295.414917 L 266.274829 295.42949 L 267.275637 295.440784 L 268.27648 295.451431 L 269.280891 295.39487 L 270.284165 295.359721 L 271.286716 295.338193 L 272.289999 295.302872 L 273.292519 295.281928 L 274.293719 295.285843 L 275.295262 295.283317 L 276.295695 295.301679 L 277.294918 295.342837 L 278.29469 295.373657 L 279.293919 295.414708 L 280.292606 295.465972 L 281.290912 295.524393 L 282.288647 295.593581 L 284.088582 295.705657 L 285.077144 295.779884 L 286.075615 295.83675 L 287.073378 295.909877 L 288.069688 296.016355 L 289.066595 296.109143 L 290.063642 296.198701 L 291.059117 296.324365 L 292.056173 296.413738 L 293.053732 296.491544 L 294.050455 296.588546 L 295.04564 296.720862 L 296.043338 296.795485 L 297.037689 296.946945 L 298.031865 297.102424 L 299.029376 297.181342 L 300.02474 297.309562 L 301.020938 297.41862 L 302.01555 297.564091 L 303.009546 297.72371 L 304.006828 297.807876 L 305.004093 297.89244 L 306.001551 297.97256 L 306.99882 298.057031 L 308.253736 298.18783 L 309.25425 298.299319 L 310.252542 298.365306 L 311.250983 298.427099 L 312.248361 298.518964 L 313.246164 298.598771 L 314.24448 298.66409 L 315.242901 298.726448 L 316.240773 298.804306 L 317.238282 298.892457 L 318.236566 298.958678 L 319.235014 299.020255 L 320.233863 299.070498 L 321.232169 299.136087 L 322.230792 299.192722 L 323.229572 299.244919 L 324.228781 299.284951 L 325.228136 299.320879 L 326.227584 299.354153 L 327.227167 299.383615 L 328.227202 299.400298 L 329.22771 299.403581 L 330.228727 299.392489 L 331.229584 299.385888 L 332.231316 299.354544 L 333.233132 299.32084 L 334.234181 299.308813 L 335.235377 299.292646 L 336.644884 299.302734 L 337.650476 299.261826 L 338.651961 299.223678 L 339.654647 299.143167 L 340.656095 299.106301 L 341.658761 299.026492 L 342.660089 298.993868 L 343.661067 298.973558 L 344.662827 298.925711 L 345.664113 298.894559 L 346.665827 298.848316 L 347.668794 298.757893 L 348.671169 298.688343 L 349.673009 298.637681 L 350.673904 298.620309 L 351.674275 298.621403 L 352.675111 298.606114 L 353.676086 298.585905 L 354.676584 298.582539 L 355.678457 298.530697 L 356.67994 298.492586 L 357.680219 298.496927 L 358.681533 298.464808 L 359.681761 298.470941 L 360.681886 298.480703 L 361.682316 298.479744 L 362.682359 298.492406 L 363.682192 298.512465 L 364.68208 298.530589 L 365.681972 298.548605 L 366.68155 298.577639 L 367.681041 298.609773 L 368.680173 298.654563 L 369.931243 298.70219 L 370.925472 298.735551 L 371.924491 298.789824 L 372.923638 298.838493 L 373.922657 298.892797 L 374.921872 298.938504 L 375.921207 298.978997 L 376.919803 299.0517 L 377.918449 299.122251 L 378.916545 299.216844 L 379.915005 299.295496 L 380.914143 299.34459 L 381.913176 299.398255 L 382.910858 299.510892 L 383.908653 299.618568 L 384.906889 299.707048 L 385.905577 299.775764 L 386.90433 299.841654 L 387.902659 299.926054 L 388.90011 300.048757 L 389.89883 300.116079 L 390.897421 300.189018 L 391.894368 300.333731 L 392.892739 300.416312 L 393.891754 300.470773 L 394.890751 300.526012 L 395.889239 300.603461 L 396.888003 300.668853 L 397.886562 300.743215 L 398.884275 300.854481 L 399.883229 300.911572 L 400.881961 300.978398 L 401.880239 301.064998 L 403.125459 301.168742 L 403.1424 300.429259 " + clip-path="url(#p53efc7421d)" + style="fill: none; stroke: #ffffff; stroke-width: 4; stroke-linecap: square" + id="path9" /> + <path + d="M 65.62632 -1 L 65.623625 0.00049 L 65.615428 1.001139 L 65.54645 2.003534 L 65.542671 3.004056 L 65.497805 4.005758 L 65.487983 5.006453 L 65.481313 6.007058 L 65.452425 7.008301 L 65.410796 8.00991 L 65.387582 9.010991 L 65.357245 10.012275 L 65.297688 11.0144 L 65.280291 12.015313 L 65.266626 13.016118 L 65.264874 14.016582 L 65.267569 15.016917 L 65.275105 16.017113 L 65.249555 17.018261 L 65.250357 18.018651 L 65.249374 19.019092 L 65.252718 20.019409 L 65.27025 21.019318 L 65.288859 22.019196 L 65.317792 23.018777 L 65.356026 24.018091 L 65.396403 25.017344 L 65.456148 26.016039 L 65.496039 27.015306 L 65.554873 28.014028 L 65.643353 29.011898 L 65.709257 30.010417 L 65.777066 31.008881 L 65.875969 32.972894 L 65.946725 33.977527 L 66.051898 34.974264 L 66.12879 35.972071 L 66.209229 36.969744 L 66.317554 37.966362 L 66.391713 38.964272 L 66.487869 39.96135 L 66.636537 40.956442 L 66.74494 41.953057 L 66.895594 42.948074 L 66.979128 43.94563 L 67.078163 44.942599 L 67.164422 45.940052 L 67.282982 46.936282 L 67.43921 47.931089 L 67.547166 48.927721 L 67.668163 49.923859 L 67.739076 50.921892 L 67.828071 51.919241 L 67.934216 52.915942 L 68.038178 53.912725 L 68.152835 54.909103 L 68.217926 55.907356 L 68.282179 56.905641 L 68.342608 57.90407 L 68.39992 58.902618 L 68.46409 59.900906 L 68.55162 60.89831 L 68.624463 61.89627 L 68.698097 62.8942 L 68.751248 63.892905 L 68.804801 64.891594 L 68.846006 65.890751 L 68.886216 66.889945 L 68.923525 67.889249 L 68.983723 69.531925 L 69.019376 70.519785 L 69.060395 71.518979 L 69.088283 72.518822 L 69.114678 73.518739 L 69.146864 74.518369 L 69.177823 75.518061 L 69.206794 76.51785 L 69.239613 77.517449 L 69.22631 78.51933 L 69.200535 79.521827 L 69.217335 80.522218 L 69.199252 81.524335 L 69.19467 82.525784 L 69.210406 83.526228 L 69.169788 84.529459 L 69.190687 85.529648 L 69.208638 86.529982 L 69.227064 87.530293 L 69.221722 88.53178 L 69.206612 89.53375 L 69.217862 90.534416 L 69.171443 91.537934 L 69.171644 92.539146 L 69.177027 93.540102 L 69.186351 94.540864 L 69.127516 95.544996 L 69.135337 96.545831 L 69.124445 97.583556 L 69.117327 98.589227 L 69.075553 99.593805 L 69.101163 100.594161 L 69.117901 101.595073 L 69.112067 102.597399 L 69.125942 103.59849 L 69.111022 104.601385 L 69.143067 105.601338 L 69.136214 106.603728 L 69.174813 107.60327 L 69.208773 108.603103 L 69.229588 109.60376 L 69.27058 110.603152 L 69.319185 111.602067 L 69.35504 112.601782 L 69.408274 113.600407 L 69.458378 114.599229 L 69.50987 115.597963 L 69.566742 116.596361 L 69.624513 117.594702 L 69.692576 118.592399 L 69.777738 119.739256 L 69.863397 120.750051 L 69.965266 121.745157 L 70.065923 122.740358 L 70.179154 123.734585 L 70.282197 124.729601 L 70.38161 125.724897 L 70.527323 126.716611 L 70.678794 127.707878 L 70.849652 128.697646 L 70.97771 129.690726 L 71.108641 130.683583 L 71.220945 131.677882 L 71.403875 132.666715 L 71.533142 133.659702 L 71.647097 134.653873 L 71.755194 135.648497 L 71.966574 137.587295 L 72.127215 138.57948 L 72.269181 139.570559 L 72.427362 140.560119 L 72.558656 141.552198 L 72.693742 142.543921 L 72.828849 143.535643 L 72.981379 144.525732 L 73.187319 145.510818 L 73.332615 146.501585 L 73.465133 147.493549 L 73.605303 148.484796 L 73.755107 149.475141 L 73.880901 150.467735 L 74.089312 152.304535 L 74.231025 153.284892 L 74.375932 154.274931 L 74.544788 155.262299 L 74.700533 156.25113 L 74.840813 157.241685 L 75.001726 158.229938 L 75.137607 159.220984 L 75.269367 160.212489 L 75.414957 161.202452 L 75.549936 162.193598 L 75.674755 163.185877 L 75.859298 164.669696 L 76.002447 165.64111 L 76.144706 166.631019 L 76.280306 167.6218 L 76.416944 168.612445 L 76.551887 169.603312 L 76.679933 170.595082 L 76.807044 171.586974 L 76.925798 172.57996 L 77.027615 173.575164 L 77.200817 175.235419 L 77.327888 176.208648 L 77.437526 177.203464 L 77.548052 178.198145 L 77.679306 179.189678 L 77.8072 180.181721 L 77.89145 181.180392 L 77.992452 182.17652 L 78.069727 183.17625 L 78.222532 184.390967 L 78.316895 185.377432 L 78.450942 186.369146 L 78.549703 187.367014 L 78.618967 188.370025 L 78.72195 189.367156 L 78.790057 190.370369 L 78.907635 191.364955 L 78.968504 192.43285 L 79.094342 193.429735 L 79.175342 194.433158 L 79.320745 195.423802 L 79.480446 196.41161 L 79.585411 197.410278 L 79.727551 198.401569 L 79.858518 199.513305 L 80.01267 200.518739 L 80.185639 201.504776 L 80.333941 202.496339 L 80.503614 203.483114 L 80.705247 204.462729 L 80.970823 205.771754 L 81.208463 206.77257 L 81.439524 207.745701 L 81.652274 208.723556 L 81.886148 209.695962 L 82.12783 210.666353 L 82.373435 211.635733 L 82.616873 212.605672 L 82.948245 213.880046 L 83.253759 214.875087 L 83.558752 215.827583 L 83.878588 216.775594 L 84.204211 217.721856 L 84.526794 218.669037 L 84.876436 219.608041 L 85.238755 220.732965 L 85.627302 221.692365 L 85.981124 222.62801 L 86.363902 223.553525 L 86.723644 224.487099 L 87.10124 225.414426 L 87.557991 226.62142 L 88.013427 227.542336 L 88.449672 228.444799 L 88.929327 229.329851 L 89.371655 230.229875 L 90.06719 231.653606 L 90.55581 232.534187 L 91.069233 233.399147 L 91.519804 234.292755 L 92.028156 235.160027 L 92.53738 236.036614 L 93.027897 236.890589 L 93.515562 237.764294 L 94.018909 238.629939 L 94.760166 239.985381 L 95.278107 240.812752 L 95.835637 241.645661 L 96.368411 242.49282 L 96.992857 243.476372 L 97.556404 244.262897 L 98.138955 245.077295 L 99.174507 246.611243 L 99.750898 247.370904 L 100.348324 248.172979 L 100.967562 248.959328 L 101.995082 250.359155 L 102.610655 251.072353 L 103.259851 251.833246 L 103.897811 252.603337 L 104.769185 253.663765 L 105.406249 254.356161 L 106.075839 255.098982 L 106.741516 255.845414 L 107.453787 256.664083 L 108.125554 257.332034 L 108.807346 258.065474 L 110.106217 259.391396 L 110.792544 260.059592 L 111.517811 260.749487 L 112.732987 261.89968 L 113.463779 262.529989 L 114.220378 263.186086 L 114.967448 263.854448 L 116.025569 264.749217 L 116.801037 265.344128 L 117.580448 265.975376 L 118.37063 266.591005 L 119.3289 267.32553 L 120.153183 267.876943 L 120.970352 268.457005 L 121.766514 269.071152 L 122.643268 269.682309 L 123.4778 270.250033 L 124.339185 270.758992 L 125.191427 271.284622 L 126.659752 272.223185 L 127.560452 272.701216 L 128.435278 273.188866 L 129.32126 273.653579 L 130.739614 274.441745 L 131.665634 274.88977 L 132.552177 275.359434 L 133.446921 275.810045 L 134.340502 276.263358 L 135.504623 276.789422 L 136.468415 277.17404 L 137.392849 277.556477 L 138.316778 277.940244 L 139.247024 278.307394 L 140.346608 278.752094 L 141.327375 279.094856 L 142.274197 279.416637 L 143.223627 279.730645 L 144.175573 280.037162 L 145.927841 280.610129 L 146.926783 280.8878 L 147.896196 281.135793 L 148.861212 281.39874 L 149.836567 281.626521 L 150.814914 281.844128 L 152.257896 282.239851 L 153.258992 282.46307 L 154.239491 282.665534 L 155.219891 282.868382 L 156.202985 283.060778 L 157.195196 283.217804 L 158.596452 283.534445 L 159.594804 283.70952 L 160.583051 283.873212 L 161.56888 284.047583 L 162.557699 284.208747 L 163.545404 284.374828 L 164.537103 284.52327 L 165.635746 284.651764 L 166.626275 284.79097 L 167.62826 284.878941 L 168.629842 284.968949 L 169.631701 285.05756 L 170.619374 285.217848 L 171.620404 285.310643 L 173.366427 285.578994 L 174.342678 285.706215 L 175.334943 285.836446 L 176.324352 285.983334 L 177.319395 286.097372 L 178.309407 286.240743 L 179.300126 286.37999 L 180.294316 286.498997 L 181.283077 286.649662 L 182.40399 286.819892 L 183.373434 286.949984 L 184.365484 287.077256 L 185.357299 287.206115 L 186.347603 287.345213 L 187.336728 287.492289 L 188.324981 287.64528 L 189.312888 287.800611 L 190.298746 287.969819 L 192.075455 288.257497 L 193.046842 288.392725 L 194.034774 288.551108 L 195.024806 288.692897 L 196.014583 288.836709 L 197.000501 289.011008 L 197.987087 289.180026 L 198.973765 289.348322 L 199.962971 289.496633 L 200.950003 289.662129 L 201.931436 289.871869 L 203.084759 290.060556 L 204.062382 290.230494 L 205.051892 290.38159 L 206.034598 290.595879 L 207.020613 290.779439 L 208.010964 290.922733 L 208.99934 291.084367 L 209.985552 291.266098 L 210.973531 291.431419 L 211.963867 291.574846 L 212.946124 291.793311 L 213.933772 291.961704 L 215.456043 292.176435 L 216.44705 292.366026 L 217.439466 292.494696 L 218.432116 292.620802 L 219.419664 292.802862 L 220.411603 292.936761 L 221.40263 293.080674 L 222.395514 293.204208 L 223.385672 293.357647 L 224.37665 293.502084 L 225.367331 293.649779 L 226.361194 293.762582 L 227.353091 293.896946 L 229.247785 294.116996 L 230.256922 294.211404 L 231.251845 294.315884 L 232.248075 294.403337 L 233.244796 294.484382 L 234.241434 294.566502 L 235.2385 294.643042 L 236.235807 294.71645 L 237.233146 294.789436 L 238.230662 294.86012 L 239.228716 294.923795 L 240.227593 294.976728 L 241.225802 295.038376 L 242.224675 295.091362 L 243.224524 295.131639 L 245.194758 295.251106 L 246.205224 295.285947 L 247.208209 295.271342 L 248.2085 295.298792 L 249.208099 295.337047 L 250.210571 295.330445 L 251.21435 295.303456 L 252.216265 295.305552 L 253.216369 295.335934 L 254.216529 295.36543 L 255.220712 295.332116 L 256.221709 295.34855 L 257.221678 295.381034 L 258.222425 295.401365 L 259.224865 295.395266 L 260.226008 295.409427 L 261.226179 295.438747 L 262.231143 295.393249 L 263.272267 295.426401 L 264.271346 295.442036 L 265.274194 295.414917 L 266.274829 295.42949 L 267.275637 295.440784 L 268.27648 295.451431 L 269.280891 295.39487 L 270.284165 295.359721 L 271.286716 295.338193 L 272.289999 295.302872 L 273.292519 295.281928 L 274.293719 295.285843 L 275.295262 295.283317 L 276.295695 295.301679 L 277.294918 295.342837 L 278.29469 295.373657 L 279.293919 295.414708 L 280.292606 295.465972 L 281.290912 295.524393 L 282.288647 295.593581 L 284.088582 295.705657 L 285.077144 295.779884 L 286.075615 295.83675 L 287.073378 295.909877 L 288.069688 296.016355 L 289.066595 296.109143 L 290.063642 296.198701 L 291.059117 296.324365 L 292.056173 296.413738 L 293.053732 296.491544 L 294.050455 296.588546 L 295.04564 296.720862 L 296.043338 296.795485 L 297.037689 296.946945 L 298.031865 297.102424 L 299.029376 297.181342 L 300.02474 297.309562 L 301.020938 297.41862 L 302.01555 297.564091 L 303.009546 297.72371 L 304.006828 297.807876 L 305.004093 297.89244 L 306.001551 297.97256 L 306.99882 298.057031 L 308.253736 298.18783 L 309.25425 298.299319 L 310.252542 298.365306 L 311.250983 298.427099 L 312.248361 298.518964 L 313.246164 298.598771 L 314.24448 298.66409 L 315.242901 298.726448 L 316.240773 298.804306 L 317.238282 298.892457 L 318.236566 298.958678 L 319.235014 299.020255 L 320.233863 299.070498 L 321.232169 299.136087 L 322.230792 299.192722 L 323.229572 299.244919 L 324.228781 299.284951 L 325.228136 299.320879 L 326.227584 299.354153 L 327.227167 299.383615 L 328.227202 299.400298 L 329.22771 299.403581 L 330.228727 299.392489 L 331.229584 299.385888 L 332.231316 299.354544 L 333.233132 299.32084 L 334.234181 299.308813 L 335.235377 299.292646 L 336.644884 299.302734 L 337.650476 299.261826 L 338.651961 299.223678 L 339.654647 299.143167 L 340.656095 299.106301 L 341.658761 299.026492 L 342.660089 298.993868 L 343.661067 298.973558 L 344.662827 298.925711 L 345.664113 298.894559 L 346.665827 298.848316 L 347.668794 298.757893 L 348.671169 298.688343 L 349.673009 298.637681 L 350.673904 298.620309 L 351.674275 298.621403 L 352.675111 298.606114 L 353.676086 298.585905 L 354.676584 298.582539 L 355.678457 298.530697 L 356.67994 298.492586 L 357.680219 298.496927 L 358.681533 298.464808 L 359.681761 298.470941 L 360.681886 298.480703 L 361.682316 298.479744 L 362.682359 298.492406 L 363.682192 298.512465 L 364.68208 298.530589 L 365.681972 298.548605 L 366.68155 298.577639 L 367.681041 298.609773 L 368.680173 298.654563 L 369.931243 298.70219 L 370.925472 298.735551 L 371.924491 298.789824 L 372.923638 298.838493 L 373.922657 298.892797 L 374.921872 298.938504 L 375.921207 298.978997 L 376.919803 299.0517 L 377.918449 299.122251 L 378.916545 299.216844 L 379.915005 299.295496 L 380.914143 299.34459 L 381.913176 299.398255 L 382.910858 299.510892 L 383.908653 299.618568 L 384.906889 299.707048 L 385.905577 299.775764 L 386.90433 299.841654 L 387.902659 299.926054 L 388.90011 300.048757 L 389.89883 300.116079 L 390.897421 300.189018 L 391.894368 300.333731 L 392.892739 300.416312 L 393.891754 300.470773 L 394.890751 300.526012 L 395.889239 300.603461 L 396.888003 300.668853 L 397.886562 300.743215 L 398.884275 300.854481 L 399.883229 300.911572 L 400.881961 300.978398 L 401.880239 301.064998 L 403.125459 301.168742 L 403.1424 300.429259 " + clip-path="url(#p53efc7421d)" + style="fill: none; stroke: #0000ff; stroke-width: 2; stroke-linecap: square" + id="path10" /> + </g> + <g + id="patch_3"> + <path + d="M 59.602588 307.584 L 60.602588 307.615436 L 61.602588 307.652377 L 62.602588 307.750123 L 63.602588 307.782645 L 64.602588 307.85627 L 65.602588 307.894835 L 66.602588 307.930248 L 67.602588 307.987888 L 68.602588 308.058274 L 69.602588 308.110239 L 70.602588 308.169328 L 71.602588 308.257649 L 72.602588 308.303794 L 73.602588 308.346205 L 74.602588 308.376697 L 75.602588 308.402742 L 76.602588 308.423942 L 77.602588 308.478243 L 78.602588 308.506181 L 79.602588 308.535905 L 80.602588 308.5613 L 81.602588 308.5725 L 82.602588 308.582624 L 83.602588 308.58242 L 84.602588 308.57291 L 85.602588 308.561256 L 86.602588 308.530227 L 87.602588 308.519059 L 88.602588 308.488942 L 89.602588 308.429165 L 90.602588 308.391973 L 91.602588 308.352877 L 92.602588 308.310437 L 93.602588 308.277672 L 94.602588 308.210246 L 95.602588 308.17112 L 96.602588 308.128445 L 97.602588 308.057865 L 98.602588 308.021474 L 99.602588 307.963071 L 100.602588 307.852118 L 101.602588 307.78146 L 102.602588 307.66852 L 103.602588 307.622747 L 104.602588 307.561464 L 105.602588 307.512965 L 106.602588 307.432142 L 107.602588 307.313623 L 108.602588 307.243412 L 109.602588 307.16015 L 110.602588 307.127008 L 111.602588 307.075771 L 112.602588 307.007372 L 113.602588 306.941157 L 114.602588 306.86424 L 115.602588 306.836924 L 116.602588 306.810447 L 117.602588 306.787796 L 118.602588 306.768265 L 119.602588 306.741871 L 120.602588 306.6921 L 121.602588 306.657027 L 122.602588 306.621161 L 123.602588 306.605794 L 124.602588 306.590025 L 125.602588 306.586612 L 126.602588 306.584195 L 127.602588 306.584681 L 128.602588 306.58661 L 129.602588 306.599867 L 130.602588 306.608258 L 131.602588 306.629794 L 132.602588 306.652827 L 133.602588 306.67006 L 134.602588 306.688523 L 135.602588 306.708975 L 136.602588 306.725575 L 137.602588 306.788354 L 138.602588 306.863619 L 139.602588 306.896258 L 140.602588 306.963822 L 141.602588 307.017869 L 142.602588 307.051573 L 143.602588 307.141699 L 144.602588 307.170234 L 145.602588 307.20172 L 146.602588 307.232731 L 147.602588 307.287539 L 148.602588 307.352126 L 149.602588 307.390322 L 150.602588 307.486256 L 151.602588 307.535514 L 152.602588 307.579583 L 153.602588 307.619707 L 154.602588 307.728074 L 155.602588 307.769702 L 156.602588 307.831844 L 157.602588 307.901806 L 158.602588 308.00631 L 159.602588 308.043298 L 160.602588 308.089175 L 161.602588 308.15767 L 162.602588 308.206416 L 163.602588 308.284013 L 164.602588 308.314554 L 165.602588 308.384068 L 166.602588 308.408041 L 167.602588 308.436663 L 168.602588 308.478456 L 169.602588 308.500032 L 170.602588 308.51398 L 171.602588 308.540702 L 172.602588 308.550012 L 173.602588 308.562459 L 174.602588 308.573514 L 175.602588 308.579178 L 176.602588 308.583942 L 177.602588 308.578394 L 178.602588 308.565106 L 179.602588 308.557589 L 180.602588 308.532804 L 181.602588 308.509235 L 182.602588 308.473055 L 183.602588 308.447093 L 184.602588 308.424771 L 185.602588 308.356011 L 186.602588 308.281476 L 187.602588 308.187497 L 188.602588 308.136445 L 189.602588 308.082511 L 190.602588 308.04726 L 191.602588 307.941172 L 192.602588 307.888908 L 193.602588 307.852001 L 194.602588 307.82097 L 195.602588 307.759815 L 196.602588 307.692395 L 197.602588 307.643489 L 198.602588 307.578297 L 199.602588 307.540109 L 200.602588 307.498113 L 201.602588 307.456096 L 202.602588 307.39658 L 203.602588 307.28342 L 204.602588 307.231169 L 205.602588 307.191751 L 206.602588 307.14465 L 207.602588 307.08787 L 208.602588 307.055207 L 209.602588 307.019029 L 210.602588 306.986939 L 211.602588 306.952659 L 212.602588 306.894281 L 213.602588 306.849096 L 214.602588 306.819472 L 215.602588 306.769086 L 216.602588 306.743889 L 217.602588 306.722838 L 218.602588 306.68787 L 219.602588 306.66358 L 220.602588 306.649513 L 221.602588 306.630571 L 222.602588 306.61491 L 223.602588 306.602358 L 224.602588 306.596522 L 225.602588 306.58964 L 226.602588 306.584466 L 227.602588 306.586249 L 228.602588 306.588974 L 229.602588 306.600128 L 230.602588 306.628363 L 231.602588 306.672151 L 232.602588 306.69284 L 233.602588 306.733813 L 234.602588 306.773888 L 235.602588 306.792998 L 236.602588 306.815507 L 237.602588 306.882158 L 238.602588 306.931868 L 239.602588 307.005574 L 240.602588 307.036888 L 241.602588 307.11351 L 242.602588 307.151808 L 243.602588 307.225925 L 244.602588 307.329983 L 245.602588 307.399814 L 246.602588 307.505048 L 247.602588 307.560063 L 248.602588 307.683538 L 249.602588 307.754097 L 250.602588 307.869936 L 251.602588 307.920117 L 252.602588 307.955721 L 253.602588 308.047128 L 254.602588 308.100636 L 255.602588 308.188544 L 256.602588 308.257729 L 257.602588 308.304493 L 258.602588 308.376537 L 259.602588 308.426679 L 260.602588 308.444069 L 261.602588 308.471072 L 262.602588 308.490499 L 263.602588 308.509837 L 264.602588 308.548086 L 265.602588 308.564519 L 266.602588 308.572888 L 267.602588 308.577207 L 268.602588 308.583762 L 269.602588 308.581216 L 270.602588 308.575757 L 271.602588 308.559329 L 272.602588 308.527394 L 273.602588 308.489414 L 274.602588 308.45461 L 275.602588 308.391538 L 276.602588 308.370111 L 277.602588 308.319493 L 278.602588 308.294536 L 279.602588 308.238902 L 280.602588 308.207673 L 281.602588 308.157529 L 282.602588 308.125036 L 283.602588 308.044624 L 284.602588 307.975698 L 285.602588 307.860001 L 286.602588 307.784522 L 287.602588 307.668997 L 288.602588 307.589513 L 289.602588 307.481072 L 290.602588 307.441704 L 291.602588 307.338836 L 292.602588 307.239038 L 293.602588 307.193541 L 294.602588 307.159219 L 295.602588 307.107263 L 296.602588 307.067616 L 297.602588 307.032102 L 298.602588 306.964457 L 299.602588 306.925375 L 300.602588 306.874894 L 301.602588 306.825588 L 302.602588 306.774518 L 303.602588 306.730279 L 304.602588 306.708259 L 305.602588 306.692703 L 306.602588 306.650256 L 307.602588 306.635388 L 308.602588 306.61266 L 309.602588 306.592344 L 310.602588 306.586547 L 311.602588 306.584065 L 312.602588 306.587122 L 313.602588 306.598718 L 314.602588 306.615638 L 315.602588 306.647299 L 316.602588 306.661382 L 317.602588 306.714054 L 318.602588 306.763143 L 319.602588 306.817844 L 320.602588 306.862192 L 321.602588 306.932184 L 322.602588 306.982567 L 323.602588 307.036474 L 324.602588 307.105913 L 325.602588 307.163301 L 326.602588 307.213466 L 327.602588 307.290628 L 328.602588 307.348818 L 329.602588 307.409456 L 330.602588 307.446657 L 331.602588 307.511749 L 332.602588 307.616879 L 333.602588 307.677181 L 334.602588 307.773503 L 335.602588 307.805506 L 336.602588 307.856523 L 337.602588 307.973315 L 338.602588 308.008762 L 339.602588 308.064642 L 340.602588 308.095018 L 341.602588 308.183404 L 342.602588 308.228168 L 343.602588 308.309056 L 344.602588 308.369202 L 345.602588 308.432288 L 346.602588 308.455236 L 347.602588 308.471406 L 348.602588 308.500335 L 349.602588 308.530687 L 350.602588 308.543261 L 351.602588 308.56814 L 352.602588 308.580224 L 353.602588 308.583986 L 354.602588 308.57955 L 355.602588 308.567211 L 356.602588 308.552798 L 357.602588 308.536725 L 358.602588 308.501204 L 359.602588 308.48127 L 360.602588 308.424681 L 361.602588 308.357487 L 362.602588 308.330117 L 363.602588 308.295969 L 364.602588 308.247289 L 365.602588 308.199004 L 366.602588 308.139927 L 367.602588 308.044322 L 368.602588 308.001182 L 369.602588 307.951334 L 370.602588 307.8928 L 371.602588 307.845214 L 372.602588 307.784086 L 373.602588 307.728001 L 374.602588 307.65383 L 375.602588 307.536592 L 376.602588 307.480868 L 377.602588 307.372642 L 378.602588 307.266492 L 379.602588 307.15892 L 380.602588 307.124412 L 381.602588 307.021105 L 382.602588 306.945381 L 383.602588 306.905946 L 384.602588 306.866562 L 385.602588 306.84408 L 386.602588 306.788267 L 387.602588 306.762215 L 388.602588 306.73198 L 389.602588 306.681209 L 390.602588 306.662558 L 391.602588 306.640849 L 392.602588 306.628203 L 393.602588 306.60921 L 394.602588 306.59182 L 395.602588 306.584782 L 396.602588 306.585806 L 397.602588 306.59281 L 398.602588 306.60218 L 399.602588 306.625578 L 400.602588 306.650661 L 401.602588 306.66306 L 402.602588 306.696153 L 403.602588 306.71252 L 404.602588 306.730925 L 405.602588 306.780062 L 406.602588 306.823875 L 407.602588 306.86696 L 408.602588 306.889901 L 409.602588 306.930164 L 411.599771 307.015024 " + style="fill: none; stroke: #ffffff; stroke-width: 4; stroke-linecap: round" + id="path11" /> + <path + d="M 59.602588 307.584 L 60.602588 307.615436 L 61.602588 307.652377 L 62.602588 307.750123 L 63.602588 307.782645 L 64.602588 307.85627 L 65.602588 307.894835 L 66.602588 307.930248 L 67.602588 307.987888 L 68.602588 308.058274 L 69.602588 308.110239 L 70.602588 308.169328 L 71.602588 308.257649 L 72.602588 308.303794 L 73.602588 308.346205 L 74.602588 308.376697 L 75.602588 308.402742 L 76.602588 308.423942 L 77.602588 308.478243 L 78.602588 308.506181 L 79.602588 308.535905 L 80.602588 308.5613 L 81.602588 308.5725 L 82.602588 308.582624 L 83.602588 308.58242 L 84.602588 308.57291 L 85.602588 308.561256 L 86.602588 308.530227 L 87.602588 308.519059 L 88.602588 308.488942 L 89.602588 308.429165 L 90.602588 308.391973 L 91.602588 308.352877 L 92.602588 308.310437 L 93.602588 308.277672 L 94.602588 308.210246 L 95.602588 308.17112 L 96.602588 308.128445 L 97.602588 308.057865 L 98.602588 308.021474 L 99.602588 307.963071 L 100.602588 307.852118 L 101.602588 307.78146 L 102.602588 307.66852 L 103.602588 307.622747 L 104.602588 307.561464 L 105.602588 307.512965 L 106.602588 307.432142 L 107.602588 307.313623 L 108.602588 307.243412 L 109.602588 307.16015 L 110.602588 307.127008 L 111.602588 307.075771 L 112.602588 307.007372 L 113.602588 306.941157 L 114.602588 306.86424 L 115.602588 306.836924 L 116.602588 306.810447 L 117.602588 306.787796 L 118.602588 306.768265 L 119.602588 306.741871 L 120.602588 306.6921 L 121.602588 306.657027 L 122.602588 306.621161 L 123.602588 306.605794 L 124.602588 306.590025 L 125.602588 306.586612 L 126.602588 306.584195 L 127.602588 306.584681 L 128.602588 306.58661 L 129.602588 306.599867 L 130.602588 306.608258 L 131.602588 306.629794 L 132.602588 306.652827 L 133.602588 306.67006 L 134.602588 306.688523 L 135.602588 306.708975 L 136.602588 306.725575 L 137.602588 306.788354 L 138.602588 306.863619 L 139.602588 306.896258 L 140.602588 306.963822 L 141.602588 307.017869 L 142.602588 307.051573 L 143.602588 307.141699 L 144.602588 307.170234 L 145.602588 307.20172 L 146.602588 307.232731 L 147.602588 307.287539 L 148.602588 307.352126 L 149.602588 307.390322 L 150.602588 307.486256 L 151.602588 307.535514 L 152.602588 307.579583 L 153.602588 307.619707 L 154.602588 307.728074 L 155.602588 307.769702 L 156.602588 307.831844 L 157.602588 307.901806 L 158.602588 308.00631 L 159.602588 308.043298 L 160.602588 308.089175 L 161.602588 308.15767 L 162.602588 308.206416 L 163.602588 308.284013 L 164.602588 308.314554 L 165.602588 308.384068 L 166.602588 308.408041 L 167.602588 308.436663 L 168.602588 308.478456 L 169.602588 308.500032 L 170.602588 308.51398 L 171.602588 308.540702 L 172.602588 308.550012 L 173.602588 308.562459 L 174.602588 308.573514 L 175.602588 308.579178 L 176.602588 308.583942 L 177.602588 308.578394 L 178.602588 308.565106 L 179.602588 308.557589 L 180.602588 308.532804 L 181.602588 308.509235 L 182.602588 308.473055 L 183.602588 308.447093 L 184.602588 308.424771 L 185.602588 308.356011 L 186.602588 308.281476 L 187.602588 308.187497 L 188.602588 308.136445 L 189.602588 308.082511 L 190.602588 308.04726 L 191.602588 307.941172 L 192.602588 307.888908 L 193.602588 307.852001 L 194.602588 307.82097 L 195.602588 307.759815 L 196.602588 307.692395 L 197.602588 307.643489 L 198.602588 307.578297 L 199.602588 307.540109 L 200.602588 307.498113 L 201.602588 307.456096 L 202.602588 307.39658 L 203.602588 307.28342 L 204.602588 307.231169 L 205.602588 307.191751 L 206.602588 307.14465 L 207.602588 307.08787 L 208.602588 307.055207 L 209.602588 307.019029 L 210.602588 306.986939 L 211.602588 306.952659 L 212.602588 306.894281 L 213.602588 306.849096 L 214.602588 306.819472 L 215.602588 306.769086 L 216.602588 306.743889 L 217.602588 306.722838 L 218.602588 306.68787 L 219.602588 306.66358 L 220.602588 306.649513 L 221.602588 306.630571 L 222.602588 306.61491 L 223.602588 306.602358 L 224.602588 306.596522 L 225.602588 306.58964 L 226.602588 306.584466 L 227.602588 306.586249 L 228.602588 306.588974 L 229.602588 306.600128 L 230.602588 306.628363 L 231.602588 306.672151 L 232.602588 306.69284 L 233.602588 306.733813 L 234.602588 306.773888 L 235.602588 306.792998 L 236.602588 306.815507 L 237.602588 306.882158 L 238.602588 306.931868 L 239.602588 307.005574 L 240.602588 307.036888 L 241.602588 307.11351 L 242.602588 307.151808 L 243.602588 307.225925 L 244.602588 307.329983 L 245.602588 307.399814 L 246.602588 307.505048 L 247.602588 307.560063 L 248.602588 307.683538 L 249.602588 307.754097 L 250.602588 307.869936 L 251.602588 307.920117 L 252.602588 307.955721 L 253.602588 308.047128 L 254.602588 308.100636 L 255.602588 308.188544 L 256.602588 308.257729 L 257.602588 308.304493 L 258.602588 308.376537 L 259.602588 308.426679 L 260.602588 308.444069 L 261.602588 308.471072 L 262.602588 308.490499 L 263.602588 308.509837 L 264.602588 308.548086 L 265.602588 308.564519 L 266.602588 308.572888 L 267.602588 308.577207 L 268.602588 308.583762 L 269.602588 308.581216 L 270.602588 308.575757 L 271.602588 308.559329 L 272.602588 308.527394 L 273.602588 308.489414 L 274.602588 308.45461 L 275.602588 308.391538 L 276.602588 308.370111 L 277.602588 308.319493 L 278.602588 308.294536 L 279.602588 308.238902 L 280.602588 308.207673 L 281.602588 308.157529 L 282.602588 308.125036 L 283.602588 308.044624 L 284.602588 307.975698 L 285.602588 307.860001 L 286.602588 307.784522 L 287.602588 307.668997 L 288.602588 307.589513 L 289.602588 307.481072 L 290.602588 307.441704 L 291.602588 307.338836 L 292.602588 307.239038 L 293.602588 307.193541 L 294.602588 307.159219 L 295.602588 307.107263 L 296.602588 307.067616 L 297.602588 307.032102 L 298.602588 306.964457 L 299.602588 306.925375 L 300.602588 306.874894 L 301.602588 306.825588 L 302.602588 306.774518 L 303.602588 306.730279 L 304.602588 306.708259 L 305.602588 306.692703 L 306.602588 306.650256 L 307.602588 306.635388 L 308.602588 306.61266 L 309.602588 306.592344 L 310.602588 306.586547 L 311.602588 306.584065 L 312.602588 306.587122 L 313.602588 306.598718 L 314.602588 306.615638 L 315.602588 306.647299 L 316.602588 306.661382 L 317.602588 306.714054 L 318.602588 306.763143 L 319.602588 306.817844 L 320.602588 306.862192 L 321.602588 306.932184 L 322.602588 306.982567 L 323.602588 307.036474 L 324.602588 307.105913 L 325.602588 307.163301 L 326.602588 307.213466 L 327.602588 307.290628 L 328.602588 307.348818 L 329.602588 307.409456 L 330.602588 307.446657 L 331.602588 307.511749 L 332.602588 307.616879 L 333.602588 307.677181 L 334.602588 307.773503 L 335.602588 307.805506 L 336.602588 307.856523 L 337.602588 307.973315 L 338.602588 308.008762 L 339.602588 308.064642 L 340.602588 308.095018 L 341.602588 308.183404 L 342.602588 308.228168 L 343.602588 308.309056 L 344.602588 308.369202 L 345.602588 308.432288 L 346.602588 308.455236 L 347.602588 308.471406 L 348.602588 308.500335 L 349.602588 308.530687 L 350.602588 308.543261 L 351.602588 308.56814 L 352.602588 308.580224 L 353.602588 308.583986 L 354.602588 308.57955 L 355.602588 308.567211 L 356.602588 308.552798 L 357.602588 308.536725 L 358.602588 308.501204 L 359.602588 308.48127 L 360.602588 308.424681 L 361.602588 308.357487 L 362.602588 308.330117 L 363.602588 308.295969 L 364.602588 308.247289 L 365.602588 308.199004 L 366.602588 308.139927 L 367.602588 308.044322 L 368.602588 308.001182 L 369.602588 307.951334 L 370.602588 307.8928 L 371.602588 307.845214 L 372.602588 307.784086 L 373.602588 307.728001 L 374.602588 307.65383 L 375.602588 307.536592 L 376.602588 307.480868 L 377.602588 307.372642 L 378.602588 307.266492 L 379.602588 307.15892 L 380.602588 307.124412 L 381.602588 307.021105 L 382.602588 306.945381 L 383.602588 306.905946 L 384.602588 306.866562 L 385.602588 306.84408 L 386.602588 306.788267 L 387.602588 306.762215 L 388.602588 306.73198 L 389.602588 306.681209 L 390.602588 306.662558 L 391.602588 306.640849 L 392.602588 306.628203 L 393.602588 306.60921 L 394.602588 306.59182 L 395.602588 306.584782 L 396.602588 306.585806 L 397.602588 306.59281 L 398.602588 306.60218 L 399.602588 306.625578 L 400.602588 306.650661 L 401.602588 306.66306 L 402.602588 306.696153 L 403.602588 306.71252 L 404.602588 306.730925 L 405.602588 306.780062 L 406.602588 306.823875 L 407.602588 306.86696 L 408.602588 306.889901 L 409.602588 306.930164 L 411.599771 307.015024 " + style="fill: none; stroke: #000000; stroke-linecap: round" + id="path12" /> + <path + d="M 405.999771 304.784 L 406.880139 305.259331 L 407.758046 305.739585 L 408.608759 306.274226 L 409.488643 306.750528 L 410.350144 307.263593 L 411.460761 307.862019 L 410.550496 307.72152 L 409.630292 308.117178 L 408.704387 308.501437 L 407.786721 308.902172 L 406.865868 309.296534 L 405.698505 309.78147 " + style="fill: none; stroke: #ffffff; stroke-width: 4; stroke-linecap: round" + id="path13" /> + <path + d="M 405.999771 304.784 L 406.880139 305.259331 L 407.758046 305.739585 L 408.608759 306.274226 L 409.488643 306.750528 L 410.350144 307.263593 L 411.460761 307.862019 L 410.550496 307.72152 L 409.630292 308.117178 L 408.704387 308.501437 L 407.786721 308.902172 L 406.865868 309.296534 L 405.698505 309.78147 " + style="fill: none; stroke: #000000; stroke-linecap: round" + id="path14" /> + </g> + <g + id="patch_4"> + <path + d="M 57.6 305.58215 L 57.631436 304.58215 L 57.668377 303.58215 L 57.766123 302.58215 L 57.798645 301.58215 L 57.87227 300.58215 L 57.910835 299.58215 L 57.946248 298.58215 L 58.003888 297.58215 L 58.074274 296.58215 L 58.126239 295.58215 L 58.185328 294.58215 L 58.273649 293.58215 L 58.319794 292.58215 L 58.362205 291.58215 L 58.392697 290.58215 L 58.418742 289.58215 L 58.439942 288.58215 L 58.494243 287.58215 L 58.522181 286.58215 L 58.551905 285.58215 L 58.5773 284.58215 L 58.5885 283.58215 L 58.598624 282.58215 L 58.59842 281.58215 L 58.58891 280.58215 L 58.577256 279.58215 L 58.546227 278.58215 L 58.535059 277.58215 L 58.504942 276.58215 L 58.445165 275.58215 L 58.407973 274.58215 L 58.368877 273.58215 L 58.326437 272.58215 L 58.293672 271.58215 L 58.226246 270.58215 L 58.18712 269.58215 L 58.144445 268.58215 L 58.073865 267.58215 L 58.037474 266.58215 L 57.979071 265.58215 L 57.868118 264.58215 L 57.79746 263.58215 L 57.68452 262.58215 L 57.638747 261.58215 L 57.577464 260.58215 L 57.528965 259.58215 L 57.448142 258.58215 L 57.329623 257.58215 L 57.259412 256.58215 L 57.17615 255.58215 L 57.143008 254.58215 L 57.091771 253.58215 L 57.023372 252.58215 L 56.957157 251.58215 L 56.88024 250.58215 L 56.852924 249.58215 L 56.826447 248.58215 L 56.803796 247.58215 L 56.784265 246.58215 L 56.757871 245.58215 L 56.7081 244.58215 L 56.673027 243.58215 L 56.637161 242.58215 L 56.621794 241.58215 L 56.606025 240.58215 L 56.602612 239.58215 L 56.600195 238.58215 L 56.600681 237.58215 L 56.60261 236.58215 L 56.615867 235.58215 L 56.624258 234.58215 L 56.645794 233.58215 L 56.668827 232.58215 L 56.68606 231.58215 L 56.704523 230.58215 L 56.724975 229.58215 L 56.741575 228.58215 L 56.804354 227.58215 L 56.879619 226.58215 L 56.912258 225.58215 L 56.979822 224.58215 L 57.033869 223.58215 L 57.067573 222.58215 L 57.157699 221.58215 L 57.186234 220.58215 L 57.21772 219.58215 L 57.248731 218.58215 L 57.303539 217.58215 L 57.368126 216.58215 L 57.406322 215.58215 L 57.502256 214.58215 L 57.551514 213.58215 L 57.595583 212.58215 L 57.635707 211.58215 L 57.744074 210.58215 L 57.785702 209.58215 L 57.847844 208.58215 L 57.917806 207.58215 L 58.02231 206.58215 L 58.059298 205.58215 L 58.105175 204.58215 L 58.17367 203.58215 L 58.222416 202.58215 L 58.300013 201.58215 L 58.330554 200.58215 L 58.400068 199.58215 L 58.424041 198.58215 L 58.452663 197.58215 L 58.494456 196.58215 L 58.516032 195.58215 L 58.52998 194.58215 L 58.556702 193.58215 L 58.566012 192.58215 L 58.578459 191.58215 L 58.589514 190.58215 L 58.595178 189.58215 L 58.599942 188.58215 L 58.594394 187.58215 L 58.581106 186.58215 L 58.573589 185.58215 L 58.548804 184.58215 L 58.525235 183.58215 L 58.489055 182.58215 L 58.463093 181.58215 L 58.440771 180.58215 L 58.372011 179.58215 L 58.297476 178.58215 L 58.203497 177.58215 L 58.152445 176.58215 L 58.098511 175.58215 L 58.06326 174.58215 L 57.957172 173.58215 L 57.904908 172.58215 L 57.868001 171.58215 L 57.83697 170.58215 L 57.775815 169.58215 L 57.708395 168.58215 L 57.659489 167.58215 L 57.594297 166.58215 L 57.556109 165.58215 L 57.514113 164.58215 L 57.472096 163.58215 L 57.41258 162.58215 L 57.29942 161.58215 L 57.247169 160.58215 L 57.207751 159.58215 L 57.16065 158.58215 L 57.10387 157.58215 L 57.071207 156.58215 L 57.035029 155.58215 L 57.002939 154.58215 L 56.968659 153.58215 L 56.910281 152.58215 L 56.865096 151.58215 L 56.835472 150.58215 L 56.785086 149.58215 L 56.759889 148.58215 L 56.738838 147.58215 L 56.70387 146.58215 L 56.67958 145.58215 L 56.665513 144.58215 L 56.646571 143.58215 L 56.63091 142.58215 L 56.618358 141.58215 L 56.612522 140.58215 L 56.60564 139.58215 L 56.600466 138.58215 L 56.602249 137.58215 L 56.604974 136.58215 L 56.616128 135.58215 L 56.644363 134.58215 L 56.688151 133.58215 L 56.70884 132.58215 L 56.749813 131.58215 L 56.789888 130.58215 L 56.808998 129.58215 L 56.831507 128.58215 L 56.898158 127.58215 L 56.947868 126.58215 L 57.021574 125.58215 L 57.052888 124.58215 L 57.12951 123.58215 L 57.167808 122.58215 L 57.241925 121.58215 L 57.345983 120.58215 L 57.415814 119.58215 L 57.521048 118.58215 L 57.576063 117.58215 L 57.699538 116.58215 L 57.770097 115.58215 L 57.885936 114.58215 L 57.936117 113.58215 L 57.971721 112.58215 L 58.063128 111.58215 L 58.116636 110.58215 L 58.204544 109.58215 L 58.273729 108.58215 L 58.320493 107.58215 L 58.392537 106.58215 L 58.442679 105.58215 L 58.460069 104.58215 L 58.487072 103.58215 L 58.506499 102.58215 L 58.525837 101.58215 L 58.564086 100.58215 L 58.580519 99.58215 L 58.588888 98.58215 L 58.593207 97.58215 L 58.599762 96.58215 L 58.597216 95.58215 L 58.591757 94.58215 L 58.575329 93.58215 L 58.543394 92.58215 L 58.505414 91.58215 L 58.47061 90.58215 L 58.407538 89.58215 L 58.386111 88.58215 L 58.335493 87.58215 L 58.310536 86.58215 L 58.254902 85.58215 L 58.223673 84.58215 L 58.173529 83.58215 L 58.141036 82.58215 L 58.060624 81.58215 L 57.991698 80.58215 L 57.876001 79.58215 L 57.800522 78.58215 L 57.684997 77.58215 L 57.605513 76.58215 L 57.497072 75.58215 L 57.457704 74.58215 L 57.354836 73.58215 L 57.255038 72.58215 L 57.209541 71.58215 L 57.175219 70.58215 L 57.123263 69.58215 L 57.083616 68.58215 L 57.048102 67.58215 L 56.980457 66.58215 L 56.941375 65.58215 L 56.890894 64.58215 L 56.841588 63.58215 L 56.790518 62.58215 L 56.746279 61.58215 L 56.724259 60.58215 L 56.708703 59.58215 L 56.666256 58.58215 L 56.651388 57.58215 L 56.62866 56.58215 L 56.608344 55.58215 L 56.602547 54.58215 L 56.600065 53.58215 L 56.603122 52.58215 L 56.614718 51.58215 L 56.631638 50.58215 L 56.663299 49.58215 L 56.677382 48.58215 L 56.730054 47.58215 L 56.779143 46.58215 L 56.833844 44.592945 " + style="fill: none; stroke: #ffffff; stroke-width: 4; stroke-linecap: round" + id="path15" /> + <path + d="M 57.6 305.58215 L 57.631436 304.58215 L 57.668377 303.58215 L 57.766123 302.58215 L 57.798645 301.58215 L 57.87227 300.58215 L 57.910835 299.58215 L 57.946248 298.58215 L 58.003888 297.58215 L 58.074274 296.58215 L 58.126239 295.58215 L 58.185328 294.58215 L 58.273649 293.58215 L 58.319794 292.58215 L 58.362205 291.58215 L 58.392697 290.58215 L 58.418742 289.58215 L 58.439942 288.58215 L 58.494243 287.58215 L 58.522181 286.58215 L 58.551905 285.58215 L 58.5773 284.58215 L 58.5885 283.58215 L 58.598624 282.58215 L 58.59842 281.58215 L 58.58891 280.58215 L 58.577256 279.58215 L 58.546227 278.58215 L 58.535059 277.58215 L 58.504942 276.58215 L 58.445165 275.58215 L 58.407973 274.58215 L 58.368877 273.58215 L 58.326437 272.58215 L 58.293672 271.58215 L 58.226246 270.58215 L 58.18712 269.58215 L 58.144445 268.58215 L 58.073865 267.58215 L 58.037474 266.58215 L 57.979071 265.58215 L 57.868118 264.58215 L 57.79746 263.58215 L 57.68452 262.58215 L 57.638747 261.58215 L 57.577464 260.58215 L 57.528965 259.58215 L 57.448142 258.58215 L 57.329623 257.58215 L 57.259412 256.58215 L 57.17615 255.58215 L 57.143008 254.58215 L 57.091771 253.58215 L 57.023372 252.58215 L 56.957157 251.58215 L 56.88024 250.58215 L 56.852924 249.58215 L 56.826447 248.58215 L 56.803796 247.58215 L 56.784265 246.58215 L 56.757871 245.58215 L 56.7081 244.58215 L 56.673027 243.58215 L 56.637161 242.58215 L 56.621794 241.58215 L 56.606025 240.58215 L 56.602612 239.58215 L 56.600195 238.58215 L 56.600681 237.58215 L 56.60261 236.58215 L 56.615867 235.58215 L 56.624258 234.58215 L 56.645794 233.58215 L 56.668827 232.58215 L 56.68606 231.58215 L 56.704523 230.58215 L 56.724975 229.58215 L 56.741575 228.58215 L 56.804354 227.58215 L 56.879619 226.58215 L 56.912258 225.58215 L 56.979822 224.58215 L 57.033869 223.58215 L 57.067573 222.58215 L 57.157699 221.58215 L 57.186234 220.58215 L 57.21772 219.58215 L 57.248731 218.58215 L 57.303539 217.58215 L 57.368126 216.58215 L 57.406322 215.58215 L 57.502256 214.58215 L 57.551514 213.58215 L 57.595583 212.58215 L 57.635707 211.58215 L 57.744074 210.58215 L 57.785702 209.58215 L 57.847844 208.58215 L 57.917806 207.58215 L 58.02231 206.58215 L 58.059298 205.58215 L 58.105175 204.58215 L 58.17367 203.58215 L 58.222416 202.58215 L 58.300013 201.58215 L 58.330554 200.58215 L 58.400068 199.58215 L 58.424041 198.58215 L 58.452663 197.58215 L 58.494456 196.58215 L 58.516032 195.58215 L 58.52998 194.58215 L 58.556702 193.58215 L 58.566012 192.58215 L 58.578459 191.58215 L 58.589514 190.58215 L 58.595178 189.58215 L 58.599942 188.58215 L 58.594394 187.58215 L 58.581106 186.58215 L 58.573589 185.58215 L 58.548804 184.58215 L 58.525235 183.58215 L 58.489055 182.58215 L 58.463093 181.58215 L 58.440771 180.58215 L 58.372011 179.58215 L 58.297476 178.58215 L 58.203497 177.58215 L 58.152445 176.58215 L 58.098511 175.58215 L 58.06326 174.58215 L 57.957172 173.58215 L 57.904908 172.58215 L 57.868001 171.58215 L 57.83697 170.58215 L 57.775815 169.58215 L 57.708395 168.58215 L 57.659489 167.58215 L 57.594297 166.58215 L 57.556109 165.58215 L 57.514113 164.58215 L 57.472096 163.58215 L 57.41258 162.58215 L 57.29942 161.58215 L 57.247169 160.58215 L 57.207751 159.58215 L 57.16065 158.58215 L 57.10387 157.58215 L 57.071207 156.58215 L 57.035029 155.58215 L 57.002939 154.58215 L 56.968659 153.58215 L 56.910281 152.58215 L 56.865096 151.58215 L 56.835472 150.58215 L 56.785086 149.58215 L 56.759889 148.58215 L 56.738838 147.58215 L 56.70387 146.58215 L 56.67958 145.58215 L 56.665513 144.58215 L 56.646571 143.58215 L 56.63091 142.58215 L 56.618358 141.58215 L 56.612522 140.58215 L 56.60564 139.58215 L 56.600466 138.58215 L 56.602249 137.58215 L 56.604974 136.58215 L 56.616128 135.58215 L 56.644363 134.58215 L 56.688151 133.58215 L 56.70884 132.58215 L 56.749813 131.58215 L 56.789888 130.58215 L 56.808998 129.58215 L 56.831507 128.58215 L 56.898158 127.58215 L 56.947868 126.58215 L 57.021574 125.58215 L 57.052888 124.58215 L 57.12951 123.58215 L 57.167808 122.58215 L 57.241925 121.58215 L 57.345983 120.58215 L 57.415814 119.58215 L 57.521048 118.58215 L 57.576063 117.58215 L 57.699538 116.58215 L 57.770097 115.58215 L 57.885936 114.58215 L 57.936117 113.58215 L 57.971721 112.58215 L 58.063128 111.58215 L 58.116636 110.58215 L 58.204544 109.58215 L 58.273729 108.58215 L 58.320493 107.58215 L 58.392537 106.58215 L 58.442679 105.58215 L 58.460069 104.58215 L 58.487072 103.58215 L 58.506499 102.58215 L 58.525837 101.58215 L 58.564086 100.58215 L 58.580519 99.58215 L 58.588888 98.58215 L 58.593207 97.58215 L 58.599762 96.58215 L 58.597216 95.58215 L 58.591757 94.58215 L 58.575329 93.58215 L 58.543394 92.58215 L 58.505414 91.58215 L 58.47061 90.58215 L 58.407538 89.58215 L 58.386111 88.58215 L 58.335493 87.58215 L 58.310536 86.58215 L 58.254902 85.58215 L 58.223673 84.58215 L 58.173529 83.58215 L 58.141036 82.58215 L 58.060624 81.58215 L 57.991698 80.58215 L 57.876001 79.58215 L 57.800522 78.58215 L 57.684997 77.58215 L 57.605513 76.58215 L 57.497072 75.58215 L 57.457704 74.58215 L 57.354836 73.58215 L 57.255038 72.58215 L 57.209541 71.58215 L 57.175219 70.58215 L 57.123263 69.58215 L 57.083616 68.58215 L 57.048102 67.58215 L 56.980457 66.58215 L 56.941375 65.58215 L 56.890894 64.58215 L 56.841588 63.58215 L 56.790518 62.58215 L 56.746279 61.58215 L 56.724259 60.58215 L 56.708703 59.58215 L 56.666256 58.58215 L 56.651388 57.58215 L 56.62866 56.58215 L 56.608344 55.58215 L 56.602547 54.58215 L 56.600065 53.58215 L 56.603122 52.58215 L 56.614718 51.58215 L 56.631638 50.58215 L 56.663299 49.58215 L 56.677382 48.58215 L 56.730054 47.58215 L 56.779143 46.58215 L 56.833844 44.592945 " + style="fill: none; stroke: #000000; stroke-linecap: round" + id="path16" /> + <path + d="M 54.8 50.192945 L 55.275331 49.312576 L 55.755585 48.434669 L 56.290226 47.583956 L 56.766528 46.704072 L 57.279593 45.842571 L 57.878019 44.731954 L 57.73752 45.642219 L 58.133178 46.562423 L 58.517437 47.488328 L 58.918172 48.405994 L 59.312534 49.326847 L 59.79747 50.49421 " + style="fill: none; stroke: #ffffff; stroke-width: 4; stroke-linecap: round" + id="path17" /> + <path + d="M 54.8 50.192945 L 55.275331 49.312576 L 55.755585 48.434669 L 56.290226 47.583956 L 56.766528 46.704072 L 57.279593 45.842571 L 57.878019 44.731954 L 57.73752 45.642219 L 58.133178 46.562423 L 58.517437 47.488328 L 58.918172 48.405994 L 59.312534 49.326847 L 59.79747 50.49421 " + style="fill: none; stroke: #000000; stroke-linecap: round" + id="path18" /> + </g> + </g> + </g> + <defs + id="defs18"> + <clipPath + id="p53efc7421d"> + <rect + x="57.6" + y="41.472" + width="357.12" + height="266.112" + id="rect18" /> + </clipPath> + </defs> + <path + style="fill:#ffffff;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-opacity:0.18525;fill-opacity:1" + d="m 402.11605,300.06616 2.16807,0.15101 -0.0108,-1.35908 -2.54559,0.35595 z" + id="path19" /> + <path + style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-opacity:0.18525" + d="m 404.52142,306.22518 2.04941,0.0971 -0.1618,0.98156 -1.77975,-0.31281 z" + id="path20" /> + <path + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-opacity:0.18525" + d="M 63.984775,40.686206 63.812194,51.041125 69.766273,51.170562 69.075944,39.69386 Z" + id="path21" /> + <path + style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-opacity:0.18525" + d="m 56.105329,51.747633 0.04315,-1.876829 h 1.008527 l -0.02157,0.328984 -0.711901,1.661102 z" + id="path22" /> +</svg> 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 523/538] 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 ba0489020..2e0b79337 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 <python/python-docs-id>` * - `Italian (it) <https://docs.python.org/it/>`__ - - Alessandro Cucci (`email <mailto:alessandro.cucci@gmail.com>`__) + - Alessandro Cucci (:github-user:`acuccie3`, `email <mailto:alessandro.cucci@gmail.com>`__) - :github:`GitHub <python/python-docs-it>`, `original announcement <https://mail.python.org/pipermail/doc-sig/2019-April/004114.html>`__ * - `Japanese (ja) <https://docs.python.org/ja/>`__ @@ -99,11 +99,11 @@ For more details about translations and their progress, see `the dashboard - :github:`GitHub <python/python-docs-zh-cn>`, `Transifex <tx_>`_ * - `Spanish (es) <https://docs.python.org/es/>`__ - - Raúl Cumplido + - Raúl Cumplido (:github-user:`raulcd`) - :github:`GitHub <python/python-docs-es>` * - `Traditional Chinese (zh-tw) <https://docs.python.org/zh-tw/>`__ - | 王威翔 Matt Wang (:github-user:`mattwang44`), - | Josix Wang + | Josix Wang (:github-user:`josix`) - :github:`GitHub <python/python-docs-zh-tw>` * - `Turkish (tr) <https://docs.python.org/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 524/538] 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 2e0b79337..f300f1fed 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 <https://discord.gg/h3qDwgyzga>`_, `translation -mailing list <translation_ml_>`_, and the `translations category <_discourse>`_ +mailing list <translation_ml_>`_, and the `translations category <discourse_>`_ 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 525/538] 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 f300f1fed..0a28edad4 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 <https://python-docs-transifex-automation.readthedocs.io/>`_. -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 <https://github.com/orgs/python/projects/58>`_ GitHub project: + This project contains issues and pull requests that aim to improve + the Python documenation for translations. +- `Python Pootle archive <https://github.com/python/pootle-python-org-backup>`_: + 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 526/538] 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 348ceb95a..769bba2b0 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 5031227a1..b564c933e 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 527/538] 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 000000000..364cf20be --- /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 <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" <o_ampersand>` + 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 + ``<parameter_name>_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 * <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 <heap-types>` 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 * <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 ``"<a>_<b>"``, + where ``"<a>"`` is the semantic object represented (the parsing function, + the impl function, the docstring, or the methoddef structure) and ``"<b>"`` + 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 <destination> + +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 <field> <destination> + +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 <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 <name> <command> [...] + +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 <name> new <type> + +This creates a new destination with name ``<name>`` and type ``<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 <name> new <type> <file_template> + + 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 <name> 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 <limited-c-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 <clinic-howto-critical-sections>` 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 <argument>` for positional-or-keyword +:term:`parameters <parameter>` 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 6446d1a46..69fb99e91 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 <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" <o_ampersand>` - 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 - ``<parameter_name>_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 * <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 <heap-types>` 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 * <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 ``"<a>_<b>"``, - where ``"<a>"`` is the semantic object represented (the parsing function, - the impl function, the docstring, or the methoddef structure) and ``"<b>"`` - 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 <destination> - -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 <field> <destination> - -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 <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 <name> <command> [...] - -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 <name> new <type> - -This creates a new destination with name ``<name>`` and type ``<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 <name> new <type> <file_template> - - 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 <name> 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 <limited-c-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 <clinic-howto-critical-sections>` 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 <argument>` for positional-or-keyword -:term:`parameters <parameter>` 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 528/538] 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 69fb99e91..a6ddd5c72 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 <clinic-howtos>` -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 <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 000000000..6acfaee4b --- /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 <clinic-howtos>` +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 <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 <po@danielnylander.se> Date: Sun, 31 Aug 2025 22:26:18 +0200 Subject: [PATCH 529/538] 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 0a28edad4..ebd0dc631 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) <https://docs.python.org/es/>`__ - Raúl Cumplido (:github-user:`raulcd`) - :github:`GitHub <python/python-docs-es>` + * - Swedish (sv) + - Daniel Nylander (:github-user:`yeager`) + - :github:`GitHub <python/python-docs-sv>` * - `Traditional Chinese (zh-tw) <https://docs.python.org/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 530/538] 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 0b287df92..1c64b4832 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 <pullrequest-qu you will learn the workflow for documentation pull requests. .. _documentation issues: https://github.com/python/cpython/issues?q=is%3Aissue+is%3Aopen+label%3Adocs -.. _octocat: https://github.com/logos + + +Translating +=========== + +The Python documentation is being actively translated into several languages. +If you are interested in helping with translation, see our pages on +:ref:`translating <translating>` 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 531/538] Note how to translate `python-docs-theme` (GH-1650) Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com> Co-authored-by: Rafael Fontenelle <rffontenelle@users.noreply.github.com> 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 aaed4b831..31ab4359e 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 <https://www.sphinx-doc.org/en/master/internals/contributing.html#translations>`__ (`sphinx-doc on Transifex <https://app.transifex.com/sphinx-doc/>`__) or in -the `python-docs-theme <https://github.com/python/python-docs-theme>`_ -(currently this is not possible; see this -`issue <https://github.com/python/python-docs-theme/issues/194>`__). +the :ref:`Python Docs Sphinx Theme <python-docs-theme-i18n>`. 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 ebd0dc631..af86ca803 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 <tx_>`_, 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 <https://help.transifex.com/en/collections/3441044-starting-with-the-basics>`__: A group of documents with basic information. +Within the organization, a project for translating the +:github:`Python Docs Sphinx Theme <python/python-docs-theme>` can also be +found. For further information about Transifex see our `documentation <https://python-docs-transifex-automation.readthedocs.io/>`_. @@ -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 <https://explore.transifex.com/python-doc/python-docs-theme/>`_ +(see :ref:`translating on Transifex <transifex-use>` for more information) +or locally by following the steps outlined below. + +To translate locally, clone the :github:`Python Docs Sphinx Theme repository <python/python-docs-theme>` 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 <python/python-docs-theme>`. +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 532/538] 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 31ab4359e..13cf617b8 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 <https://discord.gg/h3qDwgyzga>`_, `translation -mailing list <translation_ml_>`_, and the +`#translations channel <https://discord.gg/h3qDwgyzga>`_ and the `translations category <trans_disc_>`_ 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 <translation_ml_>`_. +- Coordinator requests are to be public in the `translations category of the + Python Discourse <trans_disc_>`_. - 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 <translation_ml_>`_. + period of time, someone else can ask to be added as a primary coordinator in + the `translations category of the Python Discourse <trans_disc_>`_. 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 af86ca803..7ed46b1bd 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 <https://discord.gg/h3qDwgyzga>`_, `translation -mailing list <translation_ml_>`_, and the `translations category <discourse_>`_ -of the Python Discourse. +`#translations channel <https://discord.gg/h3qDwgyzga>`_ and the +`translations category <discourse_>`_ 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 533/538] 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 f6a6f6a94..39125c35e 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 534/538] 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 74ce892f7..2fb37cb3f 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 <hz@mit.edu> Date: Wed, 17 Sep 2025 10:33:14 -0400 Subject: [PATCH 535/538] Update documentation for Emscripten Builds (#1621) Co-authored-by: Russell Keith-Magee <russell@keith-magee.com> 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 39125c35e..2cf30d1e7 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 <seth@python.org> Date: Tue, 30 Sep 2025 12:38:44 +0000 Subject: [PATCH 536/538] Add runbook for code signing certificate reports to PSRT (#1651) Co-authored-by: Steve Dower <steve.dower@microsoft.com> Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com> 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 9d9019dbf..cf5acd2b7 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 + <https://discuss.python.org/t/103356/2>`__ 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 <savannahostrowski@gmail.com> Date: Wed, 1 Oct 2025 17:47:23 -0700 Subject: [PATCH 537/538] 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 ab87c50fa..8c4625493 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 538/538] 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 214871b64..abdcd1869 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"