-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
gh-134160: Start "Extending and embedding" with a Diataxis-style tutorial #142314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| first-extension-module.rst | ||
| extending.rst | ||
| newtypes_tutorial.rst | ||
| newtypes.rst | ||
| building.rst | ||
| windows.rst | ||
| embedding.rst |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| first-extension-module.rst | |
| extending.rst | |
| newtypes_tutorial.rst | |
| newtypes.rst | |
| building.rst | |
| windows.rst | |
| embedding.rst | |
| first-extension-module | |
| extending | |
| newtypes_tutorial | |
| newtypes | |
| building | |
| windows | |
| embedding |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change this? All of CPython's toctrees have the .rst suffixes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s not required, so is a little cleaner (like we don’t have to do import './module.py'), but maybe Sphinx didn’t support that when it was first created and now that’s the style we have.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh. Makes sense!
But I think the first such change should be its own PR, so it's easily revertable if anything goes wrong. This PR is big enough on its own.
Co-authored-by: Stan Ulbrych <[email protected]> Co-authored-by: Éric <[email protected]>
|
I've changed things so the first compilation is after adding |
|
The “now run your build tool” section stood out as the most no-tutorial-i part of the tutorial, so I tried the tools from the PyPA recommendation list and chose the most straightforward one: I put notes on using other tools in an appendix. |
|
As a big proponent of meson-python IMO it's a great choice for this. |
| .. tip:: | ||
|
|
||
| If you don't have ``pip`` installed, run ``python -m ensurepip``, | ||
| preferably in a :mod:`virtual environment <venv>`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do people actually need to run ensurepip if they have run python -m venv .venv ?
This tutorial could show the venv commands directly (and avoid ensurepip step) instead of referring to them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added “You need to be able to install Python packages” to the intro, leaving exact steps for setting that up out of scope here.
Does that work?
| preferably in a :mod:`virtual environment <venv>`. | ||
| You can also use another tool that can build and install | ||
| ``pyproject.toml``-based projects, like | ||
| `uv <https://docs.astral.sh/uv/>`_ (``uv pip install .``). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This note seems to contradict the intent of not providing options in a tutorial 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is partly setup you're expected to have before starting, and part troubleshooting advice.
I added it to the introduction, and made this note smaller. Does that work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will check!
ZeroIntensity
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay, thanks for doing this! I'm excited to finally see a better tutorial.
I tried to avoid being overly nitpicky in my review.
Co-authored-by: Daniele Nicolodi <[email protected]> Co-authored-by: Peter Bierma <[email protected]>
ZeroIntensity
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly just typos left. I left a few minor wording suggestions, so feel free to reject those if you want to.
|
|
||
| We will focus on giving you a "feel" of what Python's C API is like. | ||
| It will not teach you important concepts, like error handling | ||
| and reference counting, which are covered in later chapters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't currently incorrect, but I feel that this reads better:
| and reference counting, which are covered in later chapters. | |
| and reference counting, as those are covered in later chapters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for which (simpler, direct)
| On other systems, you might need to adjust some details -- for example, | ||
| a system command name. | ||
|
|
||
| You need to have suitable C compiler and Python development headers installed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| You need to have suitable C compiler and Python development headers installed. | |
| You need to have a suitable C compiler and Python development headers installed. |
| ====================== | ||
|
|
||
| Begin by creating a directory for this tutorial, and switching to it | ||
| on command line. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| on command line. | |
| on the command line. |
Or:
| on command line. | |
| on your command line. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for the
| See `meson-python documentation <meson-python>`_ for details on | ||
| configuration. | ||
|
|
||
| Now, build install the *project in the current directory* (``.``) via ``pip``: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this italicized?
| extension. | ||
| Unlike Python, C has an explicit compilation step. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two sentences feel very related.
| extension. | |
| Unlike Python, C has an explicit compilation step. | |
| extension, because unlike Python, C has an explicit compilation step. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Juxtaposition is a valid construct! 🙂
| >>> print(spam) | ||
| <module 'spam' from '/home/encukou/dev/cpython/spam.so'> | ||
| You have a extension module! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| You have a extension module! | |
| You have an extension module! |
| One of the simplest ways to write glue code is a ":c:data:`METH_O`" function, | ||
| which takes two Python objects and returns one. | ||
| All Python objects -- regardless of the Python type -- are represented in C | ||
| as pointers to the ``PyObject`` structure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to have a link here, since this is the first time we introduce it.
| as pointers to the ``PyObject`` structure. | |
| as pointers to the :c:type:`PyObject` structure. |
| As with module slots, a zero-filled sentinel marks the end of the array. | ||
|
|
||
| Next, we'll add the method to the module. | ||
| Add a :c:data:`Py_mod_methods` slot to your a :c:type:`PyMethodDef` array: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Add a :c:data:`Py_mod_methods` slot to your a :c:type:`PyMethodDef` array: | |
| Add a :c:data:`Py_mod_methods` slot to your :c:type:`PyMethodDef` array: |
| but let's start with a fixed value, say, ``3``. | ||
|
|
||
| The Python C API provides a function to create a Python :py:type:`int` object | ||
| from a C ``int`` values: :c:func:`PyLong_FromLong`. [#why-pylongfromlong]_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| from a C ``int`` values: :c:func:`PyLong_FromLong`. [#why-pylongfromlong]_ | |
| from a C ``int`` value: :c:func:`PyLong_FromLong`. [#why-pylongfromlong]_ |
| } | ||
| That's it for the setup. | ||
| Now, all that is left is calling C library function :c:func:`system` with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Now, all that is left is calling C library function :c:func:`system` with | |
| Now, all that is left is calling the C library function :c:func:`system` with |
The "Extending and embedding" section of the docs starts with a "tutorial", which is now outdated (it uses soft-deprecated API), but it also doesn't quite work as a tutorial (in the Diátaxis sense).
This PR pulls out the bits needed for a simple extension module: it's as simple as it can get to expose a C function. Topics that need lengthy explanation are left out (this includes crucial ones like refcounting & error handling, put also modern things like ABI info or free-threading support).
The code is updated to modern, non-deprecated API -- specifically, PEP 793's PyModExport.
The remainder of the existing chapter is renamed to "Using the C API: Assorted topics", to mirror the later chapter “Defining Extension Types: Assorted Topics”. This title was somewhat fitting even without the tutorial part taken out.
Care is taken to not remove any information, unless it's duplicated or no longer relevant. An “assorted topics” section works nicely here.
It would be nice to pull more bits out into dedicated explanation or tutorial pages; that's out of scope for this PR.
I apologize for any typos; I found reviewers are much better at finding them than I am (especially after I've been rewriting drafts for days).
📚 Documentation preview 📚: https://cpython-previews--142314.org.readthedocs.build/