Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Doc/includes/custom2.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, "|OOi", kwlist,
48
&first, &last,
49
&self->number))
50
return -1;
51
52
if (first) {
53
Py_XSETREF(self->first, Py_NewRef(first));
54
}
55
if (last) {
56
Py_XSETREF(self->last, Py_NewRef(last));
57
}
58
return 0;
59
}
60
61
static PyMemberDef Custom_members[] = {
62
{"first", Py_T_OBJECT_EX, offsetof(CustomObject, first), 0,
63
"first name"},
64
{"last", Py_T_OBJECT_EX, offsetof(CustomObject, last), 0,
65
"last name"},
66
{"number", Py_T_INT, offsetof(CustomObject, number), 0,
67
"custom number"},
68
{NULL} /* Sentinel */
69
};
70
71
static PyObject *
72
Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
73
{
74
if (self->first == NULL) {
75
PyErr_SetString(PyExc_AttributeError, "first");
76
return NULL;
77
}
78
if (self->last == NULL) {
79
PyErr_SetString(PyExc_AttributeError, "last");
80
return NULL;
81
}
82
return PyUnicode_FromFormat("%S %S", self->first, self->last);
83
}
84
85
static PyMethodDef Custom_methods[] = {
86
{"name", (PyCFunction) Custom_name, METH_NOARGS,
87
"Return the name, combining the first and last name"
88
},
89
{NULL} /* Sentinel */
90
};
91
92
static PyTypeObject CustomType = {
93
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
94
.tp_name = "custom2.Custom",
95
.tp_doc = PyDoc_STR("Custom objects"),
96
.tp_basicsize = sizeof(CustomObject),
97
.tp_itemsize = 0,
98
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
99
.tp_new = Custom_new,
100
.tp_init = (initproc) Custom_init,
101
.tp_dealloc = (destructor) Custom_dealloc,
102
.tp_members = Custom_members,
103
.tp_methods = Custom_methods,
104
};
105
106
static PyModuleDef custommodule = {
107
.m_base =PyModuleDef_HEAD_INIT,
108
.m_name = "custom2",
109
.m_doc = "Example module that creates an extension type.",
110
.m_size = -1,
111
};
112
113
PyMODINIT_FUNC
114
PyInit_custom2(void)
115
{
116
PyObject *m;
117
if (PyType_Ready(&CustomType) < 0)
118
return NULL;
119
120
m = PyModule_Create(&custommodule);
121
if (m == NULL)
122
return NULL;
123
124
if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) {
125
Py_DECREF(m);
126
return NULL;
127
}
128
129
return m;
130
}
131
132