Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Objects/interpreteridobject.c
12 views
1
/* InterpreterID object */
2
3
#include "Python.h"
4
#include "pycore_abstract.h" // _PyIndex_Check()
5
#include "pycore_interp.h" // _PyInterpreterState_LookUpID()
6
#include "interpreteridobject.h"
7
8
9
typedef struct interpid {
10
PyObject_HEAD
11
int64_t id;
12
} interpid;
13
14
static interpid *
15
newinterpid(PyTypeObject *cls, int64_t id, int force)
16
{
17
PyInterpreterState *interp = _PyInterpreterState_LookUpID(id);
18
if (interp == NULL) {
19
if (force) {
20
PyErr_Clear();
21
}
22
else {
23
return NULL;
24
}
25
}
26
27
if (interp != NULL) {
28
if (_PyInterpreterState_IDIncref(interp) < 0) {
29
return NULL;
30
}
31
}
32
33
interpid *self = PyObject_New(interpid, cls);
34
if (self == NULL) {
35
if (interp != NULL) {
36
_PyInterpreterState_IDDecref(interp);
37
}
38
return NULL;
39
}
40
self->id = id;
41
42
return self;
43
}
44
45
static int
46
interp_id_converter(PyObject *arg, void *ptr)
47
{
48
int64_t id;
49
if (PyObject_TypeCheck(arg, &_PyInterpreterID_Type)) {
50
id = ((interpid *)arg)->id;
51
}
52
else if (_PyIndex_Check(arg)) {
53
id = PyLong_AsLongLong(arg);
54
if (id == -1 && PyErr_Occurred()) {
55
return 0;
56
}
57
if (id < 0) {
58
PyErr_Format(PyExc_ValueError,
59
"interpreter ID must be a non-negative int, got %R", arg);
60
return 0;
61
}
62
}
63
else {
64
PyErr_Format(PyExc_TypeError,
65
"interpreter ID must be an int, got %.100s",
66
Py_TYPE(arg)->tp_name);
67
return 0;
68
}
69
*(int64_t *)ptr = id;
70
return 1;
71
}
72
73
static PyObject *
74
interpid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds)
75
{
76
static char *kwlist[] = {"id", "force", NULL};
77
int64_t id;
78
int force = 0;
79
if (!PyArg_ParseTupleAndKeywords(args, kwds,
80
"O&|$p:InterpreterID.__init__", kwlist,
81
interp_id_converter, &id, &force)) {
82
return NULL;
83
}
84
85
return (PyObject *)newinterpid(cls, id, force);
86
}
87
88
static void
89
interpid_dealloc(PyObject *v)
90
{
91
int64_t id = ((interpid *)v)->id;
92
PyInterpreterState *interp = _PyInterpreterState_LookUpID(id);
93
if (interp != NULL) {
94
_PyInterpreterState_IDDecref(interp);
95
}
96
else {
97
// already deleted
98
PyErr_Clear();
99
}
100
Py_TYPE(v)->tp_free(v);
101
}
102
103
static PyObject *
104
interpid_repr(PyObject *self)
105
{
106
PyTypeObject *type = Py_TYPE(self);
107
const char *name = _PyType_Name(type);
108
interpid *id = (interpid *)self;
109
return PyUnicode_FromFormat("%s(%" PRId64 ")", name, id->id);
110
}
111
112
static PyObject *
113
interpid_str(PyObject *self)
114
{
115
interpid *id = (interpid *)self;
116
return PyUnicode_FromFormat("%" PRId64 "", id->id);
117
}
118
119
static PyObject *
120
interpid_int(PyObject *self)
121
{
122
interpid *id = (interpid *)self;
123
return PyLong_FromLongLong(id->id);
124
}
125
126
static PyNumberMethods interpid_as_number = {
127
0, /* nb_add */
128
0, /* nb_subtract */
129
0, /* nb_multiply */
130
0, /* nb_remainder */
131
0, /* nb_divmod */
132
0, /* nb_power */
133
0, /* nb_negative */
134
0, /* nb_positive */
135
0, /* nb_absolute */
136
0, /* nb_bool */
137
0, /* nb_invert */
138
0, /* nb_lshift */
139
0, /* nb_rshift */
140
0, /* nb_and */
141
0, /* nb_xor */
142
0, /* nb_or */
143
(unaryfunc)interpid_int, /* nb_int */
144
0, /* nb_reserved */
145
0, /* nb_float */
146
147
0, /* nb_inplace_add */
148
0, /* nb_inplace_subtract */
149
0, /* nb_inplace_multiply */
150
0, /* nb_inplace_remainder */
151
0, /* nb_inplace_power */
152
0, /* nb_inplace_lshift */
153
0, /* nb_inplace_rshift */
154
0, /* nb_inplace_and */
155
0, /* nb_inplace_xor */
156
0, /* nb_inplace_or */
157
158
0, /* nb_floor_divide */
159
0, /* nb_true_divide */
160
0, /* nb_inplace_floor_divide */
161
0, /* nb_inplace_true_divide */
162
163
(unaryfunc)interpid_int, /* nb_index */
164
};
165
166
static Py_hash_t
167
interpid_hash(PyObject *self)
168
{
169
interpid *id = (interpid *)self;
170
PyObject *obj = PyLong_FromLongLong(id->id);
171
if (obj == NULL) {
172
return -1;
173
}
174
Py_hash_t hash = PyObject_Hash(obj);
175
Py_DECREF(obj);
176
return hash;
177
}
178
179
static PyObject *
180
interpid_richcompare(PyObject *self, PyObject *other, int op)
181
{
182
if (op != Py_EQ && op != Py_NE) {
183
Py_RETURN_NOTIMPLEMENTED;
184
}
185
186
if (!PyObject_TypeCheck(self, &_PyInterpreterID_Type)) {
187
Py_RETURN_NOTIMPLEMENTED;
188
}
189
190
interpid *id = (interpid *)self;
191
int equal;
192
if (PyObject_TypeCheck(other, &_PyInterpreterID_Type)) {
193
interpid *otherid = (interpid *)other;
194
equal = (id->id == otherid->id);
195
}
196
else if (PyLong_CheckExact(other)) {
197
/* Fast path */
198
int overflow;
199
long long otherid = PyLong_AsLongLongAndOverflow(other, &overflow);
200
if (otherid == -1 && PyErr_Occurred()) {
201
return NULL;
202
}
203
equal = !overflow && (otherid >= 0) && (id->id == otherid);
204
}
205
else if (PyNumber_Check(other)) {
206
PyObject *pyid = PyLong_FromLongLong(id->id);
207
if (pyid == NULL) {
208
return NULL;
209
}
210
PyObject *res = PyObject_RichCompare(pyid, other, op);
211
Py_DECREF(pyid);
212
return res;
213
}
214
else {
215
Py_RETURN_NOTIMPLEMENTED;
216
}
217
218
if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) {
219
Py_RETURN_TRUE;
220
}
221
Py_RETURN_FALSE;
222
}
223
224
PyDoc_STRVAR(interpid_doc,
225
"A interpreter ID identifies a interpreter and may be used as an int.");
226
227
PyTypeObject _PyInterpreterID_Type = {
228
PyVarObject_HEAD_INIT(&PyType_Type, 0)
229
"InterpreterID", /* tp_name */
230
sizeof(interpid), /* tp_basicsize */
231
0, /* tp_itemsize */
232
(destructor)interpid_dealloc, /* tp_dealloc */
233
0, /* tp_vectorcall_offset */
234
0, /* tp_getattr */
235
0, /* tp_setattr */
236
0, /* tp_as_async */
237
(reprfunc)interpid_repr, /* tp_repr */
238
&interpid_as_number, /* tp_as_number */
239
0, /* tp_as_sequence */
240
0, /* tp_as_mapping */
241
interpid_hash, /* tp_hash */
242
0, /* tp_call */
243
(reprfunc)interpid_str, /* tp_str */
244
0, /* tp_getattro */
245
0, /* tp_setattro */
246
0, /* tp_as_buffer */
247
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
248
interpid_doc, /* tp_doc */
249
0, /* tp_traverse */
250
0, /* tp_clear */
251
interpid_richcompare, /* tp_richcompare */
252
0, /* tp_weaklistoffset */
253
0, /* tp_iter */
254
0, /* tp_iternext */
255
0, /* tp_methods */
256
0, /* tp_members */
257
0, /* tp_getset */
258
0, /* tp_base */
259
0, /* tp_dict */
260
0, /* tp_descr_get */
261
0, /* tp_descr_set */
262
0, /* tp_dictoffset */
263
0, /* tp_init */
264
0, /* tp_alloc */
265
interpid_new, /* tp_new */
266
};
267
268
PyObject *_PyInterpreterID_New(int64_t id)
269
{
270
return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0);
271
}
272
273
PyObject *
274
_PyInterpreterState_GetIDObject(PyInterpreterState *interp)
275
{
276
if (_PyInterpreterState_IDInitref(interp) != 0) {
277
return NULL;
278
};
279
int64_t id = PyInterpreterState_GetID(interp);
280
if (id < 0) {
281
return NULL;
282
}
283
return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0);
284
}
285
286
PyInterpreterState *
287
_PyInterpreterID_LookUp(PyObject *requested_id)
288
{
289
int64_t id;
290
if (!interp_id_converter(requested_id, &id)) {
291
return NULL;
292
}
293
return _PyInterpreterState_LookUpID(id);
294
}
295
296