Skip to content

Commit 1525795

Browse files
committed
Start from the beginning
1 parent 4c2b982 commit 1525795

File tree

2 files changed

+115
-24
lines changed

2 files changed

+115
-24
lines changed

Doc/extending/first-extension-module.rst

Lines changed: 115 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
Your first C API extension module
88
*********************************
99

10-
This tutorial will take you, line by line, through creating a simple
10+
This tutorial will take you through creating a simple
1111
Python extension module written in C or C++.
1212

1313
The tutorial assumes basic knowledge about Python: you should be able to
@@ -19,15 +19,30 @@ While we will mention several concepts that a C beginner would not be expected
1919
to know, like ``static`` functions or linkage declarations, understanding these
2020
is not necessary for success.
2121

22-
As a word warning before we begin: after the code is written, you will need to
22+
As a word warning before we begin: as the code is written, you will need to
2323
compile it with the right tools and settings for your system.
2424
It is generally best to use a third-party tool to handle the details.
2525
This is covered in later chapters, not in this tutorial.
2626

2727
The tutorial assumes that you use a Unix-like system (including macOS and
2828
Linux) or Windows.
29+
If you don't have a preference, currently you're most likely to get the best
30+
experience on Linux.
2931

30-
.. include:: ../includes/tutorial-new-api.rst
32+
If you learn better by having the full context at the beginning,
33+
skip to the end to see :ref:`the resulting source <first-extension-result>`,
34+
then return here.
35+
The tutorial will explain every line, although in a different order.
36+
37+
.. note::
38+
39+
This tutorial uses API that was added in CPython 3.15.
40+
To create an extension that's compatible with earlier versions of CPython,
41+
please follow an earlier version of this documentation.
42+
43+
This tutorial uses some syntax added in C11 and C++20.
44+
If your extension needs to be compatible with earlier standards,
45+
please follow tutorials in documentation for Python 3.14 or below.
3146

3247

3348
What we'll do
@@ -65,25 +80,108 @@ We want this function to be callable from Python as follows:
6580
both Unix and Windows.
6681

6782

68-
.. _extending-spammodule:
83+
Warming up your build tool: an empty module
84+
===========================================
6985

70-
The ``spam`` module
71-
===================
86+
Begin by creating a file named :file:`spammodule.c`.
87+
The name is entirely up to you, though some tools can be picky about
88+
the ``.c`` extension.
89+
(Some people would just use :file:`spam.c` to implement a module
90+
named ``spam``, for example.
91+
If you do this, you'll need to adjust some instructions below.)
92+
93+
Now, while the file is emptly, we'll compile it, so that you can make
94+
and test incremental changes as you follow the rest of the tutorial.
7295

96+
Choose a build tool such as Setuptools or Meson, and follow its instructions
97+
to compile and install the empty :file:`spammodule.c` as if it was a
98+
C extension module.
7399

74-
Begin by creating a file :file:`spammodule.c`.
100+
.. note:: Workaround for missing ``PyInit``
101+
102+
If your build tool output complains about missing ``PyInit_spam``,
103+
add the following function to your module for now:
104+
105+
.. code-block:: c
106+
107+
// A workaround
108+
void *PyInit_spam(void) { return NULL; }
109+
110+
This is a shim for an old-style :ref:`initialization function <extension-export-hook>`,
111+
which was required in extension modules for CPython 3.14 and below.
112+
Current CPython will not call it, but some build tools may still assume that
113+
all extension modules need to define it.
114+
115+
If you use this workaround, you will get the exception
116+
``SystemError: initialization of spam failed without raising an exception``
117+
instead of an :py:exc:`ImportError` in the next step.
75118

76119
.. note::
77120

78-
Historically, if a module is called ``spam``, the C file containing its
79-
implementation is called :file:`spammodule.c`.
80-
But the naming is entirely up to you.
81-
If you use a different name, remember to adjust the commands later,
82-
when you build the extension.
121+
Using a third-party build tool is heavily recommended, as in will take
122+
care of various details of your platform and Python installation,
123+
naming the resulting extension, and, later, distributing your work.
124+
125+
If you don't want to use a tool, you can try to run your compiler directly.
126+
The following command should work for many flavors of Linux, and generate
127+
a ``spam.so`` file that you need to put in a directory
128+
in :py:attr:`sys.path`:
129+
130+
.. code-block:: shell
131+
132+
gcc --shared spammodule.c -o spam.so
133+
134+
When your extension is compiled and installed, start Python and try to import
135+
your extension.
136+
This should fail with the following exception:
137+
138+
.. code-block:: pycon
139+
140+
>>> import spam
141+
Traceback (most recent call last):
142+
File "<string>", line 1, in <module>
143+
import spam
144+
ImportError: dynamic module does not define module export function (PyModExport_spam or PyInit_spam)
145+
146+
147+
Including the Header
148+
====================
149+
150+
151+
Now, put the first line in the file: include :file:`Python.h` to pull in
152+
all definitions of the Python C API:
153+
154+
.. literalinclude:: ../includes/capi-extension/spammodule-01.c
155+
:start-at: <Python.h>
156+
:end-at: <Python.h>
157+
158+
This header contains all of the Python C API.
159+
160+
Next, bring in the declaration of the C library function we want to call.
161+
Documentation of the :c:func:`system` function tells us that we need
162+
``stdlib.h``:
163+
164+
.. literalinclude:: ../includes/capi-extension/spammodule-01.c
165+
:start-at: <stdlib.h>
166+
:end-at: <stdlib.h>
167+
168+
Be sure to put this, and any other standard library includes, *after*
169+
:file:`Python.h`, since Python may define some pre-processor definitions
170+
which affect the standard headers on some systems.
171+
172+
.. tip::
173+
174+
The ``<stdlib.h>`` include is technically not necessary.
175+
:file:`Python.h` :ref:`includes several standard header files <capi-system-includes>`
176+
for its own use and for backwards compatibility,
177+
and ``stdlib`` is one of them.
178+
However, it is good practice to explicitly include what you need.
179+
180+
181+
182+
The ``spam`` module
183+
===================
83184

84-
You can add code to this file as you go through the tutorial.
85-
Alternatively, if you'd like to copy the final result to the file now,
86-
get it :ref:`below <extending-spammodule-source>` and come back here.
87185

88186
The first line of this file (after any comment describing the purpose of
89187
the module, copyright notices, and the like) will pull in the Python API:
@@ -420,6 +518,8 @@ Thus, if this extension does end up loaded on Python 3.14, the user will
420518
get a proper error message.
421519

422520

521+
.. _first-extension-result:
522+
423523
End of file
424524
===========
425525

Doc/includes/tutorial-new-api.rst

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)