Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Doc/includes/custom3.c
12 views
1
#define PY_SSIZE_T_CLEAN
2
#include <Python.h>
3
#include <stddef.h> /* for offsetof() */
4
5
typedef struct {
6
PyObject_HEAD
7
PyObject *first; /* first name */
8
PyObject *last; /* last name */
9
int number;
10
} CustomObject;
11
12
static void
13
Custom_dealloc(CustomObject *self)
14
{
15
Py_XDECREF(self->first);
16
Py_XDECREF(self->last);
17
Py_TYPE(self)->tp_free((PyObject *) self);
18
}
19
20
static PyObject *
21
Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
22
{
23
CustomObject *self;
24
self = (CustomObject *) type->tp_alloc(type, 0);
25
if (self != NULL) {
26
self->first = PyUnicode_FromString("");
27
if (self->first == NULL) {
28
Py_DECREF(self);
29
return NULL;
30
}
31
self->last = PyUnicode_FromString("");
32
if (self->last == NULL) {
33
Py_DECREF(self);
34
return NULL;
35
}
36
self->number = 0;
37
}
38
return (PyObject *) self;
39
}
40
41
static int
42
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
43
{
44
static char *kwlist[] = {"first", "last", "number", NULL};
45
PyObject *first = NULL, *last = NULL;
46
47
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
48
&first, &last,
49
&self->number))
50
return -1;
51
52
if (first) {
53
Py_SETREF(self->first, Py_NewRef(first));
54
}
55
if (last) {
56
Py_SETREF(self->last, Py_NewRef(last));
57
}
58
return 0;
59
}
60
61
static PyMemberDef Custom_members[] = {
62
{"number", Py_T_INT, offsetof(CustomObject, number), 0,
63
"custom number"},
64
{NULL} /* Sentinel */
65
};
66
67
static PyObject *
68
Custom_getfirst(CustomObject *self, void *closure)
69
{
70
return Py_NewRef(self->first);
71
}
72
73
static int
74
Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
75
{
76
if (value == NULL) {
77
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
78
return -1;
79
}
80
if (!PyUnicode_Check(value)) {
81
PyErr_SetString(PyExc_TypeError,
82
"The first attribute value must be a string");
83
return -1;
84
}
85
Py_SETREF(self->first, Py_NewRef(value));
86
return 0;
87
}
88
89
static PyObject *
90
Custom_getlast(CustomObject *self, void *closure)
91
{
92
return Py_NewRef(self->last);
93
}
94
95
static int
96
Custom_setlast(CustomObject *self, PyObject *value, void *closure)
97
{
98
if (value == NULL) {
99
PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
100
return -1;
101
}
102
if (!PyUnicode_Check(value)) {
103
PyErr_SetString(PyExc_TypeError,
104
"The last attribute value must be a string");
105
return -1;
106
}
107
Py_SETREF(self->last, Py_NewRef(value));
108
return 0;
109
}
110
111
static PyGetSetDef Custom_getsetters[] = {
112
{"first", (getter) Custom_getfirst, (setter) Custom_setfirst,
113
"first name", NULL},
114
{"last", (getter) Custom_getlast, (setter) Custom_setlast,
115
"last name", NULL},
116
{NULL} /* Sentinel */
117
};
118
119
static PyObject *
120
Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
121
{
122
return PyUnicode_FromFormat("%S %S", self->first, self->last);
123
}
124
125
static PyMethodDef Custom_methods[] = {
126
{"name", (PyCFunction) Custom_name, METH_NOARGS,
127
"Return the name, combining the first and last name"
128
},
129
{NULL} /* Sentinel */
130
};
131
132
static PyTypeObject CustomType = {
133
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
134
.tp_name = "custom3.Custom",
135
.tp_doc = PyDoc_STR("Custom objects"),
136
.tp_basicsize = sizeof(CustomObject),
137
.tp_itemsize = 0,
138
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
139
.tp_new = Custom_new,
140
.tp_init = (initproc) Custom_init,
141
.tp_dealloc = (destructor) Custom_dealloc,
142
.tp_members = Custom_members,
143
.tp_methods = Custom_methods,
144
.tp_getset = Custom_getsetters,
145
};
146
147
static PyModuleDef custommodule = {
148
.m_base = PyModuleDef_HEAD_INIT,
149
.m_name = "custom3",
150
.m_doc = "Example module that creates an extension type.",
151
.m_size = -1,
152
};
153
154
PyMODINIT_FUNC
155
PyInit_custom3(void)
156
{
157
PyObject *m;
158
if (PyType_Ready(&CustomType) < 0)
159
return NULL;
160
161
m = PyModule_Create(&custommodule);
162
if (m == NULL)
163
return NULL;
164
165
if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) {
166
Py_DECREF(m);
167
return NULL;
168
}
169
170
return m;
171
}
172
173