# Copyright (C) 2001-2018, Python Software Foundation # For licence information, see README file. # msgid "" msgstr "" "Project-Id-Version: Python 3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-01-23 09:57+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: FRENCH \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: howto/isolating-extensions.rst:5 msgid "Isolating Extension Modules" msgstr "" #: howto/isolating-extensions.rst:-1 msgid "Abstract" msgstr "" #: howto/isolating-extensions.rst:9 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:14 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:21 msgid "Who should read this" msgstr "" #: howto/isolating-extensions.rst:23 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:29 msgid "Background" msgstr "" #: howto/isolating-extensions.rst:31 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:35 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:38 msgid "" "in sequence, with several :c:func:`Py_InitializeEx`/:c:func:`Py_FinalizeEx` " "cycles, and" msgstr "" #: howto/isolating-extensions.rst:40 msgid "" "in parallel, managing \"sub-interpreters\" using :c:func:" "`Py_NewInterpreter`/:c:func:`Py_EndInterpreter`." msgstr "" #: howto/isolating-extensions.rst:43 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:48 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:56 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:61 msgid "Enter Per-Module State" msgstr "" #: howto/isolating-extensions.rst:63 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 is 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:70 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:76 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:85 msgid "Isolated Module Objects" msgstr "" #: howto/isolating-extensions.rst:87 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:101 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:109 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:115 msgid "Surprising Edge Cases" msgstr "" #: howto/isolating-extensions.rst:117 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:137 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:140 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:146 msgid "Making Modules Safe with Multiple Interpreters" msgstr "" #: howto/isolating-extensions.rst:150 msgid "Managing Global State" msgstr "" #: howto/isolating-extensions.rst:152 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:156 msgid "The ``readline`` module manages *the* terminal." msgstr "" #: howto/isolating-extensions.rst:157 msgid "" "A module running on a circuit board wants to control *the* on-board LED." msgstr "" #: howto/isolating-extensions.rst:160 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:166 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 `Opt-Out: Limiting to One Module " "Object per Process`_." msgstr "" #: howto/isolating-extensions.rst:173 msgid "Managing Per-Module State" msgstr "" #: howto/isolating-extensions.rst:175 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:179 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:188 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:193 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:196 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:203 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:209 msgid "Opt-Out: Limiting to One Module Object per Process" msgstr "" #: howto/isolating-extensions.rst:211 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:232 msgid "Module State Access from Functions" msgstr "" #: howto/isolating-extensions.rst:234 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:249 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:256 msgid "Heap Types" msgstr "" #: howto/isolating-extensions.rst:258 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:262 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:268 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:275 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:282 msgid "For new modules, using heap types by default is a good rule of thumb." msgstr "" #: howto/isolating-extensions.rst:286 msgid "Changing Static Types to Heap Types" msgstr "" #: howto/isolating-extensions.rst:288 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:297 msgid "" "Watch out for the following two points in particular (but note that this is " "not a comprehensive list):" msgstr "" #: howto/isolating-extensions.rst:300 msgid "" "Unlike static types, heap type objects are mutable by default. Use the :c:" "data:`Py_TPFLAGS_IMMUTABLETYPE` flag to prevent mutability." msgstr "" #: howto/isolating-extensions.rst:302 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:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag." msgstr "" #: howto/isolating-extensions.rst:308 msgid "Defining Heap Types" msgstr "" #: howto/isolating-extensions.rst:310 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:315 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:319 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:325 msgid "Garbage-Collection Protocol" msgstr "" #: howto/isolating-extensions.rst:327 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:332 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:336 msgid "Have the :c:data:`Py_TPFLAGS_HAVE_GC` flag." msgstr "" #: howto/isolating-extensions.rst:337 msgid "" "Define a traverse function using ``Py_tp_traverse``, which visits the type " "(e.g. using :c:expr:`Py_VISIT(Py_TYPE(self))`)." msgstr "" #: howto/isolating-extensions.rst:340 msgid "" "Please refer to the :ref:`the documentation ` of :c:data:" "`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse` for " "additional considerations." msgstr "" #: howto/isolating-extensions.rst:344 msgid "" "If your traverse function delegates to the ``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:348 msgid "For example, if your traverse function includes::" msgstr "" #: howto/isolating-extensions.rst:352 msgid "...and ``base`` may be a static type, then it should also include::" msgstr "" #: howto/isolating-extensions.rst:360 msgid "" "It is not necessary to handle the type's reference count in ``tp_new`` and " "``tp_clear``." msgstr "" #: howto/isolating-extensions.rst:365 msgid "Module State Access from Classes" msgstr "" #: howto/isolating-extensions.rst:367 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:371 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:381 msgid "Module State Access from Regular Methods" msgstr "" #: howto/isolating-extensions.rst:383 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:388 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:392 msgid "" "Do not confuse the defining class with :c:expr:`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:397 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:413 msgid "" "For a method to get its \"defining class\", it must use the :data:" "`METH_METHOD | METH_FASTCALL | METH_KEYWORDS` :c:type:`calling convention " "` and the corresponding :c:type:`PyCMethod` signature::" msgstr "" #: howto/isolating-extensions.rst:425 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:428 msgid "For example::" msgstr "" #: howto/isolating-extensions.rst:456 msgid "Module State Access from Slot Methods, Getters and Setters" msgstr "" #: howto/isolating-extensions.rst:460 msgid "This is new in Python 3.11." msgstr "" #: howto/isolating-extensions.rst:468 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:" "`~PyType.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:475 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:486 msgid "" "``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:492 msgid "" "In very exotic cases (inheritance chains spanning multiple modules created " "from the same definition), ``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:500 msgid "Lifetime of the Module State" msgstr "" #: howto/isolating-extensions.rst:502 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:506 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:515 msgid "Open Issues" msgstr "" #: howto/isolating-extensions.rst:517 msgid "Several issues around per-module state and heap types are still open." msgstr "" #: howto/isolating-extensions.rst:519 msgid "" "Discussions about improving the situation are best held on the `capi-sig " "mailing list `__." msgstr "" #: howto/isolating-extensions.rst:524 msgid "Per-Class Scope" msgstr "" #: howto/isolating-extensions.rst:526 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:533 msgid "Lossless Conversion to Heap Types" msgstr "" #: howto/isolating-extensions.rst:535 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 ""