mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-111178: fix UBSan failures in Modules/xx*.c
(GH-129797)
Fix UBSan failures in `Modules/xxlimited.c`, `Modules/xxlimited_35.c`, `Modules/xxsubtype.c`, `Modules/xxmodule.c`
This commit is contained in:
parent
3d40317ed2
commit
ead091357d
4 changed files with 112 additions and 77 deletions
|
@ -90,6 +90,7 @@ typedef struct {
|
||||||
Py_ssize_t x_exports; /* how many buffer are exported */
|
Py_ssize_t x_exports; /* how many buffer are exported */
|
||||||
} XxoObject;
|
} XxoObject;
|
||||||
|
|
||||||
|
#define XxoObject_CAST(op) ((XxoObject *)(op))
|
||||||
// XXX: no good way to do this yet
|
// XXX: no good way to do this yet
|
||||||
// #define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type)
|
// #define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type)
|
||||||
|
|
||||||
|
@ -114,28 +115,29 @@ newXxoObject(PyObject *module)
|
||||||
/* Xxo finalization */
|
/* Xxo finalization */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Xxo_traverse(PyObject *self_obj, visitproc visit, void *arg)
|
Xxo_traverse(PyObject *op, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
// Visit the type
|
// Visit the type
|
||||||
Py_VISIT(Py_TYPE(self_obj));
|
Py_VISIT(Py_TYPE(op));
|
||||||
|
|
||||||
// Visit the attribute dict
|
// Visit the attribute dict
|
||||||
XxoObject *self = (XxoObject *)self_obj;
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
Py_VISIT(self->x_attr);
|
Py_VISIT(self->x_attr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Xxo_clear(XxoObject *self)
|
Xxo_clear(PyObject *op)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
Py_CLEAR(self->x_attr);
|
Py_CLEAR(self->x_attr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Xxo_finalize(PyObject *self_obj)
|
Xxo_finalize(PyObject *op)
|
||||||
{
|
{
|
||||||
XxoObject *self = (XxoObject *)self_obj;
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
Py_CLEAR(self->x_attr);
|
Py_CLEAR(self->x_attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +156,9 @@ Xxo_dealloc(PyObject *self)
|
||||||
/* Xxo attribute handling */
|
/* Xxo attribute handling */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Xxo_getattro(XxoObject *self, PyObject *name)
|
Xxo_getattro(PyObject *op, PyObject *name)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
if (self->x_attr != NULL) {
|
if (self->x_attr != NULL) {
|
||||||
PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
|
PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
|
@ -165,12 +168,13 @@ Xxo_getattro(XxoObject *self, PyObject *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PyObject_GenericGetAttr((PyObject *)self, name);
|
return PyObject_GenericGetAttr(op, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Xxo_setattro(XxoObject *self, PyObject *name, PyObject *v)
|
Xxo_setattro(PyObject *op, PyObject *name, PyObject *v)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
if (self->x_attr == NULL) {
|
if (self->x_attr == NULL) {
|
||||||
// prepare the attribute dict
|
// prepare the attribute dict
|
||||||
self->x_attr = PyDict_New();
|
self->x_attr = PyDict_New();
|
||||||
|
@ -197,8 +201,8 @@ Xxo_setattro(XxoObject *self, PyObject *name, PyObject *v)
|
||||||
/* Xxo methods */
|
/* Xxo methods */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Xxo_demo(XxoObject *self, PyTypeObject *defining_class,
|
Xxo_demo(PyObject *op, PyTypeObject *defining_class,
|
||||||
PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
{
|
{
|
||||||
if (kwnames != NULL && PyObject_Length(kwnames)) {
|
if (kwnames != NULL && PyObject_Length(kwnames)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "demo() takes no keyword arguments");
|
PyErr_SetString(PyExc_TypeError, "demo() takes no keyword arguments");
|
||||||
|
@ -233,9 +237,10 @@ static PyMethodDef Xxo_methods[] = {
|
||||||
/* Xxo buffer interface */
|
/* Xxo buffer interface */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Xxo_getbuffer(XxoObject *self, Py_buffer *view, int flags)
|
Xxo_getbuffer(PyObject *op, Py_buffer *view, int flags)
|
||||||
{
|
{
|
||||||
int res = PyBuffer_FillInfo(view, (PyObject*)self,
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
|
int res = PyBuffer_FillInfo(view, op,
|
||||||
(void *)self->x_buffer, BUFSIZE,
|
(void *)self->x_buffer, BUFSIZE,
|
||||||
0, flags);
|
0, flags);
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
|
@ -245,14 +250,16 @@ Xxo_getbuffer(XxoObject *self, Py_buffer *view, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Xxo_releasebuffer(XxoObject *self, Py_buffer *view)
|
Xxo_releasebuffer(PyObject *op, Py_buffer *Py_UNUSED(view))
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
self->x_exports--;
|
self->x_exports--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Xxo_get_x_exports(XxoObject *self, void *c)
|
Xxo_get_x_exports(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
return PyLong_FromSsize_t(self->x_exports);
|
return PyLong_FromSsize_t(self->x_exports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +269,7 @@ PyDoc_STRVAR(Xxo_doc,
|
||||||
"A class that explicitly stores attributes in an internal dict");
|
"A class that explicitly stores attributes in an internal dict");
|
||||||
|
|
||||||
static PyGetSetDef Xxo_getsetlist[] = {
|
static PyGetSetDef Xxo_getsetlist[] = {
|
||||||
{"x_exports", (getter) Xxo_get_x_exports, NULL, NULL},
|
{"x_exports", Xxo_get_x_exports, NULL, NULL},
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@ typedef struct {
|
||||||
|
|
||||||
static PyObject *Xxo_Type;
|
static PyObject *Xxo_Type;
|
||||||
|
|
||||||
#define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type)
|
#define XxoObject_CAST(op) ((XxoObject *)(op))
|
||||||
|
#define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type)
|
||||||
|
|
||||||
static XxoObject *
|
static XxoObject *
|
||||||
newXxoObject(PyObject *arg)
|
newXxoObject(PyObject *arg)
|
||||||
|
@ -40,32 +41,36 @@ newXxoObject(PyObject *arg)
|
||||||
/* Xxo methods */
|
/* Xxo methods */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Xxo_traverse(XxoObject *self, visitproc visit, void *arg)
|
Xxo_traverse(PyObject *op, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
Py_VISIT(Py_TYPE(self));
|
Py_VISIT(Py_TYPE(self));
|
||||||
Py_VISIT(self->x_attr);
|
Py_VISIT(self->x_attr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Xxo_clear(XxoObject *self)
|
Xxo_clear(PyObject *op)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
Py_CLEAR(self->x_attr);
|
Py_CLEAR(self->x_attr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Xxo_finalize(XxoObject *self)
|
Xxo_finalize(PyObject *op)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
Py_CLEAR(self->x_attr);
|
Py_CLEAR(self->x_attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Xxo_demo(XxoObject *self, PyObject *args)
|
Xxo_demo(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *o = NULL;
|
PyObject *o = NULL;
|
||||||
if (!PyArg_ParseTuple(args, "|O:demo", &o))
|
if (!PyArg_ParseTuple(args, "|O:demo", &o)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
/* Test availability of fast type checks */
|
/* Test availability of fast type checks */
|
||||||
if (o != NULL && PyUnicode_Check(o)) {
|
if (o != NULL && PyUnicode_Check(o)) {
|
||||||
return Py_NewRef(o);
|
return Py_NewRef(o);
|
||||||
|
@ -74,14 +79,14 @@ Xxo_demo(XxoObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef Xxo_methods[] = {
|
static PyMethodDef Xxo_methods[] = {
|
||||||
{"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
|
{"demo", Xxo_demo, METH_VARARGS, PyDoc_STR("demo() -> None")},
|
||||||
PyDoc_STR("demo() -> None")},
|
{NULL, NULL} /* sentinel */
|
||||||
{NULL, NULL} /* sentinel */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Xxo_getattro(XxoObject *self, PyObject *name)
|
Xxo_getattro(PyObject *op, PyObject *name)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
if (self->x_attr != NULL) {
|
if (self->x_attr != NULL) {
|
||||||
PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
|
PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
|
@ -91,26 +96,28 @@ Xxo_getattro(XxoObject *self, PyObject *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PyObject_GenericGetAttr((PyObject *)self, name);
|
return PyObject_GenericGetAttr(op, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Xxo_setattr(XxoObject *self, const char *name, PyObject *v)
|
Xxo_setattr(PyObject *op, const char *name, PyObject *v)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
if (self->x_attr == NULL) {
|
if (self->x_attr == NULL) {
|
||||||
self->x_attr = PyDict_New();
|
self->x_attr = PyDict_New();
|
||||||
if (self->x_attr == NULL)
|
if (self->x_attr == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
int rv = PyDict_DelItemString(self->x_attr, name);
|
int rv = PyDict_DelItemString(self->x_attr, name);
|
||||||
if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
|
if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||||
PyErr_SetString(PyExc_AttributeError,
|
PyErr_SetString(PyExc_AttributeError,
|
||||||
"delete non-existing Xxo attribute");
|
"delete non-existing Xxo attribute");
|
||||||
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
else
|
return PyDict_SetItemString(self->x_attr, name, v);
|
||||||
return PyDict_SetItemString(self->x_attr, name, v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyType_Slot Xxo_Type_slots[] = {
|
static PyType_Slot Xxo_Type_slots[] = {
|
||||||
|
|
|
@ -25,15 +25,16 @@ typedef struct {
|
||||||
|
|
||||||
static PyTypeObject Xxo_Type;
|
static PyTypeObject Xxo_Type;
|
||||||
|
|
||||||
#define XxoObject_Check(v) Py_IS_TYPE(v, &Xxo_Type)
|
#define XxoObject_CAST(op) ((XxoObject *)(op))
|
||||||
|
#define XxoObject_Check(v) Py_IS_TYPE(v, &Xxo_Type)
|
||||||
|
|
||||||
static XxoObject *
|
static XxoObject *
|
||||||
newXxoObject(PyObject *arg)
|
newXxoObject(PyObject *arg)
|
||||||
{
|
{
|
||||||
XxoObject *self;
|
XxoObject *self = PyObject_New(XxoObject, &Xxo_Type);
|
||||||
self = PyObject_New(XxoObject, &Xxo_Type);
|
if (self == NULL) {
|
||||||
if (self == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
self->x_attr = NULL;
|
self->x_attr = NULL;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -41,29 +42,31 @@ newXxoObject(PyObject *arg)
|
||||||
/* Xxo methods */
|
/* Xxo methods */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Xxo_dealloc(XxoObject *self)
|
Xxo_dealloc(PyObject *op)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
Py_XDECREF(self->x_attr);
|
Py_XDECREF(self->x_attr);
|
||||||
PyObject_Free(self);
|
PyObject_Free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Xxo_demo(XxoObject *self, PyObject *args)
|
Xxo_demo(PyObject *Py_UNUSED(op), PyObject *args)
|
||||||
{
|
{
|
||||||
if (!PyArg_ParseTuple(args, ":demo"))
|
if (!PyArg_ParseTuple(args, ":demo")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return Py_NewRef(Py_None);
|
return Py_NewRef(Py_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef Xxo_methods[] = {
|
static PyMethodDef Xxo_methods[] = {
|
||||||
{"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
|
{"demo", Xxo_demo, METH_VARARGS, PyDoc_STR("demo() -> None")},
|
||||||
PyDoc_STR("demo() -> None")},
|
{NULL, NULL} /* sentinel */
|
||||||
{NULL, NULL} /* sentinel */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Xxo_getattro(XxoObject *self, PyObject *name)
|
Xxo_getattro(PyObject *op, PyObject *name)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
if (self->x_attr != NULL) {
|
if (self->x_attr != NULL) {
|
||||||
PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
|
PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
|
@ -73,26 +76,28 @@ Xxo_getattro(XxoObject *self, PyObject *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PyObject_GenericGetAttr((PyObject *)self, name);
|
return PyObject_GenericGetAttr(op, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Xxo_setattr(XxoObject *self, const char *name, PyObject *v)
|
Xxo_setattr(PyObject *op, const char *name, PyObject *v)
|
||||||
{
|
{
|
||||||
|
XxoObject *self = XxoObject_CAST(op);
|
||||||
if (self->x_attr == NULL) {
|
if (self->x_attr == NULL) {
|
||||||
self->x_attr = PyDict_New();
|
self->x_attr = PyDict_New();
|
||||||
if (self->x_attr == NULL)
|
if (self->x_attr == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
int rv = PyDict_DelItemString(self->x_attr, name);
|
int rv = PyDict_DelItemString(self->x_attr, name);
|
||||||
if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
|
if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||||
PyErr_SetString(PyExc_AttributeError,
|
PyErr_SetString(PyExc_AttributeError,
|
||||||
"delete non-existing Xxo attribute");
|
"delete non-existing Xxo attribute");
|
||||||
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
else
|
return PyDict_SetItemString(self->x_attr, name, v);
|
||||||
return PyDict_SetItemString(self->x_attr, name, v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyTypeObject Xxo_Type = {
|
static PyTypeObject Xxo_Type = {
|
||||||
|
@ -103,10 +108,10 @@ static PyTypeObject Xxo_Type = {
|
||||||
sizeof(XxoObject), /*tp_basicsize*/
|
sizeof(XxoObject), /*tp_basicsize*/
|
||||||
0, /*tp_itemsize*/
|
0, /*tp_itemsize*/
|
||||||
/* methods */
|
/* methods */
|
||||||
(destructor)Xxo_dealloc, /*tp_dealloc*/
|
Xxo_dealloc, /*tp_dealloc*/
|
||||||
0, /*tp_vectorcall_offset*/
|
0, /*tp_vectorcall_offset*/
|
||||||
(getattrfunc)0, /*tp_getattr*/
|
0, /*tp_getattr*/
|
||||||
(setattrfunc)Xxo_setattr, /*tp_setattr*/
|
Xxo_setattr, /*tp_setattr*/
|
||||||
0, /*tp_as_async*/
|
0, /*tp_as_async*/
|
||||||
0, /*tp_repr*/
|
0, /*tp_repr*/
|
||||||
0, /*tp_as_number*/
|
0, /*tp_as_number*/
|
||||||
|
@ -115,7 +120,7 @@ static PyTypeObject Xxo_Type = {
|
||||||
0, /*tp_hash*/
|
0, /*tp_hash*/
|
||||||
0, /*tp_call*/
|
0, /*tp_call*/
|
||||||
0, /*tp_str*/
|
0, /*tp_str*/
|
||||||
(getattrofunc)Xxo_getattro, /*tp_getattro*/
|
Xxo_getattro, /*tp_getattro*/
|
||||||
0, /*tp_setattro*/
|
0, /*tp_setattro*/
|
||||||
0, /*tp_as_buffer*/
|
0, /*tp_as_buffer*/
|
||||||
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
||||||
|
|
|
@ -26,21 +26,26 @@ typedef struct {
|
||||||
int state;
|
int state;
|
||||||
} spamlistobject;
|
} spamlistobject;
|
||||||
|
|
||||||
|
#define _spamlistobject_CAST(op) ((spamlistobject *)(op))
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
spamlist_getstate(spamlistobject *self, PyObject *args)
|
spamlist_getstate(PyObject *op, PyObject *args)
|
||||||
{
|
{
|
||||||
if (!PyArg_ParseTuple(args, ":getstate"))
|
if (!PyArg_ParseTuple(args, ":getstate")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
spamlistobject *self = _spamlistobject_CAST(op);
|
||||||
return PyLong_FromLong(self->state);
|
return PyLong_FromLong(self->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
spamlist_setstate(spamlistobject *self, PyObject *args)
|
spamlist_setstate(PyObject *op, PyObject *args)
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
|
if (!PyArg_ParseTuple(args, "i:setstate", &state)) {
|
||||||
if (!PyArg_ParseTuple(args, "i:setstate", &state))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
spamlistobject *self = _spamlistobject_CAST(op);
|
||||||
self->state = state;
|
self->state = state;
|
||||||
return Py_NewRef(Py_None);
|
return Py_NewRef(Py_None);
|
||||||
}
|
}
|
||||||
|
@ -63,9 +68,9 @@ spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef spamlist_methods[] = {
|
static PyMethodDef spamlist_methods[] = {
|
||||||
{"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS,
|
{"getstate", spamlist_getstate, METH_VARARGS,
|
||||||
PyDoc_STR("getstate() -> state")},
|
PyDoc_STR("getstate() -> state")},
|
||||||
{"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS,
|
{"setstate", spamlist_setstate, METH_VARARGS,
|
||||||
PyDoc_STR("setstate(state)")},
|
PyDoc_STR("setstate(state)")},
|
||||||
/* These entries differ only in the flags; they are used by the tests
|
/* These entries differ only in the flags; they are used by the tests
|
||||||
in test.test_descr. */
|
in test.test_descr. */
|
||||||
|
@ -79,22 +84,25 @@ static PyMethodDef spamlist_methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
|
spamlist_init(PyObject *op, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
|
if (PyList_Type.tp_init(op, args, kwds) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
spamlistobject *self = _spamlistobject_CAST(op);
|
||||||
self->state = 0;
|
self->state = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
spamlist_state_get(spamlistobject *self, void *Py_UNUSED(ignored))
|
spamlist_state_get(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
spamlistobject *self = _spamlistobject_CAST(op);
|
||||||
return PyLong_FromLong(self->state);
|
return PyLong_FromLong(self->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyGetSetDef spamlist_getsets[] = {
|
static PyGetSetDef spamlist_getsets[] = {
|
||||||
{"state", (getter)spamlist_state_get, NULL,
|
{"state", spamlist_state_get, NULL,
|
||||||
PyDoc_STR("an int variable for demonstration purposes")},
|
PyDoc_STR("an int variable for demonstration purposes")},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
@ -135,7 +143,7 @@ static PyTypeObject spamlist_type = {
|
||||||
0, /* tp_descr_get */
|
0, /* tp_descr_get */
|
||||||
0, /* tp_descr_set */
|
0, /* tp_descr_set */
|
||||||
0, /* tp_dictoffset */
|
0, /* tp_dictoffset */
|
||||||
(initproc)spamlist_init, /* tp_init */
|
spamlist_init, /* tp_init */
|
||||||
0, /* tp_alloc */
|
0, /* tp_alloc */
|
||||||
0, /* tp_new */
|
0, /* tp_new */
|
||||||
};
|
};
|
||||||
|
@ -147,38 +155,46 @@ typedef struct {
|
||||||
int state;
|
int state;
|
||||||
} spamdictobject;
|
} spamdictobject;
|
||||||
|
|
||||||
|
#define _spamdictobject_CAST(op) ((spamdictobject *)(op))
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
spamdict_getstate(spamdictobject *self, PyObject *args)
|
spamdict_getstate(PyObject *op, PyObject *args)
|
||||||
{
|
{
|
||||||
if (!PyArg_ParseTuple(args, ":getstate"))
|
if (!PyArg_ParseTuple(args, ":getstate")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
spamdictobject *self = _spamdictobject_CAST(op);
|
||||||
return PyLong_FromLong(self->state);
|
return PyLong_FromLong(self->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
spamdict_setstate(spamdictobject *self, PyObject *args)
|
spamdict_setstate(PyObject *op, PyObject *args)
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
|
if (!PyArg_ParseTuple(args, "i:setstate", &state)) {
|
||||||
if (!PyArg_ParseTuple(args, "i:setstate", &state))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
spamdictobject *self = _spamdictobject_CAST(op);
|
||||||
self->state = state;
|
self->state = state;
|
||||||
return Py_NewRef(Py_None);
|
return Py_NewRef(Py_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef spamdict_methods[] = {
|
static PyMethodDef spamdict_methods[] = {
|
||||||
{"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS,
|
{"getstate", spamdict_getstate, METH_VARARGS,
|
||||||
PyDoc_STR("getstate() -> state")},
|
PyDoc_STR("getstate() -> state")},
|
||||||
{"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS,
|
{"setstate", spamdict_setstate, METH_VARARGS,
|
||||||
PyDoc_STR("setstate(state)")},
|
PyDoc_STR("setstate(state)")},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
|
spamdict_init(PyObject *op, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
|
if (PyDict_Type.tp_init(op, args, kwds) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
spamdictobject *self = _spamdictobject_CAST(op);
|
||||||
self->state = 0;
|
self->state = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +241,7 @@ static PyTypeObject spamdict_type = {
|
||||||
0, /* tp_descr_get */
|
0, /* tp_descr_get */
|
||||||
0, /* tp_descr_set */
|
0, /* tp_descr_set */
|
||||||
0, /* tp_dictoffset */
|
0, /* tp_dictoffset */
|
||||||
(initproc)spamdict_init, /* tp_init */
|
spamdict_init, /* tp_init */
|
||||||
0, /* tp_alloc */
|
0, /* tp_alloc */
|
||||||
0, /* tp_new */
|
0, /* tp_new */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue