Skip to content

Commit 1941ec6

Browse files
committed
Formalize that the Py_VISIT macro requires that the tp_traverse
implementation it's used in must give its arguments specific names.
1 parent 1213282 commit 1941ec6

3 files changed

Lines changed: 49 additions & 39 deletions

File tree

β€ŽDoc/api/newtypes.texβ€Ž

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,13 +1664,14 @@ \section{Supporting Cyclic Garbage Collection
16641664
\end{ctypedesc}
16651665

16661666
To simplify writing \member{tp_traverse} handlers, a
1667-
\cfunction{Py_VISIT()} is provided:
1667+
\cfunction{Py_VISIT()} macro is provided. In order to use this macro,
1668+
the \member{tp_traverse} implementation must name its arguments
1669+
exactly \var{visit} and \var{arg}:
16681670

16691671
\begin{cfuncdesc}{void}{Py_VISIT}{PyObject *o}
1670-
Call the \var{visit} for \var{o} with \var{arg}. If \var{visit}
1671-
returns a non-zero value, then return it. Using this macro,
1672-
\member{tp_traverse} handlers look like:
1673-
1672+
Call the \var{visit} callback, with arguments \var{o} and \var{arg}.
1673+
If \var{visit} returns a non-zero value, then return it. Using this
1674+
macro, \member{tp_traverse} handlers look like:
16741675

16751676
\begin{verbatim}
16761677
static int

β€ŽDoc/ext/newtypes.texβ€Ž

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ \section{The Basics
106106
\file{object.h} you'll see that it has many more fields that the
107107
definition above. The remaining fields will be filled with zeros by
108108
the C compiler, and it's common practice to not specify them
109-
explicitly unless you need them.
109+
explicitly unless you need them.
110110

111111
This is so important that we're going to pick the top of it apart still
112112
further:
@@ -149,7 +149,7 @@ \section{The Basics
149149
\end{verbatim}
150150

151151
Note that the name is a dotted name that includes both the module name
152-
and the name of the type within the module. The module in this case is
152+
and the name of the type within the module. The module in this case is
153153
\module{noddy} and the type is \class{Noddy}, so we set the type name
154154
to \class{noddy.Noddy}.
155155

@@ -180,7 +180,7 @@ \section{The Basics
180180
Ignore this for now.
181181

182182
Skipping a number of type methods that we don't provide, we set the
183-
class flags to \constant{Py_TPFLAGS_DEFAULT}.
183+
class flags to \constant{Py_TPFLAGS_DEFAULT}.
184184

185185
\begin{verbatim}
186186
Py_TPFLAGS_DEFAULT, /*tp_flags*/
@@ -197,8 +197,8 @@ \section{The Basics
197197

198198
Now we get into the type methods, the things that make your objects
199199
different from the others. We aren't going to implement any of these
200-
in this version of the module. We'll expand this example later to
201-
have more interesting behavior.
200+
in this version of the module. We'll expand this example later to
201+
have more interesting behavior.
202202

203203
For now, all we want to be able to do is to create new \class{Noddy}
204204
objects. To enable object creation, we have to provide a
@@ -268,7 +268,7 @@ \section{The Basics
268268
data and doesn't do anything. It can't even be subclassed.
269269

270270
\subsection{Adding data and methods to the Basic example}
271-
271+
272272
Let's expend the basic example to add some data and methods. Let's
273273
also make the type usable as a base class. We'll create
274274
a new module, \module{noddy2} that adds these capabilities:
@@ -351,7 +351,7 @@ \subsection{Adding data and methods to the Basic example}
351351
Py_DECREF(self);
352352
return NULL;
353353
}
354-
354+
355355
self->last = PyString_FromString("");
356356
if (self->last == NULL)
357357
{
@@ -417,10 +417,10 @@ \subsection{Adding data and methods to the Basic example}
417417
418418
static char *kwlist[] = {"first", "last", "number", NULL};
419419
420-
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
421-
&first, &last,
420+
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
421+
&first, &last,
422422
&self->number))
423-
return -1;
423+
return -1;
424424
425425
if (first) {
426426
tmp = self->first;
@@ -488,7 +488,7 @@ \subsection{Adding data and methods to the Basic example}
488488
garbage collection, there are calls that can be made to ``untrack''
489489
the object from garbage collection, however, these calls are
490490
advanced and not covered here.}
491-
\item
491+
\item
492492
\end{itemize}
493493

494494

@@ -527,7 +527,7 @@ \subsection{Adding data and methods to the Basic example}
527527
be set to \NULL{} if the attributes are deleted.
528528

529529
We define a single method, \method{name}, that outputs the objects
530-
name as the concatenation of the first and last names.
530+
name as the concatenation of the first and last names.
531531

532532
\begin{verbatim}
533533
static PyObject *
@@ -558,7 +558,7 @@ \subsection{Adding data and methods to the Basic example}
558558
559559
result = PyString_Format(format, args);
560560
Py_DECREF(args);
561-
561+
562562
return result;
563563
}
564564
\end{verbatim}
@@ -656,16 +656,16 @@ \subsection{Providing finer control over data attributes}
656656
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
657657
return -1;
658658
}
659-
659+
660660
if (! PyString_Check(value)) {
661-
PyErr_SetString(PyExc_TypeError,
661+
PyErr_SetString(PyExc_TypeError,
662662
"The first attribute value must be a string");
663663
return -1;
664664
}
665-
665+
666666
Py_DECREF(self->first);
667667
Py_INCREF(value);
668-
self->first = value;
668+
self->first = value;
669669
670670
return 0;
671671
}
@@ -687,11 +687,11 @@ \subsection{Providing finer control over data attributes}
687687

688688
\begin{verbatim}
689689
static PyGetSetDef Noddy_getseters[] = {
690-
{"first",
690+
{"first",
691691
(getter)Noddy_getfirst, (setter)Noddy_setfirst,
692692
"first name",
693693
NULL},
694-
{"last",
694+
{"last",
695695
(getter)Noddy_getlast, (setter)Noddy_setlast,
696696
"last name",
697697
NULL},
@@ -705,7 +705,7 @@ \subsection{Providing finer control over data attributes}
705705
Noddy_getseters, /* tp_getset */
706706
\end{verbatim}
707707

708-
to register out attribute getters and setters.
708+
to register out attribute getters and setters.
709709

710710
The last item in a \ctype{PyGetSetDef} structure is the closure
711711
mentioned above. In this case, we aren't using the closure, so we just
@@ -737,10 +737,10 @@ \subsection{Providing finer control over data attributes}
737737
738738
static char *kwlist[] = {"first", "last", "number", NULL};
739739
740-
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
741-
&first, &last,
740+
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
741+
&first, &last,
742742
&self->number))
743-
return -1;
743+
return -1;
744744
745745
if (first) {
746746
tmp = self->first;
@@ -838,11 +838,11 @@ \subsection{Supporting cyclic garbage collection}
838838
\cfunction{visit()} function, which is passed to the traversal method.
839839
The \cfunction{visit()} function takes as arguments the subobject and
840840
the extra argument \var{arg} passed to the traversal method. It
841-
returns an integer value that must be returned if it is non-zero.
841+
returns an integer value that must be returned if it is non-zero.
842842

843843

844-
Python 2.4 and higher provide a \cfunction{Py_VISIT()} that automates
845-
calling visit functions. With \cfunction{Py_VISIT()}, the
844+
Python 2.4 and higher provide a \cfunction{Py_VISIT()} macro that automates
845+
calling visit functions. With \cfunction{Py_VISIT()},
846846
\cfunction{Noddy_traverse()} can be simplified:
847847

848848

@@ -856,12 +856,17 @@ \subsection{Supporting cyclic garbage collection}
856856
}
857857
\end{verbatim}
858858

859+
\note{Note that the \member{tp_traverse} implementation must name its
860+
arguments exactly \var{visit} and \var{arg} in order to use
861+
\cfunction{Py_VISIT()}. This is to encourage uniformity
862+
across these boring implementations.}
863+
859864
We also need to provide a method for clearing any subobjects that can
860865
participate in cycles. We implement the method and reimplement the
861866
deallocator to use it:
862867

863868
\begin{verbatim}
864-
static int
869+
static int
865870
Noddy_clear(Noddy *self)
866871
{
867872
PyObject *tmp;
@@ -903,7 +908,7 @@ \subsection{Supporting cyclic garbage collection}
903908
simplified:
904909

905910
\begin{verbatim}
906-
static int
911+
static int
907912
Noddy_clear(Noddy *self)
908913
{
909914
Py_CLEAR(self->first);
@@ -973,7 +978,7 @@ \section{Type Methods
973978
Here you can put a string (or its address) that you want returned when
974979
the Python script references \code{obj.__doc__} to retrieve the
975980
doc string.
976-
981+
977982
Now we come to the basic type methods---the ones most extension types
978983
will implement.
979984

@@ -1281,7 +1286,7 @@ \subsubsection{Generic Attribute Management}
12811286
doc string using its \member{__doc__} attribute.
12821287

12831288
As with the \member{tp_methods} table, a sentinel entry with a
1284-
\member{name} value of \NULL{} is required.
1289+
\member{name} value of \NULL{} is required.
12851290

12861291

12871292
% XXX Descriptors need to be explained in more detail somewhere, but
@@ -1345,7 +1350,7 @@ \subsubsection{Type-specific Attribute Management}
13451350
third parameter will be \NULL. Here is an example that simply raises
13461351
an exception; if this were really all you wanted, the
13471352
\member{tp_setattr} handler should be set to \NULL.
1348-
1353+
13491354
\begin{verbatim}
13501355
static int
13511356
newdatatype_setattr(newdatatypeobject *obj, char *name, PyObject *v)
@@ -1389,7 +1394,7 @@ \subsection{Object Comparison}
13891394
newdatatype_compare(newdatatypeobject * obj1, newdatatypeobject * obj2)
13901395
{
13911396
long result;
1392-
1397+
13931398
if (obj1->obj_UnderlyingDatatypePtr->size <
13941399
obj2->obj_UnderlyingDatatypePtr->size) {
13951400
result = -1;
@@ -1489,7 +1494,7 @@ \subsection{Abstract Protocol Support}
14891494
this is non-\NULL, raise a \exception{TypeError} with a message
14901495
saying that keyword arguments are not supported.
14911496
\end{enumerate}
1492-
1497+
14931498
Here is a desultory example of the implementation of the call function.
14941499

14951500
\begin{verbatim}

β€ŽInclude/objimpl.hβ€Ž

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,11 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *);
302302
( (type *) _PyObject_GC_NewVar((typeobj), (n)) )
303303

304304

305-
/* Utility macro to help write tp_traverse functions */
305+
/* Utility macro to help write tp_traverse functions.
306+
* To use this macro, the tp_traverse function must name its arguments
307+
* "visit" and "arg". This is intended to keep tp_traverse functions
308+
* looking as much alike as possible.
309+
*/
306310
#define Py_VISIT(op) \
307311
do { \
308312
if (op) { \

0 commit comments

Comments
 (0)