{"id":169,"date":"2026-10-26T21:21:54","date_gmt":"2026-10-26T20:21:54","guid":{"rendered":"https:\/\/wecarus.fr\/index.php\/framework-permettant-de-creer-votre-propre-extension-c-pour-python\/"},"modified":"2026-10-26T21:21:54","modified_gmt":"2026-10-26T20:21:54","slug":"framework-permettant-de-creer-votre-propre-extension-c-pour-python","status":"publish","type":"page","link":"https:\/\/wecarus.fr\/index.php\/fr\/framework-permettant-de-creer-votre-propre-extension-c-pour-python\/","title":{"rendered":"Framework permettant de cr\u00e9er votre propre extension C pour Python"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Commen\u00e7ons par le code source. <br>Il existe deux m\u00e9thodes : la m\u00e9thode en une seule phase et la m\u00e9thode en plusieurs phases.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La m\u00e9thode en une seule phase n&#x27;est plus recommand\u00e9e (est-elle obsol\u00e8te ? Je n&#x27;en suis pas encore s\u00fbr) ==&gt; Pourquoi ne pas cr\u00e9er un programme permettant de migrer le code source de la m\u00e9thode en une seule phase vers la m\u00e9thode en plusieurs phases ? C&#x27;est peut-\u00eatre possible ? Mais c&#x27;est un autre sujet.<br><br><br> Concentrons-nous sur le code source : voici un mod\u00e8le g\u00e9n\u00e9rique. Commen\u00e7ons par nous exercer sur le code pour comprendre comment proc\u00e9der.<br><br> Et au c\u0153ur de Python :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Include\/pyport.h<\/code> contient le commentaire : \u00ab D\u00e9sormais, PY_SSIZE_T_CLEAN est obligatoire. Ceci est uniquement pour des raisons de compatibilit\u00e9 ascendante. \u00bb<\/li>\n\n\n\n<li>et il d\u00e9finit \u00e9galement : <code>typedef Py_ssize_t Py_ssize_clean_t;<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">La r\u00e8gle pratique est donc la suivante :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>avant Python 3.13 : le d\u00e9finir avant <code>#include &lt;Python.h&gt;<\/code> pour utiliser les API avec <code>#<\/code><\/li>\n\n\n\n<li>\u00e0 partir de Python 3.13 : ce n\u2019est plus strictement n\u00e9cessaire, mais on le conserve pour des raisons de compatibilit\u00e9<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En bref, <code>PY_SSIZE_T_CLEAN<\/code> cela sert \u00e0 garantir le bon type <code>Py_ssize_t<\/code> dans les liaisons C\/extensions, et le d\u00e9p\u00f4t le met surtout en avant dans la documentation et les exemples, pas dans le corps de l\u2019en-t\u00eate principal.<br><br><code>#ifdef PY_SSIZE_T_CLEAN<\/code> est une condition de compilation utilis\u00e9e par l\u2019API C de CPython pour basculer certaines fonctions vers les <code>Py_ssize_t<\/code>variantes bas\u00e9es sur .<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En pratique, le mod\u00e8le courant est le suivant :<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">C<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define PY_SSIZE_T_CLEAN\n#include &lt;Python.h&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ainsi, les API qui prennent en param\u00e8tre une longueur\/un nombre ou une taille de tampon utilisent <code>Py_ssize_t<\/code> au lieu de <code>int<\/code> pour certaines unit\u00e9s de format telles que :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>s#<\/code><\/li>\n\n\n\n<li><code>y#<\/code><\/li>\n\n\n\n<li><code>z#<\/code><\/li>\n\n\n\n<li>et d\u2019autres <code>#<\/code>formats d\u2019analyse d\u2019arguments bas\u00e9s sur<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Exemple :<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">C<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>char *buf;\nPy_ssize_t len;\n\nPyArg_ParseTuple(args, \"s#\", &amp;buf, &amp;len);\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sans <code>PY_SSIZE_T_CLEAN<\/code>, certaines anciennes versions de Python pouvaient consid\u00e9rer la longueur comme <code>int<\/code> au lieu de <code>Py_ssize_t<\/code>, ce qui n\u2019est pas id\u00e9al pour les grandes tailles et constitue une source de probl\u00e8mes d\u2019incompatibilit\u00e9 ABI\/API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Remarques importantes concernant CPython :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sous Python 3.12 et versions ant\u00e9rieures, cette macro est n\u00e9cessaire pour utiliser les <code>#<\/code> variantes en toute s\u00e9curit\u00e9.<\/li>\n\n\n\n<li>Sous Python 3.13 et versions ult\u00e9rieures, elle n\u2019est plus n\u00e9cessaire dans la plupart des cas.<\/li>\n\n\n\n<li>Dans le code CPython plus r\u00e9cent, elle est consid\u00e9r\u00e9e comme une macro de compatibilit\u00e9 : le moteur la prend toujours en charge, mais le code moderne utilise principalement les <code>Py_ssize_t<\/code>sans avoir besoin d\u2019elle.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Vous pouvez \u00e9galement le constater dans la documentation de CPython :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Doc\/c-api\/arg.rst<\/code> il est indiqu\u00e9 qu\u2019elle doit \u00eatre d\u00e9finie sous Python 3.12 et versions ant\u00e9rieures pour toutes les <code>#<\/code> variantes de format.<\/li>\n\n\n\n<li><code>Include\/pyport.h<\/code> indique que cela n\u2019est d\u00e9sormais conserv\u00e9 que pour des raisons de compatibilit\u00e9 ascendante.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En r\u00e9sum\u00e9 :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>PY_SSIZE_T_CLEAN<\/code> = \u00ab utiliser <code>Py_ssize_t<\/code> pour les arguments de type taille\/nombre de l\u2019API C \u00bb<\/li>\n\n\n\n<li>Cela concerne principalement l\u2019analyse des arguments et les API de tampon<\/li>\n\n\n\n<li>Il ne s\u2019agit pas d\u2019un indicateur d\u2019ex\u00e9cution, mais simplement d\u2019une macro qui modifie le contrat de l\u2019API C lors de la compilation<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Si vous le souhaitez, je peux \u00e9galement vous indiquer pr\u00e9cis\u00e9ment quelles fonctions de l\u2019API C de CPython sont concern\u00e9es et comment les utiliser <code>Py_ssize_t<\/code> correctement dans un module d\u2019extension.<br><br><br><code>Py_ssize_t<\/code> <strong>n\u2019est pas d\u00e9fini en fonction de <code>PY_SSIZE_T_CLEAN<\/code><\/strong>. Il est d\u00e9fini dans <code>Include\/pyport.h<\/code>. La macro <code>PY_SSIZE_T_CLEAN<\/code> modifie plut\u00f4t <strong>la fonction d\u2019analyse syntaxique<\/strong> utilis\u00e9e, et donc le type attendu pour les longueurs des formats <code>#<\/code> comme <code>s#<\/code> ou <code>y#<\/code>.<a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/huggingface.co\/datasets\/yyyzzzzyyy\/envss\/raw\/6efd85e5975d3068e42f1913d8524a97a2106e38\/LlamaGen\/include\/python3.10\/modsupport.h\">huggingface<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">D\u00e9finition de Py_ssize_t<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dans <code>Include\/pyport.h<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">c<code>typedef ssize_t Py_ssize_t;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">lorsque la plateforme fournit <code>ssize_t<\/code>. Sinon, CPython choisit un type entier sign\u00e9 de m\u00eame taille que <code>size_t<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">c<code>sizeof(Py_ssize_t) == sizeof(size_t)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Donc :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">text<code>Py_ssize_t : toujours d\u00e9fini dans Include\/pyport.h\nPY_SSIZE_T_CLEAN : contr\u00f4le le comportement des formats \"#\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">O\u00f9 intervient PY_SSIZE_T_CLEAN<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La macro est utilis\u00e9e dans <code>Include\/modsupport.h<\/code>. Elle redirige les fonctions d\u2019analyse vers leurs variantes <code>_SizeT<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">c<code>#ifdef PY_SSIZE_T_CLEAN\n#define PyArg_Parse                 _PyArg_Parse_SizeT\n#define PyArg_ParseTuple            _PyArg_ParseTuple_SizeT\n#define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT\n#define Py_VaBuildValue             _Py_VaBuildValue_SizeT\n#endif<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ainsi, avec :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">c<code>#define PY_SSIZE_T_CLEAN\n#include &lt;Python.h&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ce code :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">c<code>PyArg_ParseTuple(args, \"y#\", &amp;data, &amp;length);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">appelle en r\u00e9alit\u00e9 :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">c<code>_PyArg_ParseTuple_SizeT(args, \"y#\", &amp;data, &amp;length);<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Effet sur les formats #<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Macro d\u00e9finie ?<\/th><th>Fonction appel\u00e9e<\/th><th>Type attendu pour <code>s#<\/code>, <code>y#<\/code>, etc.<\/th><\/tr><\/thead><tbody><tr><td>Non<\/td><td><code>PyArg_ParseTuple<\/code><\/td><td><code>int<\/code><\/td><\/tr><tr><td>Oui<\/td><td><code>_PyArg_ParseTuple_SizeT<\/code><\/td><td><code>Py_ssize_t<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">huggingface+1<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Exemple :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">c<code>#define PY_SSIZE_T_CLEAN\n#include &lt;Python.h&gt;\n\nconst char *data;\nPy_ssize_t length;\n\nPyArg_ParseTuple(args, \"y#\", &amp;data, &amp;length);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ici, <code>length<\/code> il doit s&#x27;agir d&#x27;un <code>Py_ssize_t<\/code>.cmi.ac+1<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">O\u00f9 est impl\u00e9ment\u00e9 le comportement<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">L\u2019impl\u00e9mentation se trouve dans :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">text<code>Python\/getargs.c<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">notamment dans les fonctions de conversion telles que <code>convertsimple()<\/code>. C\u2019est l\u00e0 que CPython v\u00e9rifie, pour les anciennes versions, que la macro a bien \u00e9t\u00e9 d\u00e9finie avant d\u2019accepter un format <code>#<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">c<code>#define REQUIRE_PY_SSIZE_T_CLEAN \nif (!(flags &amp; FLAG_SIZE_T)) { \n    PyErr_SetString(PyExc_SystemError, \n        \"PY_SSIZE_T_CLEAN macro must be defined for '#' formats\"); \n    return NULL; \n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">R\u00e9sum\u00e9 des fichiers<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Fichier CPython<\/th><th>R\u00f4le<\/th><\/tr><\/thead><tbody><tr><td><code>Include\/pyport.h<\/code><\/td><td>D\u00e9finit <code>Py_ssize_t<\/code>, <code>PY_SSIZE_T_MAX<\/code>, <code>PY_SSIZE_T_MIN<\/code><\/td><\/tr><tr><td><code>Include\/Python.h<\/code><\/td><td>Inclut <code>pyport.h<\/code>, <code>modsupport.h<\/code>, etc.<\/td><\/tr><tr><td><code>Include\/modsupport.h<\/code><\/td><td>Utilise <code>PY_SSIZE_T_CLEAN<\/code> pour rediriger vers les variantes <code>_SizeT<\/code><\/td><\/tr><tr><td><code>Python\/getargs.c<\/code><\/td><td>Impl\u00e9mente l&#x27;analyse et le traitement des formats <code>#<\/code><\/td><\/tr><tr><td><code>Python\/modsupport.c<\/code><\/td><td>Impl\u00e9mente notamment <code>Py_BuildValue()<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">huggingface+1<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Depuis Python 3.13<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Depuis Python 3.13, <code>PY_SSIZE_T_CLEAN<\/code> n\u2019est plus n\u00e9cessaire pour les formats <code>#<\/code> : <code>Py_ssize_t<\/code> est d\u00e9sormais le comportement par d\u00e9faut. La macro reste recommand\u00e9e dans le code source pour des raisons de compatibilit\u00e9 avec les versions ant\u00e9rieures.<a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/python\/cpython\/pull\/106314\/files\">github<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">En un mot<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Py_ssize_t<\/code> est d\u00e9fini dans <code>Include\/pyport.h<\/code> ind\u00e9pendamment de <code>PY_SSIZE_T_CLEAN<\/code> ; cette macro, trait\u00e9e dans <code>Include\/modsupport.h<\/code> et <code>Python\/getargs.c<\/code>, s\u00e9lectionne les variantes <code>_SizeT<\/code> de <code>PyArg_Parse*()<\/code> afin que les formats <code>#<\/code> attendent un <code>Py_ssize_t<\/code> plut\u00f4t qu\u2019un <code>int<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-highlight-hover\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.75rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .75rem);--cbp-line-highlight-color:rgba(212, 226, 245, 0.2);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#24292e\"><span style=\"background:#d3d7dd;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#24292e\">Code C<\/span><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>#define PY_SSIZE_T_CLEAN<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color: #24292e\" tabindex=\"0\"><code><span class=\"line cbp-line-highlight\"><span style=\"color: #F97583\">#define<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">PY_SSIZE_T_CLEAN<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>#define PY_SSIZE_T_CLEAN\n#include &lt;Python.h&gt;\n#include &lt;string.h&gt;\n\n\/* ------------------------------------------------------------------ *\/\n\/* 1. \u00c9tat du module                                                   *\/\n\/* ------------------------------------------------------------------ *\/\n\ntypedef struct {\n    long counter;\n    char* message;\n} module_state;\n\n\/* ------------------------------------------------------------------ *\/\n\/* 2. Fonctions expos\u00e9es \u00e0 Python                                      *\/\n\/* ------------------------------------------------------------------ *\/\n\nstatic PyObject*\nadd(PyObject* self, PyObject* args)\n{\n    long a, b;\n\n    if (!PyArg_ParseTuple(args, &quot;ll&quot;, &amp;a, &amp;b)) {\n        return NULL;\n    }\n\n    return PyLong_FromLong(a + b);\n}\n\nstatic PyObject*\nincrement_counter(PyObject* self, PyObject* args)\n{\n    module_state* state;\n\n    if (!PyArg_ParseTuple(args, &quot;&quot;)) {\n        return NULL;\n    }\n\n    state = (module_state*)PyModule_GetState(self);\n\n    if (state == NULL) {\n        return NULL;\n    }\n\n    state-&gt;counter++;\n\n    return PyLong_FromLong(state-&gt;counter);\n}\n\nstatic PyObject*\nget_counter(PyObject* self, PyObject* args)\n{\n    module_state* state;\n\n    if (!PyArg_ParseTuple(args, &quot;&quot;)) {\n        return NULL;\n    }\n\n    state = (module_state*)PyModule_GetState(self);\n\n    if (state == NULL) {\n        return NULL;\n    }\n\n    return PyLong_FromLong(state-&gt;counter);\n}\n\nstatic PyObject*\nset_message(PyObject* self, PyObject* args)\n{\n    const char* text;\n    module_state* state;\n    char* copy;\n\n    if (!PyArg_ParseTuple(args, &quot;s&quot;, &amp;text)) {\n        return NULL;\n    }\n\n    state = (module_state*)PyModule_GetState(self);\n\n    if (state == NULL) {\n        return NULL;\n    }\n\n    copy = PyMem_Malloc(strlen(text) + 1);\n\n    if (copy == NULL) {\n        PyErr_NoMemory();\n        return NULL;\n    }\n\n    strcpy(copy, text);\n\n    PyMem_Free(state-&gt;message);\n    state-&gt;message = copy;\n\n    Py_RETURN_NONE;\n}\n\nstatic PyObject*\nget_message(PyObject* self, PyObject* args)\n{\n    module_state* state;\n\n    if (!PyArg_ParseTuple(args, &quot;&quot;)) {\n        return NULL;\n    }\n\n    state = (module_state*)PyModule_GetState(self);\n\n    if (state == NULL) {\n        return NULL;\n    }\n\n    if (state-&gt;message == NULL) {\n        Py_RETURN_NONE;\n    }\n\n    return PyUnicode_FromString(state-&gt;message);\n}\n\nstatic PyObject*\ndivide(PyObject* self, PyObject* args)\n{\n    long a, b;\n\n    if (!PyArg_ParseTuple(args, &quot;ll&quot;, &amp;a, &amp;b)) {\n        return NULL;\n    }\n\n    if (b == 0) {\n        PyErr_SetString(PyExc_ZeroDivisionError, &quot;division by zero&quot;);\n        return NULL;\n    }\n\n    return PyFloat_FromDouble((double)a \/ (double)b);\n}\n\n\/* ------------------------------------------------------------------ *\/\n\/* 3. Table des m\u00e9thodes                                               *\/\n\/* ------------------------------------------------------------------ *\/\n\nstatic PyMethodDef mymodule_methods[] = {\n    {&quot;add&quot;, add, METH_VARARGS,\n     &quot;add(a, b) -&gt; intnnReturn the sum of two integers.&quot;},\n\n    {&quot;divide&quot;, divide, METH_VARARGS,\n     &quot;divide(a, b) -&gt; floatnnReturn a divided by b.&quot;},\n\n    {&quot;increment_counter&quot;, increment_counter, METH_VARARGS,\n     &quot;increment_counter() -&gt; intnnIncrement and return the module counter.&quot;},\n\n    {&quot;get_counter&quot;, get_counter, METH_VARARGS,\n     &quot;get_counter() -&gt; intnnReturn the current module counter.&quot;},\n\n    {&quot;set_message&quot;, set_message, METH_VARARGS,\n     &quot;set_message(text) -&gt; NonennStore a message in the module state.&quot;},\n\n    {&quot;get_message&quot;, get_message, METH_VARARGS,\n     &quot;get_message() -&gt; str or NonennReturn the stored message.&quot;},\n\n    {NULL, NULL, 0, NULL}\n};\n\n\/* ------------------------------------------------------------------ *\/\n\/* 4. Slot Py_mod_exec : initialisation du module                      *\/\n\/* ------------------------------------------------------------------ *\/\n\nstatic int\nmymodule_exec(PyObject* module)\n{\n    module_state* state;\n    PyObject* my_error;\n\n    \/* R\u00e9cup\u00e8re l\u2019\u00e9tat allou\u00e9 par CPython gr\u00e2ce \u00e0 m_size. *\/\n    state = (module_state*)PyModule_GetState(module);\n\n    if (state == NULL) {\n        return -1;\n    }\n\n    \/* Initialisation explicite de l\u2019\u00e9tat. *\/\n    state-&gt;counter = 0;\n    state-&gt;message = NULL;\n\n    \/* Ajout des fonctions. *\/\n    if (PyModule_AddFunctions(module, mymodule_methods) &lt; 0) {\n        return -1;\n    }\n\n    \/* Ajout d\u2019une constante. *\/\n    if (PyModule_AddIntConstant(module, &quot;VERSION&quot;, 1) &lt; 0) {\n        return -1;\n    }\n\n    \/* Cr\u00e9ation et ajout d\u2019une exception personnalis\u00e9e. *\/\n    my_error = PyErr_NewException(&quot;mymodule.MyError&quot;, NULL, NULL);\n\n    if (my_error == NULL) {\n        return -1;\n    }\n\n    if (PyModule_AddObjectRef(module, &quot;MyError&quot;, my_error) &lt; 0) {\n        Py_DECREF(my_error);\n        return -1;\n    }\n\n    Py_DECREF(my_error);\n\n    return 0;\n}\n\n\/* ------------------------------------------------------------------ *\/\n\/* 5. Lib\u00e9ration de l\u2019\u00e9tat                                             *\/\n\/* ------------------------------------------------------------------ *\/\n\nstatic void\nmymodule_free(void* raw_state)\n{\n    module_state* state = (module_state*)raw_state;\n\n    if (state != NULL) {\n        PyMem_Free(state-&gt;message);\n        state-&gt;message = NULL;\n    }\n}\n\n\/* ------------------------------------------------------------------ *\/\n\/* 6. D\u00e9finition multi-phase du module                                 *\/\n\/* ------------------------------------------------------------------ *\/\n\nstatic struct PyModuleDef mymodule_module = {\n    PyModuleDef_HEAD_INIT,\n    .m_name = &quot;mymodule&quot;,\n    .m_doc = &quot;Exemple complet de module Python en C avec initialisation multi-phase.&quot;,\n    .m_size = sizeof(module_state),\n    .m_methods = mymodule_methods,\n    .m_slots = (PyModuleDef_Slot[]) {\n        {Py_mod_exec, mymodule_exec},\n        {0, NULL}\n    },\n    .m_free = mymodule_free\n};\n\n\/* ------------------------------------------------------------------ *\/\n\/* 7. Point d\u2019entr\u00e9e obligatoire                                       *\/\n\/* ------------------------------------------------------------------ *\/\n\nPyMODINIT_FUNC\nPyInit_mymodule(void)\n{\n    return PyModuleDef_Init(&amp;mymodule_module);\n}&lt;\/kbd&gt;<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color: #24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #E1E4E8\">#define <\/span><span style=\"color: #79B8FF\">PY_SSIZE_T_CLEAN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">#include <\/span><span style=\"color: #F97583\">&lt;<\/span><span style=\"color: #E1E4E8\">Python.h<\/span><span style=\"color: #F97583\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">#include <\/span><span style=\"color: #F97583\">&lt;<\/span><span style=\"color: #E1E4E8\">string.h<\/span><span style=\"color: #F97583\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* 1. \u00c9tat du module                                                   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">typedef struct {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    long counter;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    char<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> message;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">} module_state;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* 2. Fonctions expos\u00e9es \u00e0 Python                                      *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static PyObject<\/span><span style=\"color: #F97583\">*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B392F0\">add<\/span><span style=\"color: #E1E4E8\">(PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> self, PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> args)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    long a, b;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (<\/span><span style=\"color: #F97583\">!<\/span><span style=\"color: #B392F0\">PyArg_ParseTuple<\/span><span style=\"color: #E1E4E8\">(args, <\/span><span style=\"color: #9ECBFF\">&quot;ll&quot;<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #F97583\">&amp;<\/span><span style=\"color: #E1E4E8\">a, <\/span><span style=\"color: #F97583\">&amp;<\/span><span style=\"color: #E1E4E8\">b)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">PyLong_FromLong<\/span><span style=\"color: #E1E4E8\">(a <\/span><span style=\"color: #F97583\">+<\/span><span style=\"color: #E1E4E8\"> b);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static PyObject<\/span><span style=\"color: #F97583\">*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B392F0\">increment_counter<\/span><span style=\"color: #E1E4E8\">(PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> self, PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> args)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> state;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (<\/span><span style=\"color: #F97583\">!<\/span><span style=\"color: #B392F0\">PyArg_ParseTuple<\/span><span style=\"color: #E1E4E8\">(args, <\/span><span style=\"color: #9ECBFF\">&quot;&quot;<\/span><span style=\"color: #E1E4E8\">)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    state <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> (module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\">)<\/span><span style=\"color: #B392F0\">PyModule_GetState<\/span><span style=\"color: #E1E4E8\">(self);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (state <\/span><span style=\"color: #F97583\">==<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">counter<\/span><span style=\"color: #F97583\">++<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">PyLong_FromLong<\/span><span style=\"color: #E1E4E8\">(state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">counter);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static PyObject<\/span><span style=\"color: #F97583\">*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B392F0\">get_counter<\/span><span style=\"color: #E1E4E8\">(PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> self, PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> args)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> state;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (<\/span><span style=\"color: #F97583\">!<\/span><span style=\"color: #B392F0\">PyArg_ParseTuple<\/span><span style=\"color: #E1E4E8\">(args, <\/span><span style=\"color: #9ECBFF\">&quot;&quot;<\/span><span style=\"color: #E1E4E8\">)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    state <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> (module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\">)<\/span><span style=\"color: #B392F0\">PyModule_GetState<\/span><span style=\"color: #E1E4E8\">(self);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (state <\/span><span style=\"color: #F97583\">==<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">PyLong_FromLong<\/span><span style=\"color: #E1E4E8\">(state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">counter);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static PyObject<\/span><span style=\"color: #F97583\">*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B392F0\">set_message<\/span><span style=\"color: #E1E4E8\">(PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> self, PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> args)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">const<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">char<\/span><span style=\"color: #E1E4E8\">* text;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> state;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    char<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> copy;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (<\/span><span style=\"color: #F97583\">!<\/span><span style=\"color: #B392F0\">PyArg_ParseTuple<\/span><span style=\"color: #E1E4E8\">(args, <\/span><span style=\"color: #9ECBFF\">&quot;s&quot;<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #F97583\">&amp;<\/span><span style=\"color: #E1E4E8\">text)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    state <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> (module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\">)<\/span><span style=\"color: #B392F0\">PyModule_GetState<\/span><span style=\"color: #E1E4E8\">(self);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (state <\/span><span style=\"color: #F97583\">==<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    copy <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">PyMem_Malloc<\/span><span style=\"color: #E1E4E8\">(<\/span><span style=\"color: #B392F0\">strlen<\/span><span style=\"color: #E1E4E8\">(text) <\/span><span style=\"color: #F97583\">+<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">1<\/span><span style=\"color: #E1E4E8\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (copy <\/span><span style=\"color: #F97583\">==<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #B392F0\">PyErr_NoMemory<\/span><span style=\"color: #E1E4E8\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #B392F0\">strcpy<\/span><span style=\"color: #E1E4E8\">(copy, text);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #B392F0\">PyMem_Free<\/span><span style=\"color: #E1E4E8\">(state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">message);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">message <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> copy;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    Py_RETURN_NONE;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static PyObject<\/span><span style=\"color: #F97583\">*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B392F0\">get_message<\/span><span style=\"color: #E1E4E8\">(PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> self, PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> args)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> state;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (<\/span><span style=\"color: #F97583\">!<\/span><span style=\"color: #B392F0\">PyArg_ParseTuple<\/span><span style=\"color: #E1E4E8\">(args, <\/span><span style=\"color: #9ECBFF\">&quot;&quot;<\/span><span style=\"color: #E1E4E8\">)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    state <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> (module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\">)<\/span><span style=\"color: #B392F0\">PyModule_GetState<\/span><span style=\"color: #E1E4E8\">(self);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (state <\/span><span style=\"color: #F97583\">==<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">message <\/span><span style=\"color: #F97583\">==<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        Py_RETURN_NONE;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">PyUnicode_FromString<\/span><span style=\"color: #E1E4E8\">(state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">message);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static PyObject<\/span><span style=\"color: #F97583\">*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B392F0\">divide<\/span><span style=\"color: #E1E4E8\">(PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> self, PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> args)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    long a, b;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (<\/span><span style=\"color: #F97583\">!<\/span><span style=\"color: #B392F0\">PyArg_ParseTuple<\/span><span style=\"color: #E1E4E8\">(args, <\/span><span style=\"color: #9ECBFF\">&quot;ll&quot;<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #F97583\">&amp;<\/span><span style=\"color: #E1E4E8\">a, <\/span><span style=\"color: #F97583\">&amp;<\/span><span style=\"color: #E1E4E8\">b)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (b <\/span><span style=\"color: #F97583\">==<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">0<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #B392F0\">PyErr_SetString<\/span><span style=\"color: #E1E4E8\">(PyExc_ZeroDivisionError, <\/span><span style=\"color: #9ECBFF\">&quot;division by zero&quot;<\/span><span style=\"color: #E1E4E8\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">PyFloat_FromDouble<\/span><span style=\"color: #E1E4E8\">((double)a <\/span><span style=\"color: #F97583\">\/<\/span><span style=\"color: #E1E4E8\"> (double)b);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* 3. Table des m\u00e9thodes                                               *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static PyMethodDef mymodule_methods[] <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    {<\/span><span style=\"color: #9ECBFF\">&quot;add&quot;<\/span><span style=\"color: #E1E4E8\">, add, <\/span><span style=\"color: #79B8FF\">METH_VARARGS<\/span><span style=\"color: #E1E4E8\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">     <\/span><span style=\"color: #9ECBFF\">&quot;add(a, b) -&gt; int<\/span><span style=\"color: #79B8FF\">nn<\/span><span style=\"color: #9ECBFF\">Return the sum of two integers.&quot;<\/span><span style=\"color: #E1E4E8\">},<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    {<\/span><span style=\"color: #9ECBFF\">&quot;divide&quot;<\/span><span style=\"color: #E1E4E8\">, divide, <\/span><span style=\"color: #79B8FF\">METH_VARARGS<\/span><span style=\"color: #E1E4E8\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">     <\/span><span style=\"color: #9ECBFF\">&quot;divide(a, b) -&gt; float<\/span><span style=\"color: #79B8FF\">nn<\/span><span style=\"color: #9ECBFF\">Return a divided by b.&quot;<\/span><span style=\"color: #E1E4E8\">},<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    {<\/span><span style=\"color: #9ECBFF\">&quot;increment_counter&quot;<\/span><span style=\"color: #E1E4E8\">, increment_counter, <\/span><span style=\"color: #79B8FF\">METH_VARARGS<\/span><span style=\"color: #E1E4E8\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">     <\/span><span style=\"color: #9ECBFF\">&quot;increment_counter() -&gt; int<\/span><span style=\"color: #79B8FF\">nn<\/span><span style=\"color: #9ECBFF\">Increment and return the module counter.&quot;<\/span><span style=\"color: #E1E4E8\">},<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    {<\/span><span style=\"color: #9ECBFF\">&quot;get_counter&quot;<\/span><span style=\"color: #E1E4E8\">, get_counter, <\/span><span style=\"color: #79B8FF\">METH_VARARGS<\/span><span style=\"color: #E1E4E8\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">     <\/span><span style=\"color: #9ECBFF\">&quot;get_counter() -&gt; int<\/span><span style=\"color: #79B8FF\">nn<\/span><span style=\"color: #9ECBFF\">Return the current module counter.&quot;<\/span><span style=\"color: #E1E4E8\">},<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    {<\/span><span style=\"color: #9ECBFF\">&quot;set_message&quot;<\/span><span style=\"color: #E1E4E8\">, set_message, <\/span><span style=\"color: #79B8FF\">METH_VARARGS<\/span><span style=\"color: #E1E4E8\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">     <\/span><span style=\"color: #9ECBFF\">&quot;set_message(text) -&gt; None<\/span><span style=\"color: #79B8FF\">nn<\/span><span style=\"color: #9ECBFF\">Store a message in the module state.&quot;<\/span><span style=\"color: #E1E4E8\">},<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    {<\/span><span style=\"color: #9ECBFF\">&quot;get_message&quot;<\/span><span style=\"color: #E1E4E8\">, get_message, <\/span><span style=\"color: #79B8FF\">METH_VARARGS<\/span><span style=\"color: #E1E4E8\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">     <\/span><span style=\"color: #9ECBFF\">&quot;get_message() -&gt; str or None<\/span><span style=\"color: #79B8FF\">nn<\/span><span style=\"color: #9ECBFF\">Return the stored message.&quot;<\/span><span style=\"color: #E1E4E8\">},<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    {<\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #79B8FF\">0<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">};<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* 4. Slot Py_mod_exec : initialisation du module                      *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B392F0\">mymodule_exec<\/span><span style=\"color: #E1E4E8\">(PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">module<\/span><span style=\"color: #E1E4E8\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> state;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    PyObject<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> my_error;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #6A737D\">\/* R\u00e9cup\u00e8re l\u2019\u00e9tat allou\u00e9 par CPython gr\u00e2ce \u00e0 m_size. *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    state <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> (module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\">)<\/span><span style=\"color: #B392F0\">PyModule_GetState<\/span><span style=\"color: #E1E4E8\">(<\/span><span style=\"color: #79B8FF\">module<\/span><span style=\"color: #E1E4E8\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (state <\/span><span style=\"color: #F97583\">==<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #F97583\">-<\/span><span style=\"color: #79B8FF\">1<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #6A737D\">\/* Initialisation explicite de l\u2019\u00e9tat. *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">counter <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">0<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">message <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #6A737D\">\/* Ajout des fonctions. *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (<\/span><span style=\"color: #B392F0\">PyModule_AddFunctions<\/span><span style=\"color: #E1E4E8\">(<\/span><span style=\"color: #79B8FF\">module<\/span><span style=\"color: #E1E4E8\">, mymodule_methods) <\/span><span style=\"color: #F97583\">&lt;<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">0<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #F97583\">-<\/span><span style=\"color: #79B8FF\">1<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #6A737D\">\/* Ajout d\u2019une constante. *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (<\/span><span style=\"color: #B392F0\">PyModule_AddIntConstant<\/span><span style=\"color: #E1E4E8\">(<\/span><span style=\"color: #79B8FF\">module<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #9ECBFF\">&quot;VERSION&quot;<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #79B8FF\">1<\/span><span style=\"color: #E1E4E8\">) <\/span><span style=\"color: #F97583\">&lt;<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">0<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #F97583\">-<\/span><span style=\"color: #79B8FF\">1<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #6A737D\">\/* Cr\u00e9ation et ajout d\u2019une exception personnalis\u00e9e. *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    my_error <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">PyErr_NewException<\/span><span style=\"color: #E1E4E8\">(<\/span><span style=\"color: #9ECBFF\">&quot;mymodule.MyError&quot;<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (my_error <\/span><span style=\"color: #F97583\">==<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #F97583\">-<\/span><span style=\"color: #79B8FF\">1<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (<\/span><span style=\"color: #B392F0\">PyModule_AddObjectRef<\/span><span style=\"color: #E1E4E8\">(<\/span><span style=\"color: #79B8FF\">module<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #9ECBFF\">&quot;MyError&quot;<\/span><span style=\"color: #E1E4E8\">, my_error) <\/span><span style=\"color: #F97583\">&lt;<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">0<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #B392F0\">Py_DECREF<\/span><span style=\"color: #E1E4E8\">(my_error);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #F97583\">-<\/span><span style=\"color: #79B8FF\">1<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #B392F0\">Py_DECREF<\/span><span style=\"color: #E1E4E8\">(my_error);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">0<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* 5. Lib\u00e9ration de l\u2019\u00e9tat                                             *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static <\/span><span style=\"color: #F97583\">void<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B392F0\">mymodule_free<\/span><span style=\"color: #E1E4E8\">(<\/span><span style=\"color: #F97583\">void*<\/span><span style=\"color: #E1E4E8\"> raw_state)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\"> state <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> (module_state<\/span><span style=\"color: #F97583\">*<\/span><span style=\"color: #E1E4E8\">)raw_state;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">if<\/span><span style=\"color: #E1E4E8\"> (state <\/span><span style=\"color: #F97583\">!=<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        <\/span><span style=\"color: #B392F0\">PyMem_Free<\/span><span style=\"color: #E1E4E8\">(state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">message);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        state<\/span><span style=\"color: #F97583\">-&gt;<\/span><span style=\"color: #E1E4E8\">message <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* 6. D\u00e9finition multi-phase du module                                 *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">static struct PyModuleDef mymodule_module <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    PyModuleDef_HEAD_INIT,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    .m_name <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #9ECBFF\">&quot;mymodule&quot;<\/span><span style=\"color: #E1E4E8\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    .m_doc <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #9ECBFF\">&quot;Exemple complet de module Python en C avec initialisation multi-phase.&quot;<\/span><span style=\"color: #E1E4E8\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    .m_size <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">sizeof<\/span><span style=\"color: #E1E4E8\">(module_state),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    .m_methods <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> mymodule_methods,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    .m_slots <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> (PyModuleDef_Slot[]) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        {Py_mod_exec, mymodule_exec},<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">        {<\/span><span style=\"color: #79B8FF\">0<\/span><span style=\"color: #E1E4E8\">, <\/span><span style=\"color: #79B8FF\">NULL<\/span><span style=\"color: #E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    .m_free <\/span><span style=\"color: #F97583\">=<\/span><span style=\"color: #E1E4E8\"> mymodule_free<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">};<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* 7. Point d\u2019entr\u00e9e obligatoire                                       *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/* ------------------------------------------------------------------ *\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">PyMODINIT_FUNC<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B392F0\">PyInit_mymodule<\/span><span style=\"color: #E1E4E8\">(<\/span><span style=\"color: #F97583\">void<\/span><span style=\"color: #E1E4E8\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">    <\/span><span style=\"color: #F97583\">return<\/span><span style=\"color: #E1E4E8\"> <\/span><span style=\"color: #B392F0\">PyModuleDef_Init<\/span><span style=\"color: #E1E4E8\">(<\/span><span style=\"color: #F97583\">&amp;<\/span><span style=\"color: #E1E4E8\">mymodule_module);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E1E4E8\">}<\/span><span style=\"color: #F97583\">&lt;\/<\/span><span style=\"color: #E1E4E8\">kbd<\/span><span style=\"color: #F97583\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\"><\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><br><br><\/p>\n\n\n\n<div class=\"wp-block-group has-cyan-bluish-gray-background-color has-background\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\"><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Commen\u00e7ons par le code source. Il existe deux m\u00e9thodes : la m\u00e9thode en une seule phase et la m\u00e9thode en plusieurs phases. La m\u00e9thode en une seule phase n&#x27;est plus recommand\u00e9e (est-elle obsol\u00e8te ?&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-169","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/wecarus.fr\/index.php\/wp-json\/wp\/v2\/pages\/169","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wecarus.fr\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/wecarus.fr\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/wecarus.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wecarus.fr\/index.php\/wp-json\/wp\/v2\/comments?post=169"}],"version-history":[{"count":0,"href":"https:\/\/wecarus.fr\/index.php\/wp-json\/wp\/v2\/pages\/169\/revisions"}],"wp:attachment":[{"href":"https:\/\/wecarus.fr\/index.php\/wp-json\/wp\/v2\/media?parent=169"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}