Definiowanie modułów rozszerzeń
*******************************

Rozszerzeniem języka C dla CPython jest współdzielona biblioteka (na
".so" przykład plik w systemie Linux, ".pyd" biblioteka DLL w systemie
Windows), którą można załadować do proces Pythona  (na przykład
skompilować z użyciem zgodnych ustawień kompilatora) i która
eksportuje funkcja *export hook* (lub staromodną funkcja inicjalizacja
:ref:` <extension-pyinit>).

Aby można było importować współdzielona biblioteka współdzieloną
domyślny (czyli przez "importlib.machinery.ExtensionFileLoader" ),
musi być ona dostępna w "sys.path", a jej nazwa musi składać się z
nazwy moduł i rozszerzenia wymienionego
w:py:attr:*importlib.machinery.EXTENSION_SUFFIXES* .

Informacja:

  Kompilację, pakowanie i dystrybucję modułów rozszerzeń zewnętrzny
  wykonywać za pomocą narzędzi firm trzecich, co wykracza poza zakres
  niniejszego dokumentu. Jednym z odpowiednich narzędzi jest
  Setuptools, którego dokumentację można znaleźć pod adresem
  https://setuptools.pypa.io/en/latest/setuptools.html.


Hak eksportowy przedłużacza
===========================

 Dodane w wersji 3.15: wparcie Obsługa haka "PyModExport_*<name>*"
eksportu została dodana w Python 3.15. Starszy sposób definiowania
moduł jest nadal dostępny: zapoznaj się z PyInit function sekcją lub
wcześniejszymi  wersja tej dokumentacji, jeśli planujesz wparcie
wparcie wersja Pythona.

Hak eksportowy musi być eksportowaną funkcja o następującym podpisie:

PySlot *PyModExport_modulename(void)

W przypadku modułów z nazwami zawierającymi wyłącznie znaki ASCII,
parametr export hook musi mieć nazwę "PyModExport_*<name>*", a
>>``<<<name>``następnie zostać zastąpiony nazwą modułu.

W przypadku nazw modułów spoza zestawu ASCII hak eksportu musi zostać
nazwany "PyModExportU_*<name>*`(zwróć uwagę na ``U`" ), "<name>"
zakodowany przy użyciu kodowania *punycode* języka Python, z
myślnikami zastąpionymi podkreśleniami. W Python:

   def hook_name(name):
   try:
   przyrostek = b'_' + name.encode('ascii')
   except UnicodeEncodeError:
   przyrostek = b'U_' + name.encode('punycode').replace(b'-', b'_')
   zwracać b'PyModExport' + przyrostek

Hak eksportu zwracać tablica "PySlot" wpisów zakończoną wpisem o
identyfikatorze slotu równym "0". Sloty te opisują sposób tworzenia i
inicjalizacji moduł.

Ta tablica musi ważny prawidłowa i stała do momentu zamknięcia
"static" interpreter . Zazwyczaj powinna korzystać "Py_mod_create`z
:c:macro:`Py_mod_exec" pamięci masowej. Preferowane jest używanie
slotów i w przypadku wszelkich dynamicznych  zachowanie.

Hak eksportu może zwracać "NULL" wyjątek ustawiony na sygnał awarii.

Zaleca się zdefiniowanie  funkcja haka eksportu za pomocą makro
pomocniczego:

PyMODEXPORT_FUNC
    * Część stabilnego ABI od wersji 3.15.*

   Zadeklaruj hak eksportu moduł rozszerzenia. To makro:

   * określa PySlot* typ zwracać,

   * dodaje wszelkie specjalne deklaracje połączeń wymagane przez
     platformę i

   * dla C++ deklaruje funkcja jako

Na przykład moduł o "spam" nazwie zostałby zdefiniowany w następujący
sposób:

   PyABIInfo_VAR(abi_info);

   static PySlot spam_slots[] = {
   PySlot_STATIC_DATA(Py_mod_abi, &abi_info),
   PySlot_STATIC_DATA(Py_mod_name, "spam"),
   PySlot_FUNC(Py_mod_init, spam_init_function),
   ...
   PySlot_END
   };

   PyMODEXPORT_FUNC
   PyModExport_spam(void)
   {
   zwracać spam_slots;
   }

Hak eksportu jest zazwyczaj jedynym elementem innym niż  "static"
zdefiniowanym w kodzie źródłowym moduł C.

Hak powinien być krótki – najlepiej jeden wiersz, jak powyżej. Jeśli
jednak musisz użyć API Python C API w tej funkcja, zaleca się
najpierw wywołać ją, aby zgłosić rzucić wyjątek, zamiast spowodować
awarię, w typowych przypadkach niezgodności ABI.

Informacja:

  Możliwe jest eksportowanie wielu moduł z jednej biblioteki
  współdzielona biblioteka poprzez zdefiniowanie wielu haków eksportu.
  Ich importowanie wymaga jednak użycia niestandardowego importera lub
  odpowiednio nazwanych kopii/linków pliku rozszerzenia, ponieważ
  mechanizm importu Pythona znajduje tylko funkcja odpowiadającą
  nazwie pliku. Szczegółowe informacje  moduł można znaleźć w sekcji
  „Wiele modułów w jednej biblioteka”.
  <https://peps.python.org/pep-0489/#multiple-modules-in-one-
  library>`__  section in **PEP 489** for details.


Inicjalizacja wielofazowa
=========================

przetwarzanie/proces przetwarzanie tworzenia moduł rozszerzenia
przebiega w kilku fazach:

* Python wyszukuje i wywołuje hak eksportu, aby uzyskać informacje o
  sposobie tworzenia moduł.

* Zanim zostanie wykonany jakikolwiek istotny kod, Python może
  określić, jakie możliwości obsługuje moduł, i dostosować środowisko
  lub odmówić załadowania niekompatybilnego rozszerzenia. Na ten krok
  wpływają sloty takie jak "Py_mod_abi" ,  "Py_mod_gil`i
  :c:data:`Py_mod_multiple_interpreters" .

* domyślny Python sam tworzy obiekt moduł – czyli wykonuje czynność
  odpowiadającą wywołaniu "__new__()" podczas tworzenia obiektu. Ten
  krok można pominąć za pomocą "Py_mod_create" slotu.

* Python ustawia początkowe atrybuty moduł, takie jak "__package__" i
  "__loader__", i wstawia obiekt modułu do "sys.modules".

* Afterwards, the module object is initialized in an extension-
  specific way -- the equivalent of "__init__()" when creating an
  object, or of executing top-level code in a Python-language module.
  The behavior is specified using the "Py_mod_exec" slot.

This is called *multi-phase initialization* to distinguish it from the
legacy (but still supported) single-phase initialization, where an
initialization function returns a fully constructed module.

Zmienione w wersji 3.5: Added support for multi-phase initialization
(**PEP 489**).


Multiple module instances
=========================

By default, extension modules are not singletons. For example, if the
"sys.modules" entry is removed and the module is re-imported, a new
module object is created and, typically, populated with fresh method
and type objects. The old module is subject to normal garbage
collection. This mirrors the behavior of pure-Python modules.

Additional module instances may be created in sub-interpreters or
after Python runtime reinitialization ("Py_Finalize()" and
"Py_Initialize()"). In these cases, sharing Python objects between
module instances would likely cause crashes or undefined behavior.

To avoid such issues, each instance of an extension module should be
*isolated*: changes to one instance should not implicitly affect the
others, and all state owned by the module, including references to
Python objects, should be specific to a particular module instance.
See Isolating Extension Modules for more details and a practical
guide.

A simpler way to avoid these issues is raising an error on repeated
initialization.

All modules are expected to support sub-interpreters, or otherwise
explicitly signal a lack of support. This is usually achieved by
isolation or blocking repeated initialization, as above. A module may
also be limited to the main interpreter using the
"Py_mod_multiple_interpreters" slot.


"PyInit" function
=================

Soft deprecated since version 3.15: This functionality will not get
new features, but there are no plans to remove it.

Instead of "PyModExport_modulename()", an extension module can define
an older-style *initialization function* with the signature:

PyObject *PyInit_modulename(void)

Its name should be "PyInit_*<name>*", with "<name>" replaced by the
name of the module. For non-ASCII module names, use "PyInitU_*<name>*"
instead, with "<name>" encoded in the same way as for the export hook
(that is, using Punycode with underscores).

If a module exports both "PyInit_*<name>*" and "PyModExport_*<name>*",
the "PyInit_*<name>*" function is ignored.

Like with "PyMODEXPORT_FUNC", it is recommended to define the
initialization function using a helper macro:

PyMODINIT_FUNC

   Declare an extension module initialization function. This macro:

   * specifies the PyObject* return type,

   * dodaje wszelkie specjalne deklaracje połączeń wymagane przez
     platformę i

   * dla C++ deklaruje funkcja jako

Normally, the initialization function ("PyInit_modulename") returns a
"PyModuleDef" instance with non-"NULL" "m_slots". This allows Python
to use multi-phase initialization.

Before it is returned, the "PyModuleDef" instance must be initialized
using the following function:

PyObject *PyModuleDef_Init(PyModuleDef *def)
    * Część stabilnego ABI od wersji 3.5.*

   Ensure a module definition is a properly initialized Python object
   that correctly reports its type and a reference count.

   Return *def* cast to "PyObject*", or "NULL" if an error occurred.

   Calling this function is required before returning a "PyModuleDef"
   from a module initialization function. It should not be used in
   other contexts.

   Note that Python assumes that "PyModuleDef" structures are
   statically allocated. This function may return either a new
   reference or a borrowed one; this reference must not be released.

    Dodane w wersji 3.5.

Na przykład moduł o "spam" nazwie zostałby zdefiniowany w następujący
sposób:

   static struct PyModuleDef spam_module = {
       .m_base = PyModuleDef_HEAD_INIT,
       .m_name = "spam",
       ...
   };

   PyMODINIT_FUNC
   PyInit_spam(void)
   {
       return PyModuleDef_Init(&spam_module);
   }


Legacy single-phase initialization
----------------------------------

Soft deprecated since version 3.15: Single-phase initialization is a
legacy mechanism to initialize extension modules, with known drawbacks
and design flaws. Extension module authors are encouraged to use
multi-phase initialization instead.However, there are no plans to
remove support for it.

In single-phase initialization, the old-style initialization function
("PyInit_modulename") should create, populate and return a module
object. This is typically done using "PyModule_Create()" and functions
like "PyModule_AddObjectRef()".

Single-phase initialization differs from the default in the following
ways:

* Single-phase modules are, or rather *contain*, “singletons”.

  When the module is first initialized, Python saves the contents of
  the module's "__dict__" (that is, typically, the module's functions
  and types).

  For subsequent imports, Python does not call the initialization
  function again. Instead, it creates a new module object with a new
  "__dict__", and copies the saved contents to it. For example, given
  a single-phase module "_testsinglephase" [1] that defines a function
  "sum" and an exception class "error":

     >>> import sys
     >>> import _testsinglephase as one
     >>> del sys.modules['_testsinglephase']
     >>> import _testsinglephase as two
     >>> one is two
     False
     >>> one.__dict__ is two.__dict__
     False
     >>> one.sum is two.sum
     True
     >>> one.error is two.error
     True

  The exact behavior should be considered a CPython implementation
  detail.

* To work around the fact that "PyInit_modulename" does not take a
  *spec* argument, some state of the import machinery is saved and
  applied to the first suitable module created during the
  "PyInit_modulename" call. Specifically, when a sub-module is
  imported, this mechanism prepends the parent package name to the
  name of the module.

  A single-phase "PyInit_modulename" function should create “its”
  module object as soon as possible, before any other module objects
  can be created.

* Non-ASCII module names ("PyInitU_modulename") are not supported.

* Single-phase modules support module lookup functions like
  "PyState_FindModule()".

* The module's "PyModuleDef.m_slots" must be NULL.

[1] "_testsinglephase" is an internal module used in CPython's self-
    test suite; your installation may or may not include it.
