forked from AFPy/python-docs-fr
Julien Palard
ec12a7bae6
Automerge of PR #1605 by @JulienPalard Je pense que je vais m'arrêter là pour le moment sur ce fichier, si j'attaque le reste ce sera pour une autre péèrre.
961 lines
39 KiB
Plaintext
961 lines
39 KiB
Plaintext
# 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: 2021-09-23 16:16+0200\n"
|
||
"PO-Revision-Date: 2021-09-25 11:25+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
|
||
msgid ""
|
||
"The :term:`CPython` runtime sees all Python objects as variables of type :c:"
|
||
"type:`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
|
||
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_REFCNT` "
|
||
"and :c:macro:`Py_TYPE` 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 ""
|