forked from AFPy/python-docs-fr
860 lines
33 KiB
Plaintext
860 lines
33 KiB
Plaintext
# Copyright (C) 2001-2018, Python Software Foundation
|
|
# For licence information, see README file.
|
|
#
|
|
msgid ""
|
|
msgstr ""
|
|
"Project-Id-Version: Python 3.6\n"
|
|
"Report-Msgid-Bugs-To: \n"
|
|
"POT-Creation-Date: 2018-05-02 00:10+0200\n"
|
|
"PO-Revision-Date: 2018-06-17 10:15+0200\n"
|
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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"
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:7
|
|
msgid "Defining Extension Types: Tutorial"
|
|
msgstr ""
|
|
|
|
#: ../Doc/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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:24
|
|
msgid "The Basics"
|
|
msgstr ""
|
|
|
|
#: ../Doc/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 ""
|
|
|
|
#: ../Doc/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 ""
|
|
|
|
#: ../Doc/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 ""
|
|
|
|
#: ../Doc/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 ""
|
|
|
|
#: ../Doc/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 ""
|
|
|
|
#: ../Doc/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 ""
|
|
|
|
#: ../Doc/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 ""
|
|
|
|
#: ../Doc/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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:61
|
|
msgid "The first bit is::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/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 debug builds."
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:75
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:78
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:87
|
|
msgid "The second bit is the definition of the type object. ::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:99
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:103
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:108
|
|
msgid "We're going to pick it apart, one field at a time::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:112
|
|
msgid ""
|
|
"This line is mandatory boilerplate to initialize the ``ob_base`` field "
|
|
"mentioned above. ::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:117
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:127
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:136
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:142
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:152
|
|
msgid "We set the class flags to :const:`Py_TPFLAGS_DEFAULT`. ::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:156
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:160
|
|
msgid ""
|
|
"We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. ::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:164
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:171
|
|
msgid ""
|
|
"Everything else in the file should be familiar, except for some code in :c:"
|
|
"func:`PyInit_custom`::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:177
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:183
|
|
msgid ""
|
|
"This adds the type to the module dictionary. This allows us to create :"
|
|
"class:`Custom` instances by calling the :class:`Custom` class:"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:191
|
|
msgid ""
|
|
"That's it! All that remains is to build it; put the above code in a file "
|
|
"called :file:`custom.c` and:"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:200
|
|
msgid "in a file called :file:`setup.py`; then typing"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:206
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:210
|
|
msgid "That wasn't so hard, was it?"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:212
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:216
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:224
|
|
msgid "Adding data and methods to the Basic example"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:226
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:233
|
|
msgid "This version of the module has a number of changes."
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:235
|
|
msgid "We've added an extra include::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:239
|
|
msgid ""
|
|
"This include provides declarations that we use to handle attributes, as "
|
|
"described a bit later."
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:242
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:246
|
|
msgid "The object structure is updated accordingly::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:255
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:266
|
|
msgid "which is assigned to the :c:member:`~PyTypeObject.tp_dealloc` member::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:270
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:279
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:285
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:309
|
|
msgid "and install it in the :c:member:`~PyTypeObject.tp_new` member::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:313
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:321
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:329
|
|
msgid ""
|
|
"``tp_new`` shouldn't call ``tp_init`` explicitly, as the interpreter will do "
|
|
"it itself."
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:332
|
|
msgid ""
|
|
"The ``tp_new`` implementation calls the :c:member:`~PyTypeObject.tp_alloc` "
|
|
"slot to allocate memory::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:337
|
|
msgid ""
|
|
"Since memory allocation may fail, we must check the :c:member:`~PyTypeObject."
|
|
"tp_alloc` result against *NULL* before proceeding."
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:341
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:347
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:357
|
|
msgid ""
|
|
"We also define an initialization function which accepts arguments to provide "
|
|
"initial values for our instance::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:386
|
|
msgid "by filling the :c:member:`~PyTypeObject.tp_init` slot. ::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:390
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:395
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:409
|
|
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` and let arbitrary code run in other threads that accesses "
|
|
"and modifies our object."
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:416
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:420
|
|
msgid "when we absolutely know that the reference count is greater than 1;"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:422
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:425
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:428
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:441
|
|
msgid ""
|
|
"and put the definitions in the :c:member:`~PyTypeObject.tp_members` slot::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:445
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:449
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:456
|
|
msgid ""
|
|
"We define a single method, :meth:`Custom.name()`, that outputs the objects "
|
|
"name as the concatenation of the first and last names. ::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:473
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:485
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:491
|
|
msgid ""
|
|
"Now that we've defined the method, we need to create an array of method "
|
|
"definitions::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:501
|
|
msgid ""
|
|
"(note that we used the :const:`METH_NOARGS` flag to indicate that the method "
|
|
"is expecting no arguments other than *self*)"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:504
|
|
msgid "and assign it to the :c:member:`~PyTypeObject.tp_methods` slot::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:508
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:515
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:519
|
|
msgid "Finally, we update our :file:`setup.py` file to build the new module:"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:532
|
|
msgid "Providing finer control over data attributes"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:534
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:543
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:574
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:580
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:585
|
|
msgid "We create an array of :c:type:`PyGetSetDef` structures::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:595
|
|
msgid "and register it in the :c:member:`~PyTypeObject.tp_getset` slot::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:599
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:602
|
|
msgid "We also remove the member definitions for these attributes::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:610
|
|
msgid ""
|
|
"We also need to update the :c:member:`~PyTypeObject.tp_init` handler to only "
|
|
"allow strings [#]_ to be passed::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:639
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:646
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:652
|
|
msgid "Supporting cyclic garbage collection"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:654
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:664
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:669
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:683
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:690
|
|
msgid ""
|
|
"First, the traversal method lets the cyclic GC know about subobjects that "
|
|
"could participate in cycles::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:710
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:716
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:729
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:732
|
|
msgid ""
|
|
"Second, we need to provide a method for clearing any subobjects that can "
|
|
"participate in cycles::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:743
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:751
|
|
msgid "You could emulate :c:func:`Py_CLEAR` by writing::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:758
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:762
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:777
|
|
msgid ""
|
|
"Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:781
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:787
|
|
msgid "Subclassing other types"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:789
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:794
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:814
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:822
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:826
|
|
msgid ""
|
|
"When a Python object is a :class:`SubList` instance, its ``PyObject *`` "
|
|
"pointer can be safely cast to both ``PyListObject *`` and ``SubListObject "
|
|
"*``::"
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:838
|
|
msgid ""
|
|
"We see above how to call through to the :attr:`__init__` method of the base "
|
|
"type."
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:841
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:847
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:870
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:876
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:881
|
|
msgid "Footnotes"
|
|
msgstr "Notes"
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:882
|
|
msgid ""
|
|
"This is true when we know that the object is a basic type, like a string or "
|
|
"a float."
|
|
msgstr ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:885
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:888
|
|
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 ""
|
|
|
|
#: ../Doc/extending/newtypes_tutorial.rst:894
|
|
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 ""
|