1
0
Fork 0
python-docs-fr/extending/newtypes_tutorial.po

963 lines
39 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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-15 22:33+0100\n"
"PO-Revision-Date: 2022-10-18 12:22+0200\n"
"Last-Translator: Julien Palard <julien@palard.fr>\n"
"Language-Team: FRENCH <traductions@lists.afpy.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: extending/newtypes_tutorial.rst:7
msgid "Defining Extension Types: Tutorial"
msgstr "Tutoriel : définir des types dans des extensions"
#: extending/newtypes_tutorial.rst:14
msgid ""
"Python allows the writer of a C extension module to define new types that "
"can be manipulated from Python code, much like the built-in :class:`str` "
"and :class:`list` types. The code for all extension types follows a "
"pattern, but there are some details that you need to understand before you "
"can get started. This document is a gentle introduction to the topic."
msgstr ""
"Python permet à l'auteur d'un module d'extension C de définir de nouveaux "
"types qui peuvent être manipulés depuis du code Python, à la manière des "
"types natifs :class:`str` et :class:`list`. Les implémentations de tous les "
"types d'extension ont des similarités, mais quelques subtilités doivent être "
"abordées avant de commencer."
#: extending/newtypes_tutorial.rst:24
msgid "The Basics"
msgstr "Les bases"
#: extending/newtypes_tutorial.rst:26
#, fuzzy
msgid ""
"The :term:`CPython` runtime sees all Python objects as variables of type :c:"
"expr:`PyObject*`, which serves as a \"base type\" for all Python objects. "
"The :c:type:`PyObject` structure itself only contains the object's :term:"
"`reference count` and a pointer to the object's \"type object\". This is "
"where the action is; the type object determines which (C) functions get "
"called by the interpreter when, for instance, an attribute gets looked up on "
"an object, a method called, or it is multiplied by another object. These C "
"functions are called \"type methods\"."
msgstr ""
":term:`CPython` considère que tous les objets Python sont des variables de "
"type :c:type:`PyObject\\*`, qui sert de type de base pour tous les objets "
"Python. La structure de :c:type:`PyObject` ne contient que le :term:"
"`compteur de références <reference count>` et un pointeur vers un objet de "
"type « type de l'objet ». C'est ici que tout se joue : l'objet type "
"détermine quelle fonction C doit être appelée par l'interpréteur quand, par "
"exemple, un attribut est recherché sur un objet, quand une méthode est "
"appelée, ou quand l'objet est multiplié par un autre objet. Ces fonctions C "
"sont appelées des « méthodes de type »."
#: extending/newtypes_tutorial.rst:35
msgid ""
"So, if you want to define a new extension type, you need to create a new "
"type object."
msgstr ""
"Donc, pour définir un nouveau type dans une extension, vous devez créer un "
"nouvel objet type."
#: extending/newtypes_tutorial.rst:38
msgid ""
"This sort of thing can only be explained by example, so here's a minimal, "
"but complete, module that defines a new type named :class:`Custom` inside a "
"C extension module :mod:`custom`:"
msgstr ""
"Ce genre de chose ne s'explique correctement qu'avec des exemples, voici "
"donc un module minimaliste mais suffisant qui définit un nouveau type nommé :"
"class:`Custom` dans le module d'extension :mod:`custom` :"
#: extending/newtypes_tutorial.rst:43
msgid ""
"What we're showing here is the traditional way of defining *static* "
"extension types. It should be adequate for most uses. The C API also "
"allows defining heap-allocated extension types using the :c:func:"
"`PyType_FromSpec` function, which isn't covered in this tutorial."
msgstr ""
"Ce qui est montré ici est la manière traditionnelle de définir des types "
"d'extension *statiques*, et cela convient dans la majorité des cas. L'API C "
"permet aussi de définir des types alloués sur le tas, via la fonction :c:"
"func:`PyType_FromSpec`, mais ce n'est pas couvert par ce tutoriel."
#: extending/newtypes_tutorial.rst:50
msgid ""
"Now that's quite a bit to take in at once, but hopefully bits will seem "
"familiar from the previous chapter. This file defines three things:"
msgstr ""
"C'est un peu long, mais vous devez déjà reconnaître quelques morceaux "
"expliqués au chapitre précédent. Ce fichier définit trois choses :"
#: extending/newtypes_tutorial.rst:53
msgid ""
"What a :class:`Custom` **object** contains: this is the ``CustomObject`` "
"struct, which is allocated once for each :class:`Custom` instance."
msgstr ""
"Ce qu'un **objet** :class:`Custom` contient : c'est la structure "
"``CustomObject``, qui est allouée une fois pour chaque instance de :class:"
"`Custom`."
#: extending/newtypes_tutorial.rst:55
msgid ""
"How the :class:`Custom` **type** behaves: this is the ``CustomType`` struct, "
"which defines a set of flags and function pointers that the interpreter "
"inspects when specific operations are requested."
msgstr ""
"Comment le **type** :class:`Custom` se comporte : c'est la structure "
"``CustomType``, qui définit l'ensemble des options et pointeurs de fonction "
"utilisés par l'interpréteur."
#: extending/newtypes_tutorial.rst:58
msgid ""
"How to initialize the :mod:`custom` module: this is the ``PyInit_custom`` "
"function and the associated ``custommodule`` struct."
msgstr ""
"Comment initialiser le module :mod:`custom` : c'est la fonction "
"``PyInit_custom`` et la structure associée ``custommodule``."
#: extending/newtypes_tutorial.rst:61
msgid "The first bit is::"
msgstr "Commençons par ::"
#: extending/newtypes_tutorial.rst:67
#, fuzzy
msgid ""
"This is what a Custom object will contain. ``PyObject_HEAD`` is mandatory "
"at the start of each object struct and defines a field called ``ob_base`` of "
"type :c:type:`PyObject`, containing a pointer to a type object and a "
"reference count (these can be accessed using the macros :c:macro:`Py_TYPE` "
"and :c:macro:`Py_REFCNT` respectively). The reason for the macro is to "
"abstract away the layout and to enable additional fields in :ref:`debug "
"builds <debug-build>`."
msgstr ""
"C'est ce qu'un objet ``Custom`` contient. ``PyObject_HEAD`` est "
"obligatoirement au début de chaque structure d'objet et définit un champ "
"appelé ``ob_base`` de type :c:type:`PyObject`, contenant un pointeur vers un "
"objet type et un compteur de références (on peut y accéder en utilisant les "
"macros :c:macro:`Py_TYPE` et :c:macro:`Py_REFCNT`, respectivement). La "
"raison d'être de ces macros est d'abstraire l'agencement de la structure, et "
"ainsi de permettre l'ajout de champs en :ref:`mode débogage <debug-build>`."
#: extending/newtypes_tutorial.rst:76
msgid ""
"There is no semicolon above after the :c:macro:`PyObject_HEAD` macro. Be "
"wary of adding one by accident: some compilers will complain."
msgstr ""
"Il n'y a pas de point-virgule après la macro :c:macro:`PyObject_HEAD`. "
"Attention à ne pas l'ajouter par accident : certains compilateurs pourraient "
"s'en plaindre."
#: extending/newtypes_tutorial.rst:79
msgid ""
"Of course, objects generally store additional data besides the standard "
"``PyObject_HEAD`` boilerplate; for example, here is the definition for "
"standard Python floats::"
msgstr ""
"Bien sûr, les objets ajoutent généralement des données supplémentaires après "
"l'entête standard ``PyObject_HEAD``. Par exemple voici la définition du type "
"standard Python ``float`` ::"
#: extending/newtypes_tutorial.rst:88
msgid "The second bit is the definition of the type object. ::"
msgstr "La deuxième partie est la définition de l'objet type ::"
#: extending/newtypes_tutorial.rst:101
msgid ""
"We recommend using C99-style designated initializers as above, to avoid "
"listing all the :c:type:`PyTypeObject` fields that you don't care about and "
"also to avoid caring about the fields' declaration order."
msgstr ""
"Nous recommandons d'utiliser la syntaxe d'initialisation nommée (C99) pour "
"remplir la structure, comme ci-dessus, afin d'éviter d'avoir à lister les "
"champs de :c:type:`PyTypeObject` dont vous n'avez pas besoin, et de ne pas "
"vous soucier de leur ordre."
#: extending/newtypes_tutorial.rst:105
msgid ""
"The actual definition of :c:type:`PyTypeObject` in :file:`object.h` has many "
"more :ref:`fields <type-structs>` than the definition above. The remaining "
"fields will be filled with zeros by the C compiler, and it's common practice "
"to not specify them explicitly unless you need them."
msgstr ""
"La définition de :c:type:`PyTypeObject` dans :file:`object.h` contient en "
"fait bien plus de :ref:`champs <type-structs>` que la définition ci-dessus. "
"Les champs restants sont mis à zéro par le compilateur C, et c'est une "
"pratique répandue de ne pas spécifier les champs dont vous n'avez pas besoin."
#: extending/newtypes_tutorial.rst:110
msgid "We're going to pick it apart, one field at a time::"
msgstr "Regardons les champs de cette structure, un par un ::"
#: extending/newtypes_tutorial.rst:114
msgid ""
"This line is mandatory boilerplate to initialize the ``ob_base`` field "
"mentioned above. ::"
msgstr ""
"Cette ligne, obligatoire, initialise le champ ``ob_base`` mentionné "
"précédemment. ::"
#: extending/newtypes_tutorial.rst:119
msgid ""
"The name of our type. This will appear in the default textual "
"representation of our objects and in some error messages, for example:"
msgstr ""
"C'est le nom de notre type. Il apparaît dans la représentation textuelle par "
"défaut de nos objets, ainsi que dans quelques messages d'erreur, par "
"exemple :"
#: extending/newtypes_tutorial.rst:129
msgid ""
"Note that the name is a dotted name that includes both the module name and "
"the name of the type within the module. The module in this case is :mod:"
"`custom` and the type is :class:`Custom`, so we set the type name to :class:"
"`custom.Custom`. Using the real dotted import path is important to make your "
"type compatible with the :mod:`pydoc` and :mod:`pickle` modules. ::"
msgstr ""
"Notez que le nom comporte un point : il inclut le nom du module et le nom du "
"type. Dans ce cas le module est :mod:`custom`, et le type est :class:"
"`Custom`, donc nous donnons comme nom :class:`custom.Custom`. Nommer "
"correctement son type, avec le point, est important pour le rendre "
"compatible avec :mod:`pydoc` et :mod:`pickle`. ::"
#: extending/newtypes_tutorial.rst:138
msgid ""
"This is so that Python knows how much memory to allocate when creating new :"
"class:`Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is only "
"used for variable-sized objects and should otherwise be zero."
msgstr ""
"C'est pour que Python sache combien de mémoire allouer à la création d'une "
"nouvelle instance de :class:`Custom`. :c:member:`~PyTypeObject.tp_itemsize` "
"n'est utilisé que pour les objets de taille variable, sinon il doit rester à "
"zéro."
#: extending/newtypes_tutorial.rst:144
msgid ""
"If you want your type to be subclassable from Python, and your type has the "
"same :c:member:`~PyTypeObject.tp_basicsize` as its base type, you may have "
"problems with multiple inheritance. A Python subclass of your type will "
"have to list your type first in its :attr:`~class.__bases__`, or else it "
"will not be able to call your type's :meth:`__new__` method without getting "
"an error. You can avoid this problem by ensuring that your type has a "
"larger value for :c:member:`~PyTypeObject.tp_basicsize` than its base type "
"does. Most of the time, this will be true anyway, because either your base "
"type will be :class:`object`, or else you will be adding data members to "
"your base type, and therefore increasing its size."
msgstr ""
"Si vous voulez qu'une classe en Python puisse hériter de votre type, et que "
"votre type a le même :c:member:`~PyTypeObject.tp_basicsize` que son parent, "
"vous rencontrerez des problèmes avec l'héritage multiple. Une sous-classe "
"Python de votre type devra lister votre type en premier dans son :attr:"
"`~class.__bases__`, sans quoi elle ne sera pas capable d'appeler la méthode :"
"meth:`__new__` de votre type sans erreur. Vous pouvez éviter ce problème en "
"vous assurant que votre type a un :c:member:`~PyTypeObject.tp_basicsize` "
"plus grand que son parent. La plupart du temps ce sera vrai (soit son parent "
"sera :class:`object`, soit vous ajouterez des attributs à votre type, "
"augmentant ainsi sa taille)."
#: extending/newtypes_tutorial.rst:154
msgid "We set the class flags to :const:`Py_TPFLAGS_DEFAULT`. ::"
msgstr ""
"On utilise la constante :const:`Py_TPFLAGS_DEFAULT` comme seule option de "
"type. ::"
#: extending/newtypes_tutorial.rst:158
msgid ""
"All types should include this constant in their flags. It enables all of "
"the members defined until at least Python 3.3. If you need further members, "
"you will need to OR the corresponding flags."
msgstr ""
"Chaque type doit inclure cette constante dans ses options : elle active tous "
"les membres définis jusqu'à au moins Python 3.3. Si vous avez besoin de plus "
"de membres, vous pouvez la combiner à d'autres constantes avec un *ou* "
"binaire."
#: extending/newtypes_tutorial.rst:162
msgid ""
"We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. ::"
msgstr ""
"On fournit une *docstring* pour ce type via le membre :c:member:"
"`~PyTypeObject.tp_doc`. ::"
#: extending/newtypes_tutorial.rst:166
msgid ""
"To enable object creation, we have to provide a :c:member:`~PyTypeObject."
"tp_new` handler. This is the equivalent of the Python method :meth:"
"`__new__`, but has to be specified explicitly. In this case, we can just "
"use the default implementation provided by the API function :c:func:"
"`PyType_GenericNew`. ::"
msgstr ""
"Pour permettre la création d'une instance, nous devons fournir un *handler* :"
"c:member:`~PyTypeObject.tp_new`, qui est l'équivalent de la méthode Python :"
"meth:`__new__`, mais elle a besoin d'être spécifiée explicitement. Dans ce "
"cas, on se contente de l'implémentation par défaut fournie par la fonction :"
"c:func:`PyType_GenericNew` de l'API. ::"
#: extending/newtypes_tutorial.rst:173
msgid ""
"Everything else in the file should be familiar, except for some code in :c:"
"func:`PyInit_custom`::"
msgstr ""
"Le reste du fichier doit vous être familier, en dehors du code de :c:func:"
"`PyInit_custom` ::"
#: extending/newtypes_tutorial.rst:179
msgid ""
"This initializes the :class:`Custom` type, filling in a number of members to "
"the appropriate default values, including :attr:`ob_type` that we initially "
"set to ``NULL``. ::"
msgstr ""
"Il initialise le type :class:`Custom`, en assignant quelques membres à leurs "
"valeurs par défaut, tel que :attr:`ob_type` qui valait initialement "
"``NULL``. ::"
#: extending/newtypes_tutorial.rst:190
msgid ""
"This adds the type to the module dictionary. This allows us to create :"
"class:`Custom` instances by calling the :class:`Custom` class:"
msgstr ""
"Ici on ajoute le type au dictionnaire du module. Cela permet de créer une "
"instance de :class:`Custom` en appelant la classe :class:`Custom` :"
#: extending/newtypes_tutorial.rst:198
msgid ""
"That's it! All that remains is to build it; put the above code in a file "
"called :file:`custom.c` and:"
msgstr ""
"C'est tout ! Il ne reste plus qu'à compiler, placez le code ci-dessus dans "
"un fichier :file:`custom.c` et :"
#: extending/newtypes_tutorial.rst:207
msgid "in a file called :file:`setup.py`; then typing"
msgstr ""
#: extending/newtypes_tutorial.rst:213
msgid ""
"at a shell should produce a file :file:`custom.so` in a subdirectory; move "
"to that directory and fire up Python --- you should be able to ``import "
"custom`` and play around with Custom objects."
msgstr ""
#: extending/newtypes_tutorial.rst:217
msgid "That wasn't so hard, was it?"
msgstr ""
#: extending/newtypes_tutorial.rst:219
msgid ""
"Of course, the current Custom type is pretty uninteresting. It has no data "
"and doesn't do anything. It can't even be subclassed."
msgstr ""
#: extending/newtypes_tutorial.rst:223
msgid ""
"While this documentation showcases the standard :mod:`distutils` module for "
"building C extensions, it is recommended in real-world use cases to use the "
"newer and better-maintained ``setuptools`` library. Documentation on how to "
"do this is out of scope for this document and can be found in the `Python "
"Packaging User's Guide <https://packaging.python.org/tutorials/distributing-"
"packages/>`_."
msgstr ""
#: extending/newtypes_tutorial.rst:231
msgid "Adding data and methods to the Basic example"
msgstr ""
#: extending/newtypes_tutorial.rst:233
msgid ""
"Let's extend the basic example to add some data and methods. Let's also "
"make the type usable as a base class. We'll create a new module, :mod:"
"`custom2` that adds these capabilities:"
msgstr ""
#: extending/newtypes_tutorial.rst:240
msgid "This version of the module has a number of changes."
msgstr ""
#: extending/newtypes_tutorial.rst:242
msgid "We've added an extra include::"
msgstr ""
#: extending/newtypes_tutorial.rst:246
msgid ""
"This include provides declarations that we use to handle attributes, as "
"described a bit later."
msgstr ""
#: extending/newtypes_tutorial.rst:249
msgid ""
"The :class:`Custom` type now has three data attributes in its C struct, "
"*first*, *last*, and *number*. The *first* and *last* variables are Python "
"strings containing first and last names. The *number* attribute is a C "
"integer."
msgstr ""
#: extending/newtypes_tutorial.rst:253
msgid "The object structure is updated accordingly::"
msgstr ""
#: extending/newtypes_tutorial.rst:262
msgid ""
"Because we now have data to manage, we have to be more careful about object "
"allocation and deallocation. At a minimum, we need a deallocation method::"
msgstr ""
#: extending/newtypes_tutorial.rst:273
msgid "which is assigned to the :c:member:`~PyTypeObject.tp_dealloc` member::"
msgstr ""
#: extending/newtypes_tutorial.rst:277
msgid ""
"This method first clears the reference counts of the two Python attributes. :"
"c:func:`Py_XDECREF` correctly handles the case where its argument is "
"``NULL`` (which might happen here if ``tp_new`` failed midway). It then "
"calls the :c:member:`~PyTypeObject.tp_free` member of the object's type "
"(computed by ``Py_TYPE(self)``) to free the object's memory. Note that the "
"object's type might not be :class:`CustomType`, because the object may be an "
"instance of a subclass."
msgstr ""
#: extending/newtypes_tutorial.rst:286
msgid ""
"The explicit cast to ``destructor`` above is needed because we defined "
"``Custom_dealloc`` to take a ``CustomObject *`` argument, but the "
"``tp_dealloc`` function pointer expects to receive a ``PyObject *`` "
"argument. Otherwise, the compiler will emit a warning. This is object-"
"oriented polymorphism, in C!"
msgstr ""
#: extending/newtypes_tutorial.rst:292
msgid ""
"We want to make sure that the first and last names are initialized to empty "
"strings, so we provide a ``tp_new`` implementation::"
msgstr ""
#: extending/newtypes_tutorial.rst:316
msgid "and install it in the :c:member:`~PyTypeObject.tp_new` member::"
msgstr ""
#: extending/newtypes_tutorial.rst:320
msgid ""
"The ``tp_new`` handler is responsible for creating (as opposed to "
"initializing) objects of the type. It is exposed in Python as the :meth:"
"`__new__` method. It is not required to define a ``tp_new`` member, and "
"indeed many extension types will simply reuse :c:func:`PyType_GenericNew` as "
"done in the first version of the ``Custom`` type above. In this case, we "
"use the ``tp_new`` handler to initialize the ``first`` and ``last`` "
"attributes to non-``NULL`` default values."
msgstr ""
#: extending/newtypes_tutorial.rst:328
msgid ""
"``tp_new`` is passed the type being instantiated (not necessarily "
"``CustomType``, if a subclass is instantiated) and any arguments passed when "
"the type was called, and is expected to return the instance created. "
"``tp_new`` handlers always accept positional and keyword arguments, but they "
"often ignore the arguments, leaving the argument handling to initializer (a."
"k.a. ``tp_init`` in C or ``__init__`` in Python) methods."
msgstr ""
#: extending/newtypes_tutorial.rst:336
msgid ""
"``tp_new`` shouldn't call ``tp_init`` explicitly, as the interpreter will do "
"it itself."
msgstr ""
#: extending/newtypes_tutorial.rst:339
msgid ""
"The ``tp_new`` implementation calls the :c:member:`~PyTypeObject.tp_alloc` "
"slot to allocate memory::"
msgstr ""
#: extending/newtypes_tutorial.rst:344
msgid ""
"Since memory allocation may fail, we must check the :c:member:`~PyTypeObject."
"tp_alloc` result against ``NULL`` before proceeding."
msgstr ""
#: extending/newtypes_tutorial.rst:348
msgid ""
"We didn't fill the :c:member:`~PyTypeObject.tp_alloc` slot ourselves. "
"Rather :c:func:`PyType_Ready` fills it for us by inheriting it from our base "
"class, which is :class:`object` by default. Most types use the default "
"allocation strategy."
msgstr ""
#: extending/newtypes_tutorial.rst:354
msgid ""
"If you are creating a co-operative :c:member:`~PyTypeObject.tp_new` (one "
"that calls a base type's :c:member:`~PyTypeObject.tp_new` or :meth:"
"`__new__`), you must *not* try to determine what method to call using method "
"resolution order at runtime. Always statically determine what type you are "
"going to call, and call its :c:member:`~PyTypeObject.tp_new` directly, or "
"via ``type->tp_base->tp_new``. If you do not do this, Python subclasses of "
"your type that also inherit from other Python-defined classes may not work "
"correctly. (Specifically, you may not be able to create instances of such "
"subclasses without getting a :exc:`TypeError`.)"
msgstr ""
#: extending/newtypes_tutorial.rst:364
msgid ""
"We also define an initialization function which accepts arguments to provide "
"initial values for our instance::"
msgstr ""
#: extending/newtypes_tutorial.rst:393
msgid "by filling the :c:member:`~PyTypeObject.tp_init` slot. ::"
msgstr ""
#: extending/newtypes_tutorial.rst:397
msgid ""
"The :c:member:`~PyTypeObject.tp_init` slot is exposed in Python as the :meth:"
"`__init__` method. It is used to initialize an object after it's created. "
"Initializers always accept positional and keyword arguments, and they should "
"return either ``0`` on success or ``-1`` on error."
msgstr ""
#: extending/newtypes_tutorial.rst:402
msgid ""
"Unlike the ``tp_new`` handler, there is no guarantee that ``tp_init`` is "
"called at all (for example, the :mod:`pickle` module by default doesn't "
"call :meth:`__init__` on unpickled instances). It can also be called "
"multiple times. Anyone can call the :meth:`__init__` method on our "
"objects. For this reason, we have to be extra careful when assigning the "
"new attribute values. We might be tempted, for example to assign the "
"``first`` member like this::"
msgstr ""
#: extending/newtypes_tutorial.rst:416
msgid ""
"But this would be risky. Our type doesn't restrict the type of the "
"``first`` member, so it could be any kind of object. It could have a "
"destructor that causes code to be executed that tries to access the "
"``first`` member; or that destructor could release the :term:`Global "
"interpreter Lock <GIL>` and let arbitrary code run in other threads that "
"accesses and modifies our object."
msgstr ""
#: extending/newtypes_tutorial.rst:423
msgid ""
"To be paranoid and protect ourselves against this possibility, we almost "
"always reassign members before decrementing their reference counts. When "
"don't we have to do this?"
msgstr ""
#: extending/newtypes_tutorial.rst:427
msgid "when we absolutely know that the reference count is greater than 1;"
msgstr ""
#: extending/newtypes_tutorial.rst:429
msgid ""
"when we know that deallocation of the object [#]_ will neither release the :"
"term:`GIL` nor cause any calls back into our type's code;"
msgstr ""
#: extending/newtypes_tutorial.rst:432
msgid ""
"when decrementing a reference count in a :c:member:`~PyTypeObject."
"tp_dealloc` handler on a type which doesn't support cyclic garbage "
"collection [#]_."
msgstr ""
#: extending/newtypes_tutorial.rst:435
msgid ""
"We want to expose our instance variables as attributes. There are a number "
"of ways to do that. The simplest way is to define member definitions::"
msgstr ""
#: extending/newtypes_tutorial.rst:448
msgid ""
"and put the definitions in the :c:member:`~PyTypeObject.tp_members` slot::"
msgstr ""
#: extending/newtypes_tutorial.rst:452
msgid ""
"Each member definition has a member name, type, offset, access flags and "
"documentation string. See the :ref:`Generic-Attribute-Management` section "
"below for details."
msgstr ""
#: extending/newtypes_tutorial.rst:456
msgid ""
"A disadvantage of this approach is that it doesn't provide a way to restrict "
"the types of objects that can be assigned to the Python attributes. We "
"expect the first and last names to be strings, but any Python objects can be "
"assigned. Further, the attributes can be deleted, setting the C pointers to "
"``NULL``. Even though we can make sure the members are initialized to non-"
"``NULL`` values, the members can be set to ``NULL`` if the attributes are "
"deleted."
msgstr ""
#: extending/newtypes_tutorial.rst:463
msgid ""
"We define a single method, :meth:`Custom.name()`, that outputs the objects "
"name as the concatenation of the first and last names. ::"
msgstr ""
#: extending/newtypes_tutorial.rst:480
msgid ""
"The method is implemented as a C function that takes a :class:`Custom` (or :"
"class:`Custom` subclass) instance as the first argument. Methods always "
"take an instance as the first argument. Methods often take positional and "
"keyword arguments as well, but in this case we don't take any and don't need "
"to accept a positional argument tuple or keyword argument dictionary. This "
"method is equivalent to the Python method:"
msgstr ""
#: extending/newtypes_tutorial.rst:492
msgid ""
"Note that we have to check for the possibility that our :attr:`first` and :"
"attr:`last` members are ``NULL``. This is because they can be deleted, in "
"which case they are set to ``NULL``. It would be better to prevent deletion "
"of these attributes and to restrict the attribute values to be strings. "
"We'll see how to do that in the next section."
msgstr ""
#: extending/newtypes_tutorial.rst:498
msgid ""
"Now that we've defined the method, we need to create an array of method "
"definitions::"
msgstr ""
#: extending/newtypes_tutorial.rst:508
msgid ""
"(note that we used the :const:`METH_NOARGS` flag to indicate that the method "
"is expecting no arguments other than *self*)"
msgstr ""
#: extending/newtypes_tutorial.rst:511
msgid "and assign it to the :c:member:`~PyTypeObject.tp_methods` slot::"
msgstr ""
#: extending/newtypes_tutorial.rst:515
msgid ""
"Finally, we'll make our type usable as a base class for subclassing. We've "
"written our methods carefully so far so that they don't make any assumptions "
"about the type of the object being created or used, so all we need to do is "
"to add the :const:`Py_TPFLAGS_BASETYPE` to our class flag definition::"
msgstr ""
#: extending/newtypes_tutorial.rst:522
msgid ""
"We rename :c:func:`PyInit_custom` to :c:func:`PyInit_custom2`, update the "
"module name in the :c:type:`PyModuleDef` struct, and update the full class "
"name in the :c:type:`PyTypeObject` struct."
msgstr ""
#: extending/newtypes_tutorial.rst:526
msgid "Finally, we update our :file:`setup.py` file to build the new module:"
msgstr ""
#: extending/newtypes_tutorial.rst:539
msgid "Providing finer control over data attributes"
msgstr ""
#: extending/newtypes_tutorial.rst:541
msgid ""
"In this section, we'll provide finer control over how the :attr:`first` and :"
"attr:`last` attributes are set in the :class:`Custom` example. In the "
"previous version of our module, the instance variables :attr:`first` and :"
"attr:`last` could be set to non-string values or even deleted. We want to "
"make sure that these attributes always contain strings."
msgstr ""
#: extending/newtypes_tutorial.rst:550
msgid ""
"To provide greater control, over the :attr:`first` and :attr:`last` "
"attributes, we'll use custom getter and setter functions. Here are the "
"functions for getting and setting the :attr:`first` attribute::"
msgstr ""
#: extending/newtypes_tutorial.rst:581
msgid ""
"The getter function is passed a :class:`Custom` object and a \"closure\", "
"which is a void pointer. In this case, the closure is ignored. (The "
"closure supports an advanced usage in which definition data is passed to the "
"getter and setter. This could, for example, be used to allow a single set of "
"getter and setter functions that decide the attribute to get or set based on "
"data in the closure.)"
msgstr ""
#: extending/newtypes_tutorial.rst:587
msgid ""
"The setter function is passed the :class:`Custom` object, the new value, and "
"the closure. The new value may be ``NULL``, in which case the attribute is "
"being deleted. In our setter, we raise an error if the attribute is deleted "
"or if its new value is not a string."
msgstr ""
#: extending/newtypes_tutorial.rst:592
msgid "We create an array of :c:type:`PyGetSetDef` structures::"
msgstr ""
#: extending/newtypes_tutorial.rst:602
msgid "and register it in the :c:member:`~PyTypeObject.tp_getset` slot::"
msgstr ""
#: extending/newtypes_tutorial.rst:606
msgid ""
"The last item in a :c:type:`PyGetSetDef` structure is the \"closure\" "
"mentioned above. In this case, we aren't using a closure, so we just pass "
"``NULL``."
msgstr ""
#: extending/newtypes_tutorial.rst:609
msgid "We also remove the member definitions for these attributes::"
msgstr ""
#: extending/newtypes_tutorial.rst:617
msgid ""
"We also need to update the :c:member:`~PyTypeObject.tp_init` handler to only "
"allow strings [#]_ to be passed::"
msgstr ""
#: extending/newtypes_tutorial.rst:646
msgid ""
"With these changes, we can assure that the ``first`` and ``last`` members "
"are never ``NULL`` so we can remove checks for ``NULL`` values in almost all "
"cases. This means that most of the :c:func:`Py_XDECREF` calls can be "
"converted to :c:func:`Py_DECREF` calls. The only place we can't change "
"these calls is in the ``tp_dealloc`` implementation, where there is the "
"possibility that the initialization of these members failed in ``tp_new``."
msgstr ""
#: extending/newtypes_tutorial.rst:653
msgid ""
"We also rename the module initialization function and module name in the "
"initialization function, as we did before, and we add an extra definition to "
"the :file:`setup.py` file."
msgstr ""
#: extending/newtypes_tutorial.rst:659
msgid "Supporting cyclic garbage collection"
msgstr ""
#: extending/newtypes_tutorial.rst:661
msgid ""
"Python has a :term:`cyclic garbage collector (GC) <garbage collection>` that "
"can identify unneeded objects even when their reference counts are not zero. "
"This can happen when objects are involved in cycles. For example, consider:"
msgstr ""
#: extending/newtypes_tutorial.rst:671
msgid ""
"In this example, we create a list that contains itself. When we delete it, "
"it still has a reference from itself. Its reference count doesn't drop to "
"zero. Fortunately, Python's cyclic garbage collector will eventually figure "
"out that the list is garbage and free it."
msgstr ""
#: extending/newtypes_tutorial.rst:676
msgid ""
"In the second version of the :class:`Custom` example, we allowed any kind of "
"object to be stored in the :attr:`first` or :attr:`last` attributes [#]_. "
"Besides, in the second and third versions, we allowed subclassing :class:"
"`Custom`, and subclasses may add arbitrary attributes. For any of those two "
"reasons, :class:`Custom` objects can participate in cycles:"
msgstr ""
#: extending/newtypes_tutorial.rst:690
msgid ""
"To allow a :class:`Custom` instance participating in a reference cycle to be "
"properly detected and collected by the cyclic GC, our :class:`Custom` type "
"needs to fill two additional slots and to enable a flag that enables these "
"slots:"
msgstr ""
#: extending/newtypes_tutorial.rst:697
msgid ""
"First, the traversal method lets the cyclic GC know about subobjects that "
"could participate in cycles::"
msgstr ""
#: extending/newtypes_tutorial.rst:717
msgid ""
"For each subobject that can participate in cycles, we need to call the :c:"
"func:`visit` function, which is passed to the traversal method. The :c:func:"
"`visit` function takes as arguments the subobject and the extra argument "
"*arg* passed to the traversal method. It returns an integer value that must "
"be returned if it is non-zero."
msgstr ""
#: extending/newtypes_tutorial.rst:723
msgid ""
"Python provides a :c:func:`Py_VISIT` macro that automates calling visit "
"functions. With :c:func:`Py_VISIT`, we can minimize the amount of "
"boilerplate in ``Custom_traverse``::"
msgstr ""
#: extending/newtypes_tutorial.rst:736
msgid ""
"The :c:member:`~PyTypeObject.tp_traverse` implementation must name its "
"arguments exactly *visit* and *arg* in order to use :c:func:`Py_VISIT`."
msgstr ""
#: extending/newtypes_tutorial.rst:739
msgid ""
"Second, we need to provide a method for clearing any subobjects that can "
"participate in cycles::"
msgstr ""
#: extending/newtypes_tutorial.rst:750
msgid ""
"Notice the use of the :c:func:`Py_CLEAR` macro. It is the recommended and "
"safe way to clear data attributes of arbitrary types while decrementing "
"their reference counts. If you were to call :c:func:`Py_XDECREF` instead on "
"the attribute before setting it to ``NULL``, there is a possibility that the "
"attribute's destructor would call back into code that reads the attribute "
"again (*especially* if there is a reference cycle)."
msgstr ""
#: extending/newtypes_tutorial.rst:758
msgid "You could emulate :c:func:`Py_CLEAR` by writing::"
msgstr ""
#: extending/newtypes_tutorial.rst:765
msgid ""
"Nevertheless, it is much easier and less error-prone to always use :c:func:"
"`Py_CLEAR` when deleting an attribute. Don't try to micro-optimize at the "
"expense of robustness!"
msgstr ""
#: extending/newtypes_tutorial.rst:769
msgid ""
"The deallocator ``Custom_dealloc`` may call arbitrary code when clearing "
"attributes. It means the circular GC can be triggered inside the function. "
"Since the GC assumes reference count is not zero, we need to untrack the "
"object from the GC by calling :c:func:`PyObject_GC_UnTrack` before clearing "
"members. Here is our reimplemented deallocator using :c:func:"
"`PyObject_GC_UnTrack` and ``Custom_clear``::"
msgstr ""
#: extending/newtypes_tutorial.rst:784
msgid ""
"Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags::"
msgstr ""
#: extending/newtypes_tutorial.rst:788
msgid ""
"That's pretty much it. If we had written custom :c:member:`~PyTypeObject."
"tp_alloc` or :c:member:`~PyTypeObject.tp_free` handlers, we'd need to modify "
"them for cyclic garbage collection. Most extensions will use the versions "
"automatically provided."
msgstr ""
#: extending/newtypes_tutorial.rst:794
msgid "Subclassing other types"
msgstr ""
#: extending/newtypes_tutorial.rst:796
msgid ""
"It is possible to create new extension types that are derived from existing "
"types. It is easiest to inherit from the built in types, since an extension "
"can easily use the :c:type:`PyTypeObject` it needs. It can be difficult to "
"share these :c:type:`PyTypeObject` structures between extension modules."
msgstr ""
#: extending/newtypes_tutorial.rst:801
msgid ""
"In this example we will create a :class:`SubList` type that inherits from "
"the built-in :class:`list` type. The new type will be completely compatible "
"with regular lists, but will have an additional :meth:`increment` method "
"that increases an internal counter:"
msgstr ""
#: extending/newtypes_tutorial.rst:821
msgid ""
"As you can see, the source code closely resembles the :class:`Custom` "
"examples in previous sections. We will break down the main differences "
"between them. ::"
msgstr ""
#: extending/newtypes_tutorial.rst:829
msgid ""
"The primary difference for derived type objects is that the base type's "
"object structure must be the first value. The base type will already "
"include the :c:func:`PyObject_HEAD` at the beginning of its structure."
msgstr ""
#: extending/newtypes_tutorial.rst:833
msgid ""
"When a Python object is a :class:`SubList` instance, its ``PyObject *`` "
"pointer can be safely cast to both ``PyListObject *`` and ``SubListObject "
"*``::"
msgstr ""
#: extending/newtypes_tutorial.rst:845
msgid ""
"We see above how to call through to the :attr:`__init__` method of the base "
"type."
msgstr ""
#: extending/newtypes_tutorial.rst:848
msgid ""
"This pattern is important when writing a type with custom :c:member:"
"`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_dealloc` members. "
"The :c:member:`~PyTypeObject.tp_new` handler should not actually create the "
"memory for the object with its :c:member:`~PyTypeObject.tp_alloc`, but let "
"the base class handle it by calling its own :c:member:`~PyTypeObject.tp_new`."
msgstr ""
#: extending/newtypes_tutorial.rst:854
msgid ""
"The :c:type:`PyTypeObject` struct supports a :c:member:`~PyTypeObject."
"tp_base` specifying the type's concrete base class. Due to cross-platform "
"compiler issues, you can't fill that field directly with a reference to :c:"
"type:`PyList_Type`; it should be done later in the module initialization "
"function::"
msgstr ""
#: extending/newtypes_tutorial.rst:882
msgid ""
"Before calling :c:func:`PyType_Ready`, the type structure must have the :c:"
"member:`~PyTypeObject.tp_base` slot filled in. When we are deriving an "
"existing type, it is not necessary to fill out the :c:member:`~PyTypeObject."
"tp_alloc` slot with :c:func:`PyType_GenericNew` -- the allocation function "
"from the base type will be inherited."
msgstr ""
#: extending/newtypes_tutorial.rst:888
msgid ""
"After that, calling :c:func:`PyType_Ready` and adding the type object to the "
"module is the same as with the basic :class:`Custom` examples."
msgstr ""
#: extending/newtypes_tutorial.rst:893
msgid "Footnotes"
msgstr "Notes"
#: extending/newtypes_tutorial.rst:894
msgid ""
"This is true when we know that the object is a basic type, like a string or "
"a float."
msgstr ""
#: extending/newtypes_tutorial.rst:897
msgid ""
"We relied on this in the :c:member:`~PyTypeObject.tp_dealloc` handler in "
"this example, because our type doesn't support garbage collection."
msgstr ""
#: extending/newtypes_tutorial.rst:900
msgid ""
"We now know that the first and last members are strings, so perhaps we could "
"be less careful about decrementing their reference counts, however, we "
"accept instances of string subclasses. Even though deallocating normal "
"strings won't call back into our objects, we can't guarantee that "
"deallocating an instance of a string subclass won't call back into our "
"objects."
msgstr ""
#: extending/newtypes_tutorial.rst:906
msgid ""
"Also, even with our attributes restricted to strings instances, the user "
"could pass arbitrary :class:`str` subclasses and therefore still create "
"reference cycles."
msgstr ""