# SOME DESCRIPTIVE TITLE. # Copyright (C) 2001 Python Software Foundation # This file is distributed under the same license as the Python package. # FIRST AUTHOR , YEAR. # # Translators: # python-doc bot, 2025 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Python 3.15\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2026-09-14 20:17+0000\n" "PO-Revision-Date: 2025-09-16 00:00+0000\n" "Last-Translator: python-doc bot, 2025\n" "Language-Team: German (https://app.transifex.com/python-doc/teams/5390/de/)\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../../howto/isolating-extensions.rst:7 msgid "Isolating Extension Modules" msgstr "" #: ../../howto/isolating-extensions.rst:9 msgid "Abstract" msgstr "" #: ../../howto/isolating-extensions.rst:11 msgid "" "Traditionally, state belonging to Python extension modules was kept in C " "``static`` variables, which have process-wide scope. This document describes " "problems of such per-process state and shows a safer way: per-module state." msgstr "" #: ../../howto/isolating-extensions.rst:16 msgid "" "The document also describes how to switch to per-module state where " "possible. This transition involves allocating space for that state, " "potentially switching from static types to heap types, and—perhaps most " "importantly—accessing per-module state from code." msgstr "" #: ../../howto/isolating-extensions.rst:23 msgid "Who should read this" msgstr "" #: ../../howto/isolating-extensions.rst:25 msgid "" "This guide is written for maintainers of :ref:`C-API ` " "extensions who would like to make that extension safer to use in " "applications where Python itself is used as a library." msgstr "" #: ../../howto/isolating-extensions.rst:31 msgid "Background" msgstr "" #: ../../howto/isolating-extensions.rst:33 msgid "" "An *interpreter* is the context in which Python code runs. It contains " "configuration (e.g. the import path) and runtime state (e.g. the set of " "imported modules)." msgstr "" #: ../../howto/isolating-extensions.rst:37 msgid "" "Python supports running multiple interpreters in one process. There are two " "cases to think about—users may run interpreters:" msgstr "" #: ../../howto/isolating-extensions.rst:40 msgid "" "in sequence, with several :c:func:`Py_InitializeEx`/:c:func:`Py_FinalizeEx` " "cycles, and" msgstr "" #: ../../howto/isolating-extensions.rst:42 msgid "" "in parallel, managing \"sub-interpreters\" using :c:func:" "`Py_NewInterpreter`/:c:func:`Py_EndInterpreter`." msgstr "" #: ../../howto/isolating-extensions.rst:45 msgid "" "Both cases (and combinations of them) would be most useful when embedding " "Python within a library. Libraries generally shouldn't make assumptions " "about the application that uses them, which include assuming a process-wide " "\"main Python interpreter\"." msgstr "" #: ../../howto/isolating-extensions.rst:50 msgid "" "Historically, Python extension modules don't handle this use case well. Many " "extension modules (and even some stdlib modules) use *per-process* global " "state, because C ``static`` variables are extremely easy to use. Thus, data " "that should be specific to an interpreter ends up being shared between " "interpreters. Unless the extension developer is careful, it is very easy to " "introduce edge cases that lead to crashes when a module is loaded in more " "than one interpreter in the same process." msgstr "" #: ../../howto/isolating-extensions.rst:58 msgid "" "Unfortunately, *per-interpreter* state is not easy to achieve. Extension " "authors tend to not keep multiple interpreters in mind when developing, and " "it is currently cumbersome to test the behavior." msgstr "" #: ../../howto/isolating-extensions.rst:63 msgid "Enter Per-Module State" msgstr "" #: ../../howto/isolating-extensions.rst:65 msgid "" "Instead of focusing on per-interpreter state, Python's C API is evolving to " "better support the more granular *per-module* state. This means that C-level " "data should be attached to a *module object*. Each interpreter creates its " "own module object, keeping the data separate. For testing the isolation, " "multiple module objects corresponding to a single extension can even be " "loaded in a single interpreter." msgstr "" #: ../../howto/isolating-extensions.rst:72 msgid "" "Per-module state provides an easy way to think about lifetime and resource " "ownership: the extension module will initialize when a module object is " "created, and clean up when it's freed. In this regard, a module is just like " "any other :c:expr:`PyObject *`; there are no \"on interpreter shutdown\" " "hooks to think—or forget—about." msgstr "" #: ../../howto/isolating-extensions.rst:78 msgid "" "Note that there are use cases for different kinds of \"globals\": per-" "process, per-interpreter, per-thread or per-task state. With per-module " "state as the default, these are still possible, but you should treat them as " "exceptional cases: if you need them, you should give them additional care " "and testing. (Note that this guide does not cover them.)" msgstr "" #: ../../howto/isolating-extensions.rst:87 msgid "Isolated Module Objects" msgstr "" #: ../../howto/isolating-extensions.rst:89 msgid "" "The key point to keep in mind when developing an extension module is that " "several module objects can be created from a single shared library. For " "example:" msgstr "" #: ../../howto/isolating-extensions.rst:93 msgid "" ">>> import sys\n" ">>> import binascii\n" ">>> old_binascii = binascii\n" ">>> del sys.modules['binascii']\n" ">>> import binascii # create a new module object\n" ">>> old_binascii == binascii\n" "False" msgstr "" #: ../../howto/isolating-extensions.rst:103 msgid "" "As a rule of thumb, the two modules should be completely independent. All " "objects and state specific to the module should be encapsulated within the " "module object, not shared with other module objects, and cleaned up when the " "module object is deallocated. Since this just is a rule of thumb, exceptions " "are possible (see `Managing Global State`_), but they will need more thought " "and attention to edge cases." msgstr "" #: ../../howto/isolating-extensions.rst:111 msgid "" "While some modules could do with less stringent restrictions, isolated " "modules make it easier to set clear expectations and guidelines that work " "across a variety of use cases." msgstr "" #: ../../howto/isolating-extensions.rst:117 msgid "Surprising Edge Cases" msgstr "" #: ../../howto/isolating-extensions.rst:119 msgid "" "Note that isolated modules do create some surprising edge cases. Most " "notably, each module object will typically not share its classes and " "exceptions with other similar modules. Continuing from the `example above " "`__, note that ``old_binascii.Error`` and " "``binascii.Error`` are separate objects. In the following code, the " "exception is *not* caught:" msgstr "" #: ../../howto/isolating-extensions.rst:126 msgid "" ">>> old_binascii.Error == binascii.Error\n" "False\n" ">>> try:\n" "... old_binascii.unhexlify(b'qwertyuiop')\n" "... except binascii.Error:\n" "... print('boo')\n" "...\n" "Traceback (most recent call last):\n" " File \"\", line 2, in \n" "binascii.Error: Non-hexadecimal digit found" msgstr "" #: ../../howto/isolating-extensions.rst:139 msgid "" "This is expected. Notice that pure-Python modules behave the same way: it is " "a part of how Python works." msgstr "" #: ../../howto/isolating-extensions.rst:142 msgid "" "The goal is to make extension modules safe at the C level, not to make hacks " "behave intuitively. Mutating ``sys.modules`` \"manually\" counts as a hack." msgstr "" #: ../../howto/isolating-extensions.rst:148 msgid "Making Modules Safe with Multiple Interpreters" msgstr "" #: ../../howto/isolating-extensions.rst:152 msgid "Managing Global State" msgstr "" #: ../../howto/isolating-extensions.rst:154 msgid "" "Sometimes, the state associated with a Python module is not specific to that " "module, but to the entire process (or something else \"more global\" than a " "module). For example:" msgstr "" #: ../../howto/isolating-extensions.rst:158 msgid "The ``readline`` module manages *the* terminal." msgstr "" #: ../../howto/isolating-extensions.rst:159 msgid "" "A module running on a circuit board wants to control *the* on-board LED." msgstr "" #: ../../howto/isolating-extensions.rst:162 msgid "" "In these cases, the Python module should provide *access* to the global " "state, rather than *own* it. If possible, write the module so that multiple " "copies of it can access the state independently (along with other libraries, " "whether for Python or other languages). If that is not possible, consider " "explicit locking." msgstr "" #: ../../howto/isolating-extensions.rst:168 msgid "" "If it is necessary to use process-global state, the simplest way to avoid " "issues with multiple interpreters is to explicitly prevent a module from " "being loaded more than once per process—see :ref:`isolating-extensions-" "optout`." msgstr "" #: ../../howto/isolating-extensions.rst:175 msgid "Managing Per-Module State" msgstr "" #: ../../howto/isolating-extensions.rst:177 msgid "" "To use per-module state, use :ref:`multi-phase extension module " "initialization `. This signals that your module " "supports multiple interpreters correctly." msgstr "" #: ../../howto/isolating-extensions.rst:181 msgid "" "Set ``PyModuleDef.m_size`` to a positive number to request that many bytes " "of storage local to the module. Usually, this will be set to the size of " "some module-specific ``struct``, which can store all of the module's C-level " "state. In particular, it is where you should put pointers to classes " "(including exceptions, but excluding static types) and settings (e.g. " "``csv``'s :py:data:`~csv.field_size_limit`) which the C code needs to " "function." msgstr "" #: ../../howto/isolating-extensions.rst:190 msgid "" "Another option is to store state in the module's ``__dict__``, but you must " "avoid crashing when users modify ``__dict__`` from Python code. This usually " "means error- and type-checking at the C level, which is easy to get wrong " "and hard to test sufficiently." msgstr "" #: ../../howto/isolating-extensions.rst:195 msgid "" "However, if module state is not needed in C code, storing it in ``__dict__`` " "only is a good idea." msgstr "" #: ../../howto/isolating-extensions.rst:198 msgid "" "If the module state includes ``PyObject`` pointers, the module object must " "hold references to those objects and implement the module-level hooks " "``m_traverse``, ``m_clear`` and ``m_free``. These work like ``tp_traverse``, " "``tp_clear`` and ``tp_free`` of a class. Adding them will require some work " "and make the code longer; this is the price for modules which can be " "unloaded cleanly." msgstr "" #: ../../howto/isolating-extensions.rst:205 msgid "" "An example of a module with per-module state is currently available as " "`xxlimited `__; example module initialization shown at the bottom of the file." msgstr "" #: ../../howto/isolating-extensions.rst:213 msgid "Opt-Out: Limiting to One Module Object per Process" msgstr "" #: ../../howto/isolating-extensions.rst:215 msgid "" "A non-negative ``PyModuleDef.m_size`` signals that a module supports " "multiple interpreters correctly. If this is not yet the case for your " "module, you can explicitly make your module loadable only once per process. " "For example::" msgstr "" #: ../../howto/isolating-extensions.rst:220 msgid "" "// A process-wide flag\n" "static int loaded = 0;\n" "\n" "// Mutex to provide thread safety (only needed for free-threaded Python)\n" "static PyMutex modinit_mutex = {0};\n" "\n" "static int\n" "exec_module(PyObject* module)\n" "{\n" " PyMutex_Lock(&modinit_mutex);\n" " if (loaded) {\n" " PyMutex_Unlock(&modinit_mutex);\n" " PyErr_SetString(PyExc_ImportError,\n" " \"cannot load module more than once per process\");\n" " return -1;\n" " }\n" " loaded = 1;\n" " PyMutex_Unlock(&modinit_mutex);\n" " // ... rest of initialization\n" "}" msgstr "" #: ../../howto/isolating-extensions.rst:242 msgid "" "If your module's :c:member:`PyModuleDef.m_clear` function is able to prepare " "for future re-initialization, it should clear the ``loaded`` flag. In this " "case, your module won't support multiple instances existing *concurrently*, " "but it will, for example, support being loaded after Python runtime shutdown " "(:c:func:`Py_FinalizeEx`) and re-initialization (:c:func:`Py_Initialize`)." msgstr "" #: ../../howto/isolating-extensions.rst:251 msgid "Module State Access from Functions" msgstr "" #: ../../howto/isolating-extensions.rst:253 msgid "" "Accessing the state from module-level functions is straightforward. " "Functions get the module object as their first argument; for extracting the " "state, you can use ``PyModule_GetState``::" msgstr "" #: ../../howto/isolating-extensions.rst:257 msgid "" "static PyObject *\n" "func(PyObject *module, PyObject *args)\n" "{\n" " my_struct *state = (my_struct*)PyModule_GetState(module);\n" " if (state == NULL) {\n" " return NULL;\n" " }\n" " // ... rest of logic\n" "}" msgstr "" #: ../../howto/isolating-extensions.rst:268 msgid "" "``PyModule_GetState`` may return ``NULL`` without setting an exception if " "there is no module state, i.e. ``PyModuleDef.m_size`` was zero. In your own " "module, you're in control of ``m_size``, so this is easy to prevent." msgstr "" #: ../../howto/isolating-extensions.rst:275 msgid "Heap Types" msgstr "" #: ../../howto/isolating-extensions.rst:277 msgid "" "Traditionally, types defined in C code are *static*; that is, ``static " "PyTypeObject`` structures defined directly in code and initialized using " "``PyType_Ready()``." msgstr "" #: ../../howto/isolating-extensions.rst:281 msgid "" "Such types are necessarily shared across the process. Sharing them between " "module objects requires paying attention to any state they own or access. To " "limit the possible issues, static types are immutable at the Python level: " "for example, you can't set ``str.myattribute = 123``." msgstr "" #: ../../howto/isolating-extensions.rst:287 msgid "" "Sharing truly immutable objects between interpreters is fine, as long as " "they don't provide access to mutable objects. However, in CPython, every " "Python object has a mutable implementation detail: the reference count. " "Changes to the refcount are guarded by the GIL. Thus, code that shares any " "Python objects across interpreters implicitly depends on CPython's current, " "process-wide GIL." msgstr "" #: ../../howto/isolating-extensions.rst:294 msgid "" "Because they are immutable and process-global, static types cannot access " "\"their\" module state. If any method of such a type requires access to " "module state, the type must be converted to a *heap-allocated type*, or " "*heap type* for short. These correspond more closely to classes created by " "Python's ``class`` statement." msgstr "" #: ../../howto/isolating-extensions.rst:301 msgid "For new modules, using heap types by default is a good rule of thumb." msgstr "" #: ../../howto/isolating-extensions.rst:305 msgid "Changing Static Types to Heap Types" msgstr "" #: ../../howto/isolating-extensions.rst:307 msgid "" "Static types can be converted to heap types, but note that the heap type API " "was not designed for \"lossless\" conversion from static types—that is, " "creating a type that works exactly like a given static type. So, when " "rewriting the class definition in a new API, you are likely to " "unintentionally change a few details (e.g. pickleability or inherited " "slots). Always test the details that are important to you." msgstr "" #: ../../howto/isolating-extensions.rst:316 msgid "" "Watch out for the following two points in particular (but note that this is " "not a comprehensive list):" msgstr "" #: ../../howto/isolating-extensions.rst:319 msgid "" "Unlike static types, heap type objects are mutable by default. Use the :c:" "macro:`Py_TPFLAGS_IMMUTABLETYPE` flag to prevent mutability." msgstr "" #: ../../howto/isolating-extensions.rst:321 msgid "" "Heap types inherit :c:member:`~PyTypeObject.tp_new` by default, so it may " "become possible to instantiate them from Python code. You can prevent this " "with the :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag." msgstr "" #: ../../howto/isolating-extensions.rst:327 msgid "Defining Heap Types" msgstr "" #: ../../howto/isolating-extensions.rst:329 msgid "" "Heap types can be created by filling a :c:struct:`PyType_Spec` structure, a " "description or \"blueprint\" of a class, and calling :c:func:" "`PyType_FromModuleAndSpec` to construct a new class object." msgstr "" #: ../../howto/isolating-extensions.rst:334 msgid "" "Other functions, like :c:func:`PyType_FromSpec`, can also create heap types, " "but :c:func:`PyType_FromModuleAndSpec` associates the module with the class, " "allowing access to the module state from methods." msgstr "" #: ../../howto/isolating-extensions.rst:338 msgid "" "The class should generally be stored in *both* the module state (for safe " "access from C) and the module's ``__dict__`` (for access from Python code)." msgstr "" #: ../../howto/isolating-extensions.rst:344 msgid "Garbage-Collection Protocol" msgstr "" #: ../../howto/isolating-extensions.rst:346 msgid "" "Instances of heap types hold a reference to their type. This ensures that " "the type isn't destroyed before all its instances are, but may result in " "reference cycles that need to be broken by the garbage collector." msgstr "" #: ../../howto/isolating-extensions.rst:351 msgid "" "To avoid memory leaks, instances of heap types must implement the garbage " "collection protocol. That is, heap types should:" msgstr "" #: ../../howto/isolating-extensions.rst:355 msgid "Have the :c:macro:`Py_TPFLAGS_HAVE_GC` flag." msgstr "" #: ../../howto/isolating-extensions.rst:356 msgid "" "Define a traverse function using :c:data:`Py_tp_traverse`, which visits the " "type (e.g. using ``Py_VISIT(Py_TYPE(self))``)." msgstr "" #: ../../howto/isolating-extensions.rst:359 msgid "" "Please refer to the documentation of :c:macro:`Py_TPFLAGS_HAVE_GC` and :c:" "member:`~PyTypeObject.tp_traverse` for additional considerations." msgstr "" #: ../../howto/isolating-extensions.rst:363 msgid "" "The API for defining heap types grew organically, leaving it somewhat " "awkward to use in its current state. The following sections will guide you " "through common issues." msgstr "" #: ../../howto/isolating-extensions.rst:369 msgid "``tp_traverse`` in Python 3.8 and lower" msgstr "" #: ../../howto/isolating-extensions.rst:371 msgid "" "The requirement to visit the type from ``tp_traverse`` was added in Python " "3.9. If you support Python 3.8 and lower, the traverse function must *not* " "visit the type, so it must be more complicated::" msgstr "" #: ../../howto/isolating-extensions.rst:375 msgid "" "static int my_traverse(PyObject *self, visitproc visit, void *arg)\n" "{\n" " if (Py_Version >= 0x03090000) {\n" " Py_VISIT(Py_TYPE(self));\n" " }\n" " return 0;\n" "}" msgstr "" #: ../../howto/isolating-extensions.rst:383 msgid "" "Unfortunately, :c:data:`Py_Version` was only added in Python 3.11. As a " "replacement, use:" msgstr "" #: ../../howto/isolating-extensions.rst:386 msgid ":c:macro:`PY_VERSION_HEX`, if not using the stable ABI, or" msgstr "" #: ../../howto/isolating-extensions.rst:387 msgid "" ":py:data:`sys.version_info` (via :c:func:`PySys_GetObject` and :c:func:" "`PyArg_ParseTuple`)." msgstr "" #: ../../howto/isolating-extensions.rst:392 msgid "Delegating ``tp_traverse``" msgstr "" #: ../../howto/isolating-extensions.rst:394 msgid "" "If your traverse function delegates to the :c:member:`~PyTypeObject." "tp_traverse` of its base class (or another type), ensure that " "``Py_TYPE(self)`` is visited only once. Note that only heap type are " "expected to visit the type in ``tp_traverse``." msgstr "" #: ../../howto/isolating-extensions.rst:399 msgid "For example, if your traverse function includes::" msgstr "" #: ../../howto/isolating-extensions.rst:401 msgid "base->tp_traverse(self, visit, arg)" msgstr "" #: ../../howto/isolating-extensions.rst:403 msgid "...and ``base`` may be a static type, then it should also include::" msgstr "" #: ../../howto/isolating-extensions.rst:405 msgid "" "if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {\n" " // a heap type's tp_traverse already visited Py_TYPE(self)\n" "} else {\n" " if (Py_Version >= 0x03090000) {\n" " Py_VISIT(Py_TYPE(self));\n" " }\n" "}" msgstr "" #: ../../howto/isolating-extensions.rst:413 msgid "" "It is not necessary to handle the type's reference count in :c:member:" "`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_clear`." msgstr "" #: ../../howto/isolating-extensions.rst:418 msgid "Defining ``tp_dealloc``" msgstr "" #: ../../howto/isolating-extensions.rst:420 msgid "" "If your type has a custom :c:member:`~PyTypeObject.tp_dealloc` function, it " "needs to:" msgstr "" #: ../../howto/isolating-extensions.rst:423 msgid "" "call :c:func:`PyObject_GC_UnTrack` before any fields are invalidated, and" msgstr "" #: ../../howto/isolating-extensions.rst:424 msgid "decrement the reference count of the type." msgstr "" #: ../../howto/isolating-extensions.rst:426 msgid "" "To keep the type valid while ``tp_free`` is called, the type's refcount " "needs to be decremented *after* the instance is deallocated. For example::" msgstr "" #: ../../howto/isolating-extensions.rst:429 msgid "" "static void my_dealloc(PyObject *self)\n" "{\n" " PyObject_GC_UnTrack(self);\n" " ...\n" " PyTypeObject *type = Py_TYPE(self);\n" " type->tp_free(self);\n" " Py_DECREF(type);\n" "}" msgstr "" #: ../../howto/isolating-extensions.rst:438 msgid "" "The default ``tp_dealloc`` function does this, so if your type does *not* " "override ``tp_dealloc`` you don't need to add it." msgstr "" #: ../../howto/isolating-extensions.rst:444 msgid "Not overriding ``tp_free``" msgstr "" #: ../../howto/isolating-extensions.rst:446 msgid "" "The :c:member:`~PyTypeObject.tp_free` slot of a heap type must be set to :c:" "func:`PyObject_GC_Del`. This is the default; do not override it." msgstr "" #: ../../howto/isolating-extensions.rst:452 msgid "Avoiding ``PyObject_New``" msgstr "" #: ../../howto/isolating-extensions.rst:454 msgid "GC-tracked objects need to be allocated using GC-aware functions." msgstr "" #: ../../howto/isolating-extensions.rst:456 msgid "If you use :c:func:`PyObject_New` or :c:func:`PyObject_NewVar`:" msgstr "" #: ../../howto/isolating-extensions.rst:458 msgid "" "Get and call type's :c:member:`~PyTypeObject.tp_alloc` slot, if possible. " "That is, replace ``TYPE *o = PyObject_New(TYPE, typeobj)`` with::" msgstr "" #: ../../howto/isolating-extensions.rst:461 msgid "TYPE *o = typeobj->tp_alloc(typeobj, 0);" msgstr "" #: ../../howto/isolating-extensions.rst:463 msgid "" "Replace ``o = PyObject_NewVar(TYPE, typeobj, size)`` with the same, but use " "size instead of the 0." msgstr "" #: ../../howto/isolating-extensions.rst:466 msgid "" "If the above is not possible (e.g. inside a custom ``tp_alloc``), call :c:" "func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`::" msgstr "" #: ../../howto/isolating-extensions.rst:469 msgid "" "TYPE *o = PyObject_GC_New(TYPE, typeobj);\n" "\n" "TYPE *o = PyObject_GC_NewVar(TYPE, typeobj, size);" msgstr "" #: ../../howto/isolating-extensions.rst:475 msgid "Module State Access from Classes" msgstr "" #: ../../howto/isolating-extensions.rst:477 msgid "" "If you have a type object defined with :c:func:`PyType_FromModuleAndSpec`, " "you can call :c:func:`PyType_GetModule` to get the associated module, and " "then :c:func:`PyModule_GetState` to get the module's state." msgstr "" #: ../../howto/isolating-extensions.rst:481 msgid "" "To save a some tedious error-handling boilerplate code, you can combine " "these two steps with :c:func:`PyType_GetModuleState`, resulting in::" msgstr "" #: ../../howto/isolating-extensions.rst:484 msgid "" "my_struct *state = (my_struct*)PyType_GetModuleState(type);\n" "if (state == NULL) {\n" " return NULL;\n" "}" msgstr "" #: ../../howto/isolating-extensions.rst:491 msgid "Module State Access from Regular Methods" msgstr "" #: ../../howto/isolating-extensions.rst:493 msgid "" "Accessing the module-level state from methods of a class is somewhat more " "complicated, but is possible thanks to API introduced in Python 3.9. To get " "the state, you need to first get the *defining class*, and then get the " "module state from it." msgstr "" #: ../../howto/isolating-extensions.rst:498 msgid "" "The largest roadblock is getting *the class a method was defined in*, or " "that method's \"defining class\" for short. The defining class can have a " "reference to the module it is part of." msgstr "" #: ../../howto/isolating-extensions.rst:502 msgid "" "Do not confuse the defining class with ``Py_TYPE(self)``. If the method is " "called on a *subclass* of your type, ``Py_TYPE(self)`` will refer to that " "subclass, which may be defined in different module than yours." msgstr "" #: ../../howto/isolating-extensions.rst:507 msgid "" "The following Python code can illustrate the concept. ``Base." "get_defining_class`` returns ``Base`` even if ``type(self) == Sub``:" msgstr "" #: ../../howto/isolating-extensions.rst:511 msgid "" "class Base:\n" " def get_type_of_self(self):\n" " return type(self)\n" "\n" " def get_defining_class(self):\n" " return __class__\n" "\n" "class Sub(Base):\n" " pass" msgstr "" #: ../../howto/isolating-extensions.rst:523 msgid "" "For a method to get its \"defining class\", it must use the :ref:" "`METH_METHOD | METH_FASTCALL | METH_KEYWORDS ` :c:type:`calling convention ` and the " "corresponding :c:type:`PyCMethod` signature::" msgstr "" #: ../../howto/isolating-extensions.rst:528 msgid "" "PyObject *PyCMethod(\n" " PyObject *self, // object the method was called on\n" " PyTypeObject *defining_class, // defining class\n" " PyObject *const *args, // C array of arguments\n" " Py_ssize_t nargs, // length of \"args\"\n" " PyObject *kwnames) // NULL, or dict of keyword arguments" msgstr "" #: ../../howto/isolating-extensions.rst:535 msgid "" "Once you have the defining class, call :c:func:`PyType_GetModuleState` to " "get the state of its associated module." msgstr "" #: ../../howto/isolating-extensions.rst:538 msgid "For example::" msgstr "Zum Beispiel::" #: ../../howto/isolating-extensions.rst:540 msgid "" "static PyObject *\n" "example_method(PyObject *self,\n" " PyTypeObject *defining_class,\n" " PyObject *const *args,\n" " Py_ssize_t nargs,\n" " PyObject *kwnames)\n" "{\n" " my_struct *state = (my_struct*)PyType_GetModuleState(defining_class);\n" " if (state == NULL) {\n" " return NULL;\n" " }\n" " ... // rest of logic\n" "}\n" "\n" "PyDoc_STRVAR(example_method_doc, \"...\");\n" "\n" "static PyMethodDef my_methods[] = {\n" " {\"example_method\",\n" " (PyCFunction)(void(*)(void))example_method,\n" " METH_METHOD|METH_FASTCALL|METH_KEYWORDS,\n" " example_method_doc}\n" " {NULL},\n" "}" msgstr "" #: ../../howto/isolating-extensions.rst:566 msgid "Module State Access from Slot Methods, Getters and Setters" msgstr "" #: ../../howto/isolating-extensions.rst:570 msgid "This is new in Python 3.11." msgstr "" #: ../../howto/isolating-extensions.rst:578 msgid "" "Slot methods—the fast C equivalents for special methods, such as :c:member:" "`~PyNumberMethods.nb_add` for :py:attr:`~object.__add__` or :c:member:" "`~PyTypeObject.tp_new` for initialization—have a very simple API that " "doesn't allow passing in the defining class, unlike with :c:type:" "`PyCMethod`. The same goes for getters and setters defined with :c:type:" "`PyGetSetDef`." msgstr "" #: ../../howto/isolating-extensions.rst:585 msgid "" "To access the module state in these cases, use the :c:func:" "`PyType_GetModuleByDef` function, and pass in the module definition. Once " "you have the module, call :c:func:`PyModule_GetState` to get the state::" msgstr "" #: ../../howto/isolating-extensions.rst:590 msgid "" "PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &module_def);\n" "my_struct *state = (my_struct*)PyModule_GetState(module);\n" "if (state == NULL) {\n" " return NULL;\n" "}" msgstr "" #: ../../howto/isolating-extensions.rst:596 msgid "" ":c:func:`!PyType_GetModuleByDef` works by searching the :term:`method " "resolution order` (i.e. all superclasses) for the first superclass that has " "a corresponding module." msgstr "" #: ../../howto/isolating-extensions.rst:602 msgid "" "In very exotic cases (inheritance chains spanning multiple modules created " "from the same definition), :c:func:`!PyType_GetModuleByDef` might not return " "the module of the true defining class. However, it will always return a " "module with the same definition, ensuring a compatible C memory layout." msgstr "" #: ../../howto/isolating-extensions.rst:610 msgid "Lifetime of the Module State" msgstr "" #: ../../howto/isolating-extensions.rst:612 msgid "" "When a module object is garbage-collected, its module state is freed. For " "each pointer to (a part of) the module state, you must hold a reference to " "the module object." msgstr "" #: ../../howto/isolating-extensions.rst:616 msgid "" "Usually this is not an issue, because types created with :c:func:" "`PyType_FromModuleAndSpec`, and their instances, hold a reference to the " "module. However, you must be careful in reference counting when you " "reference module state from other places, such as callbacks for external " "libraries." msgstr "" #: ../../howto/isolating-extensions.rst:625 msgid "Open Issues" msgstr "" #: ../../howto/isolating-extensions.rst:627 msgid "Several issues around per-module state and heap types are still open." msgstr "" #: ../../howto/isolating-extensions.rst:629 msgid "" "Discussions about improving the situation are best held on the `discuss " "forum under c-api tag `__." msgstr "" #: ../../howto/isolating-extensions.rst:633 msgid "Per-Class Scope" msgstr "" #: ../../howto/isolating-extensions.rst:635 msgid "" "It is currently (as of Python 3.11) not possible to attach state to " "individual *types* without relying on CPython implementation details (which " "may change in the future—perhaps, ironically, to allow a proper solution for " "per-class scope)." msgstr "" #: ../../howto/isolating-extensions.rst:642 msgid "Lossless Conversion to Heap Types" msgstr "" #: ../../howto/isolating-extensions.rst:644 msgid "" "The heap type API was not designed for \"lossless\" conversion from static " "types; that is, creating a type that works exactly like a given static type." msgstr ""