Commit 68304ccc authored by Fred Drake's avatar Fred Drake

Move reference material on PyArg_Parse*() out of the Extending & Embedding

document to the C API reference.  Move some instructional text from the API
reference to the Extending & Embedding manual.

Fix the descriptions of the es and es# formats for PyArg_Parse*().
This closes SF bug #536516.
parent 6b8ab74c
\chapter{Defining New Object Types \label{newTypes}} \chapter{Object Implementation Support \label{newTypes}}
This chapter describes the functions, types, and macros used when
defining new object types.
\section{Allocating Objects on the Heap \section{Allocating Objects on the Heap
...@@ -388,6 +392,12 @@ which do not store references to other objects, or which only store ...@@ -388,6 +392,12 @@ which do not store references to other objects, or which only store
references to atomic types (such as numbers or strings), do not need references to atomic types (such as numbers or strings), do not need
to provide any explicit support for garbage collection. to provide any explicit support for garbage collection.
An example showing the use of these interfaces can be found in
``\ulink{Supporting the Cycle
Collector}{../ext/example-cycle-support.html}'' in
\citetitle[../ext/ext.html]{Extending and Embedding the Python
Interpreter}.
To create a container type, the \member{tp_flags} field of the type To create a container type, the \member{tp_flags} field of the type
object must include the \constant{Py_TPFLAGS_HAVE_GC} and provide an object must include the \constant{Py_TPFLAGS_HAVE_GC} and provide an
implementation of the \member{tp_traverse} handler. If instances of the implementation of the \member{tp_traverse} handler. If instances of the
...@@ -504,103 +514,3 @@ The \member{tp_clear} handler must be of the \ctype{inquiry} type, or ...@@ -504,103 +514,3 @@ The \member{tp_clear} handler must be of the \ctype{inquiry} type, or
this method if it detects that this object is involved in a this method if it detects that this object is involved in a
reference cycle. reference cycle.
\end{ctypedesc} \end{ctypedesc}
\subsection{Example Cycle Collector Support
\label{example-cycle-support}}
This example shows only enough of the implementation of an extension
type to show how the garbage collector support needs to be added. It
shows the definition of the object structure, the
\member{tp_traverse}, \member{tp_clear} and \member{tp_dealloc}
implementations, the type structure, and a constructor --- the module
initialization needed to export the constructor to Python is not shown
as there are no special considerations there for the collector. To
make this interesting, assume that the module exposes ways for the
\member{container} field of the object to be modified. Note that
since no checks are made on the type of the object used to initialize
\member{container}, we have to assume that it may be a container.
\begin{verbatim}
#include "Python.h"
typedef struct {
PyObject_HEAD
PyObject *container;
} MyObject;
static int
my_traverse(MyObject *self, visitproc visit, void *arg)
{
if (self->container != NULL)
return visit(self->container, arg);
else
return 0;
}
static int
my_clear(MyObject *self)
{
Py_XDECREF(self->container);
self->container = NULL;
return 0;
}
static void
my_dealloc(MyObject *self)
{
PyObject_GC_UnTrack((PyObject *) self);
Py_XDECREF(self->container);
PyObject_GC_Del(self);
}
\end{verbatim}
\begin{verbatim}
statichere PyTypeObject
MyObject_Type = {
PyObject_HEAD_INIT(NULL)
0,
"MyObject",
sizeof(MyObject),
0,
(destructor)my_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
0, /* tp_doc */
(traverseproc)my_traverse, /* tp_traverse */
(inquiry)my_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
};
/* This constructor should be made accessible from Python. */
static PyObject *
new_object(PyObject *unused, PyObject *args)
{
PyObject *container = NULL;
MyObject *result = NULL;
if (PyArg_ParseTuple(args, "|O:new_object", &container)) {
result = PyObject_GC_New(MyObject, &MyObject_Type);
if (result != NULL) {
result->container = container;
PyObject_GC_Track(result);
}
}
return (PyObject *) result;
}
\end{verbatim}
This diff is collapsed.
#include "Python.h"
typedef struct {
PyObject_HEAD
PyObject *container;
} MyObject;
static int
my_traverse(MyObject *self, visitproc visit, void *arg)
{
if (self->container != NULL)
return visit(self->container, arg);
else
return 0;
}
static int
my_clear(MyObject *self)
{
Py_XDECREF(self->container);
self->container = NULL;
return 0;
}
static void
my_dealloc(MyObject *self)
{
PyObject_GC_UnTrack((PyObject *) self);
Py_XDECREF(self->container);
PyObject_GC_Del(self);
}
static PyTypeObject
MyObject_Type = {
PyObject_HEAD_INIT(NULL)
0,
"MyObject",
sizeof(MyObject),
0,
(destructor)my_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
0, /* tp_doc */
(traverseproc)my_traverse, /* tp_traverse */
(inquiry)my_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
};
/* This constructor should be made accessible from Python. */
static PyObject *
new_object(PyObject *unused, PyObject *args)
{
PyObject *container = NULL;
MyObject *result = NULL;
if (PyArg_ParseTuple(args, "|O:new_object", &container)) {
result = PyObject_GC_New(MyObject, &MyObject_Type);
if (result != NULL) {
result->container = container;
PyObject_GC_Track(result);
}
}
return (PyObject *) result;
}
This diff is collapsed.
...@@ -47,7 +47,9 @@ functions that have no yet been defined, but we need to be able to ...@@ -47,7 +47,9 @@ functions that have no yet been defined, but we need to be able to
refer to it, hence the declaration. refer to it, hence the declaration.
The \code{staticforward} is required to placate various brain dead The \code{staticforward} is required to placate various brain dead
compilers. compilers. The actual definition of the object declared using
\code{staticforward} should use \code{statichere} instead of
\keyword{static}.
\begin{verbatim} \begin{verbatim}
typedef struct { typedef struct {
...@@ -154,7 +156,7 @@ Python objects, one would decref them here. ...@@ -154,7 +156,7 @@ Python objects, one would decref them here.
Moving on, we come to the crunch --- the type object. Moving on, we come to the crunch --- the type object.
\begin{verbatim} \begin{verbatim}
static PyTypeObject noddy_NoddyType = { statichere PyTypeObject noddy_NoddyType = {
PyObject_HEAD_INIT(NULL) PyObject_HEAD_INIT(NULL)
0, /* ob_size */ 0, /* ob_size */
"Noddy", /* tp_name */ "Noddy", /* tp_name */
...@@ -173,6 +175,9 @@ static PyTypeObject noddy_NoddyType = { ...@@ -173,6 +175,9 @@ static PyTypeObject noddy_NoddyType = {
}; };
\end{verbatim} \end{verbatim}
(Note the use of \code{statichere} instead of \keyword{static}, since
we used \code{staticforward} in the declaration.)
Now if you go and look up the definition of \ctype{PyTypeObject} in Now if you go and look up the definition of \ctype{PyTypeObject} in
\file{object.h} you'll see that it has many, many more fields that the \file{object.h} you'll see that it has many, many more fields that the
definition above. The remaining fields will be filled with zeros by definition above. The remaining fields will be filled with zeros by
...@@ -404,7 +409,7 @@ my_dealloc(PyObject *obj) ...@@ -404,7 +409,7 @@ my_dealloc(PyObject *obj)
\end{verbatim} \end{verbatim}
\subsection{Object Representation} \subsection{Object Presentation}
In Python, there are three ways to generate a textual representation In Python, there are three ways to generate a textual representation
of an object: the \function{repr()}\bifuncindex{repr} function (or of an object: the \function{repr()}\bifuncindex{repr} function (or
...@@ -913,6 +918,29 @@ avoiding the exception can yield slightly better performance. If an ...@@ -913,6 +918,29 @@ avoiding the exception can yield slightly better performance. If an
actual error occurs, it should set an exception and return \NULL. actual error occurs, it should set an exception and return \NULL.
\subsection{Cycle Collector Support
\label{example-cycle-support}}
This example shows only enough of the implementation of an extension
type to show how the garbage collector support needs to be added. It
shows the definition of the object structure, the
\member{tp_traverse}, \member{tp_clear} and \member{tp_dealloc}
implementations, the type structure, and a constructor --- the module
initialization needed to export the constructor to Python is not shown
as there are no special considerations there for the collector. To
make this interesting, assume that the module exposes ways for the
\member{container} field of the object to be modified. Note that
since no checks are made on the type of the object used to initialize
\member{container}, we have to assume that it may be a container.
\verbatiminput{cycle-gc.c}
Full details on the APIs related to the cycle detector are in
\ulink{Supporting Cyclic Garbarge
Collection}{../api/supporting-cycle-detection.html} in the
\citetitle[../api/api.html]{Python/C API Reference Manual}.
\subsection{More Suggestions} \subsection{More Suggestions}
Remember that you can omit most of these functions, in which case you Remember that you can omit most of these functions, in which case you
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment