@@ -22,10 +22,9 @@ implement a handful of these.
22
22
As you probably expect by now, we're going to go over this and give more
23
23
information about the various handlers. We won't go in the order they are
24
24
defined in the structure, because there is a lot of historical baggage that
25
- impacts the ordering of the fields; be sure your type initialization keeps the
26
- fields in the right order! It's often easiest to find an example that includes
27
- all the fields you need (even if they're initialized to ``0 ``) and then change
28
- the values to suit your new type. ::
25
+ impacts the ordering of the fields. It's often easiest to find an example
26
+ that includes the fields you need and then change the values to suit your new
27
+ type. ::
29
28
30
29
const char *tp_name; /* For printing */
31
30
@@ -443,17 +442,23 @@ these in the :file:`Objects` directory of the Python source distribution. ::
443
442
hashfunc tp_hash;
444
443
445
444
This function, if you choose to provide it, should return a hash number for an
446
- instance of your data type. Here is a moderately pointless example::
445
+ instance of your data type. Here is a simple example::
447
446
448
447
static Py_hash_t
449
448
newdatatype_hash(newdatatypeobject *obj)
450
449
{
451
450
Py_hash_t result;
452
- result = obj->obj_UnderlyingDatatypePtr->size;
453
- result = result * 3;
451
+ result = obj->some_size + 32767 * obj->some_number;
452
+ if (result == -1)
453
+ result = -2;
454
454
return result;
455
455
}
456
456
457
+ :c:type: `Py_hash_t ` is a signed integer type with a platform-varying width.
458
+ Returning ``-1 `` from :c:member: `~PyTypeObject.tp_hash ` indicates an error,
459
+ which is why you should be careful to avoid returning it when hash computation
460
+ is successful, as seen above.
461
+
457
462
::
458
463
459
464
ternaryfunc tp_call;
@@ -505,25 +510,33 @@ Here is a toy ``tp_call`` implementation::
505
510
These functions provide support for the iterator protocol. Both handlers
506
511
take exactly one parameter, the instance for which they are being called,
507
512
and return a new reference. In the case of an error, they should set an
508
- exception and return *NULL *.
509
-
510
- Any :term: `iterable ` object must implement the ``tp_iter `` handler, which
511
- must return an :term: `iterator ` object. For collections (such as lists and
512
- tuples) which can support multiple iterators which do not interfere with
513
- each other, a new iterator should be created and returned by each call to
514
- ``tp_iter ``. Objects which can only be iterated over once (usually due to
515
- side effects of iteration, for example file objects) can implement
516
- ``tp_iter `` by returning a new reference to themselves, and should also
517
- implement the ``tp_iternext `` handler.
518
-
519
- Any :term: `iterator ` object should implement both ``tp_iter `` and ``tp_iternext ``.
520
- The ``tp_iter `` handler should return a new reference to the iterator. The
521
- ``tp_iternext `` handler should return a new reference to the next object in the
522
- iteration, if there is one. If the iteration has reached the end,
523
- ``tp_iternext `` may return *NULL * without setting an exception, or it may
524
- also set :exc: `StopIteration ` (while still returning *NULL *); avoiding
525
- the exception can yield slightly better performance. If an actual error occurs,
526
- it should always set an exception and return *NULL *.
513
+ exception and return *NULL *. :c:member: `~PyTypeObject.tp_iter ` corresponds
514
+ to the Python :meth: `__iter__ ` method, while :c:member: `~PyTypeObject.tp_iternext `
515
+ corresponds to the Python :meth: `~iterator.__next__ ` method.
516
+
517
+ Any :term: `iterable ` object must implement the :c:member: `~PyTypeObject.tp_iter `
518
+ handler, which must return an :term: `iterator ` object. Here the same guidelines
519
+ apply as for Python classes:
520
+
521
+ * For collections (such as lists and tuples) which can support multiple
522
+ independent iterators, a new iterator should be created and returned by
523
+ each call to :c:member: `~PyTypeObject.tp_iter `.
524
+ * Objects which can only be iterated over once (usually due to side effects of
525
+ iteration, such as file objects) can implement :c:member: `~PyTypeObject.tp_iter `
526
+ by returning a new reference to themselves -- and should also therefore
527
+ implement the :c:member: `~PyTypeObject.tp_iternext ` handler.
528
+
529
+ Any :term: `iterator ` object should implement both :c:member: `~PyTypeObject.tp_iter `
530
+ and :c:member: `~PyTypeObject.tp_iternext `. An iterator's
531
+ :c:member: `~PyTypeObject.tp_iter ` handler should return a new reference
532
+ to the iterator. Its :c:member: `~PyTypeObject.tp_iternext ` handler should
533
+ return a new reference to the next object in the iteration, if there is one.
534
+ If the iteration has reached the end, :c:member: `~PyTypeObject.tp_iternext `
535
+ may return *NULL * without setting an exception, or it may set
536
+ :exc: `StopIteration ` *in addition * to returning *NULL *; avoiding
537
+ the exception can yield slightly better performance. If an actual error
538
+ occurs, :c:member: `~PyTypeObject.tp_iternext ` should always set an exception
539
+ and return *NULL *.
527
540
528
541
529
542
.. _weakref-support :
@@ -535,14 +548,19 @@ One of the goals of Python's weak reference implementation is to allow any type
535
548
to participate in the weak reference mechanism without incurring the overhead on
536
549
performance-critical objects (such as numbers).
537
550
551
+ .. seealso ::
552
+ Documentation for the :mod: `weakref ` module.
553
+
538
554
For an object to be weakly referencable, the extension type must do two things:
539
555
540
556
#. Include a :c:type: `PyObject\* ` field in the C object structure dedicated to
541
- the weak reference mechanism; it must be initialized to *NULL * by the object's
542
- constructor.
557
+ the weak reference mechanism. The object's constructor should leave it
558
+ *NULL * (which is automatic when using the default
559
+ :c:member: `~PyTypeObject.tp_alloc `).
543
560
544
- #. Set the :c:member: `~PyTypeObject.tp_weaklistoffset ` member of the C type
545
- object to the offset of the aforementioned field in the C object structure.
561
+ #. Set the :c:member: `~PyTypeObject.tp_weaklistoffset ` type member
562
+ to the offset of the aforementioned field in the C object structure,
563
+ so that the interpreter knows how to access and modify that field.
546
564
547
565
Concretely, here is how a trivial object structure would be augmented
548
566
with the required field::
@@ -572,10 +590,6 @@ non-*NULL*::
572
590
Py_TYPE(self)->tp_free((PyObject *) self);
573
591
}
574
592
575
- .. seealso ::
576
- The :mod: `weakref ` module allows creating weak references to instances
577
- of types that implement the protocol described above.
578
-
579
593
580
594
More Suggestions
581
595
----------------
@@ -586,9 +600,9 @@ then search the C source files for ``tp_`` plus the function you want
586
600
(for example, ``tp_richcompare ``). You will find examples of the function
587
601
you want to implement.
588
602
589
- When you need to verify that an object is an instance of the type you are
590
- implementing, use the :c:func: `PyObject_TypeCheck ` function. A sample of its use
591
- might be something like the following::
603
+ When you need to verify that an object is a concrete instance of the type you
604
+ are implementing, use the :c:func: `PyObject_TypeCheck ` function. A sample of
605
+ its use might be something like the following::
592
606
593
607
if (!PyObject_TypeCheck(some_object, &MyType)) {
594
608
PyErr_SetString(PyExc_TypeError, "arg #1 not a mything");
0 commit comments