Showing the changes to sys/src/cmd/python/Objects (44 of 3706 files). Show all
Unified · Split
| @@ -0,0 +1,2381 @@ | ||
| 1 | +/* Abstract Object Interface (many thanks to Jim Fulton) */ | |
| 2 | + | |
| 3 | +#include "Python.h" | |
| 4 | +#include <ctype.h> | |
| 5 | +#include "structmember.h" /* we need the offsetof() macro from there */ | |
| 6 | +#include "longintrepr.h" | |
| 7 | + | |
| 8 | +#define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \ | |
| 9 | + Py_TPFLAGS_CHECKTYPES) | |
| 10 | + | |
| 11 | + | |
| 12 | +/* Shorthands to return certain errors */ | |
| 13 | + | |
| 14 | +static PyObject * | |
| 15 | +type_error(const char *msg, PyObject *obj) | |
| 16 | +{ | |
| 17 | + PyErr_Format(PyExc_TypeError, msg, obj->ob_type->tp_name); | |
| 18 | + return NULL; | |
| 19 | +} | |
| 20 | + | |
| 21 | +static PyObject * | |
| 22 | +null_error(void) | |
| 23 | +{ | |
| 24 | + if (!PyErr_Occurred()) | |
| 25 | + PyErr_SetString(PyExc_SystemError, | |
| 26 | + "null argument to internal routine"); | |
| 27 | + return NULL; | |
| 28 | +} | |
| 29 | + | |
| 30 | +/* Operations on any object */ | |
| 31 | + | |
| 32 | +int | |
| 33 | +PyObject_Cmp(PyObject *o1, PyObject *o2, int *result) | |
| 34 | +{ | |
| 35 | + int r; | |
| 36 | + | |
| 37 | + if (o1 == NULL || o2 == NULL) { | |
| 38 | + null_error(); | |
| 39 | + return -1; | |
| 40 | + } | |
| 41 | + r = PyObject_Compare(o1, o2); | |
| 42 | + if (PyErr_Occurred()) | |
| 43 | + return -1; | |
| 44 | + *result = r; | |
| 45 | + return 0; | |
| 46 | +} | |
| 47 | + | |
| 48 | +PyObject * | |
| 49 | +PyObject_Type(PyObject *o) | |
| 50 | +{ | |
| 51 | + PyObject *v; | |
| 52 | + | |
| 53 | + if (o == NULL) | |
| 54 | + return null_error(); | |
| 55 | + v = (PyObject *)o->ob_type; | |
| 56 | + Py_INCREF(v); | |
| 57 | + return v; | |
| 58 | +} | |
| 59 | + | |
| 60 | +Py_ssize_t | |
| 61 | +PyObject_Size(PyObject *o) | |
| 62 | +{ | |
| 63 | + PySequenceMethods *m; | |
| 64 | + | |
| 65 | + if (o == NULL) { | |
| 66 | + null_error(); | |
| 67 | + return -1; | |
| 68 | + } | |
| 69 | + | |
| 70 | + m = o->ob_type->tp_as_sequence; | |
| 71 | + if (m && m->sq_length) | |
| 72 | + return m->sq_length(o); | |
| 73 | + | |
| 74 | + return PyMapping_Size(o); | |
| 75 | +} | |
| 76 | + | |
| 77 | +#undef PyObject_Length | |
| 78 | +Py_ssize_t | |
| 79 | +PyObject_Length(PyObject *o) | |
| 80 | +{ | |
| 81 | + return PyObject_Size(o); | |
| 82 | +} | |
| 83 | +#define PyObject_Length PyObject_Size | |
| 84 | + | |
| 85 | +Py_ssize_t | |
| 86 | +_PyObject_LengthHint(PyObject *o) | |
| 87 | +{ | |
| 88 | + Py_ssize_t rv = PyObject_Size(o); | |
| 89 | + if (rv != -1) | |
| 90 | + return rv; | |
| 91 | + if (PyErr_ExceptionMatches(PyExc_TypeError) || | |
| 92 | + PyErr_ExceptionMatches(PyExc_AttributeError)) { | |
| 93 | + PyObject *err_type, *err_value, *err_tb, *ro; | |
| 94 | + | |
| 95 | + PyErr_Fetch(&err_type, &err_value, &err_tb); | |
| 96 | + ro = PyObject_CallMethod(o, "__length_hint__", NULL); | |
| 97 | + if (ro != NULL) { | |
| 98 | + rv = PyInt_AsLong(ro); | |
| 99 | + Py_DECREF(ro); | |
| 100 | + Py_XDECREF(err_type); | |
| 101 | + Py_XDECREF(err_value); | |
| 102 | + Py_XDECREF(err_tb); | |
| 103 | + return rv; | |
| 104 | + } | |
| 105 | + PyErr_Restore(err_type, err_value, err_tb); | |
| 106 | + } | |
| 107 | + return -1; | |
| 108 | +} | |
| 109 | + | |
| 110 | +PyObject * | |
| 111 | +PyObject_GetItem(PyObject *o, PyObject *key) | |
| 112 | +{ | |
| 113 | + PyMappingMethods *m; | |
| 114 | + | |
| 115 | + if (o == NULL || key == NULL) | |
| 116 | + return null_error(); | |
| 117 | + | |
| 118 | + m = o->ob_type->tp_as_mapping; | |
| 119 | + if (m && m->mp_subscript) | |
| 120 | + return m->mp_subscript(o, key); | |
| 121 | + | |
| 122 | + if (o->ob_type->tp_as_sequence) { | |
| 123 | + if (PyIndex_Check(key)) { | |
| 124 | + Py_ssize_t key_value; | |
| 125 | + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); | |
| 126 | + if (key_value == -1 && PyErr_Occurred()) | |
| 127 | + return NULL; | |
| 128 | + return PySequence_GetItem(o, key_value); | |
| 129 | + } | |
| 130 | + else if (o->ob_type->tp_as_sequence->sq_item) | |
| 131 | + return type_error("sequence index must " | |
| 132 | + "be integer, not '%.200s'", key); | |
| 133 | + } | |
| 134 | + | |
| 135 | + return type_error("'%.200s' object is unsubscriptable", o); | |
| 136 | +} | |
| 137 | + | |
| 138 | +int | |
| 139 | +PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) | |
| 140 | +{ | |
| 141 | + PyMappingMethods *m; | |
| 142 | + | |
| 143 | + if (o == NULL || key == NULL || value == NULL) { | |
| 144 | + null_error(); | |
| 145 | + return -1; | |
| 146 | + } | |
| 147 | + m = o->ob_type->tp_as_mapping; | |
| 148 | + if (m && m->mp_ass_subscript) | |
| 149 | + return m->mp_ass_subscript(o, key, value); | |
| 150 | + | |
| 151 | + if (o->ob_type->tp_as_sequence) { | |
| 152 | + if (PyIndex_Check(key)) { | |
| 153 | + Py_ssize_t key_value; | |
| 154 | + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); | |
| 155 | + if (key_value == -1 && PyErr_Occurred()) | |
| 156 | + return -1; | |
| 157 | + return PySequence_SetItem(o, key_value, value); | |
| 158 | + } | |
| 159 | + else if (o->ob_type->tp_as_sequence->sq_ass_item) { | |
| 160 | + type_error("sequence index must be " | |
| 161 | + "integer, not '%.200s'", key); | |
| 162 | + return -1; | |
| 163 | + } | |
| 164 | + } | |
| 165 | + | |
| 166 | + type_error("'%.200s' object does not support item assignment", o); | |
| 167 | + return -1; | |
| 168 | +} | |
| 169 | + | |
| 170 | +int | |
| 171 | +PyObject_DelItem(PyObject *o, PyObject *key) | |
| 172 | +{ | |
| 173 | + PyMappingMethods *m; | |
| 174 | + | |
| 175 | + if (o == NULL || key == NULL) { | |
| 176 | + null_error(); | |
| 177 | + return -1; | |
| 178 | + } | |
| 179 | + m = o->ob_type->tp_as_mapping; | |
| 180 | + if (m && m->mp_ass_subscript) | |
| 181 | + return m->mp_ass_subscript(o, key, (PyObject*)NULL); | |
| 182 | + | |
| 183 | + if (o->ob_type->tp_as_sequence) { | |
| 184 | + if (PyIndex_Check(key)) { | |
| 185 | + Py_ssize_t key_value; | |
| 186 | + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); | |
| 187 | + if (key_value == -1 && PyErr_Occurred()) | |
| 188 | + return -1; | |
| 189 | + return PySequence_DelItem(o, key_value); | |
| 190 | + } | |
| 191 | + else if (o->ob_type->tp_as_sequence->sq_ass_item) { | |
| 192 | + type_error("sequence index must be " | |
| 193 | + "integer, not '%.200s'", key); | |
| 194 | + return -1; | |
| 195 | + } | |
| 196 | + } | |
| 197 | + | |
| 198 | + type_error("'%.200s' object does not support item deletion", o); | |
| 199 | + return -1; | |
| 200 | +} | |
| 201 | + | |
| 202 | +int | |
| 203 | +PyObject_DelItemString(PyObject *o, char *key) | |
| 204 | +{ | |
| 205 | + PyObject *okey; | |
| 206 | + int ret; | |
| 207 | + | |
| 208 | + if (o == NULL || key == NULL) { | |
| 209 | + null_error(); | |
| 210 | + return -1; | |
| 211 | + } | |
| 212 | + okey = PyString_FromString(key); | |
| 213 | + if (okey == NULL) | |
| 214 | + return -1; | |
| 215 | + ret = PyObject_DelItem(o, okey); | |
| 216 | + Py_DECREF(okey); | |
| 217 | + return ret; | |
| 218 | +} | |
| 219 | + | |
| 220 | +int | |
| 221 | +PyObject_AsCharBuffer(PyObject *obj, | |
| 222 | + const char **buffer, | |
| 223 | + Py_ssize_t *buffer_len) | |
| 224 | +{ | |
| 225 | + PyBufferProcs *pb; | |
| 226 | + char *pp; | |
| 227 | + Py_ssize_t len; | |
| 228 | + | |
| 229 | + if (obj == NULL || buffer == NULL || buffer_len == NULL) { | |
| 230 | + null_error(); | |
| 231 | + return -1; | |
| 232 | + } | |
| 233 | + pb = obj->ob_type->tp_as_buffer; | |
| 234 | + if (pb == NULL || | |
| 235 | + pb->bf_getcharbuffer == NULL || | |
| 236 | + pb->bf_getsegcount == NULL) { | |
| 237 | + PyErr_SetString(PyExc_TypeError, | |
| 238 | + "expected a character buffer object"); | |
| 239 | + return -1; | |
| 240 | + } | |
| 241 | + if ((*pb->bf_getsegcount)(obj,NULL) != 1) { | |
| 242 | + PyErr_SetString(PyExc_TypeError, | |
| 243 | + "expected a single-segment buffer object"); | |
| 244 | + return -1; | |
| 245 | + } | |
| 246 | + len = (*pb->bf_getcharbuffer)(obj, 0, &pp); | |
| 247 | + if (len < 0) | |
| 248 | + return -1; | |
| 249 | + *buffer = pp; | |
| 250 | + *buffer_len = len; | |
| 251 | + return 0; | |
| 252 | +} | |
| 253 | + | |
| 254 | +int | |
| 255 | +PyObject_CheckReadBuffer(PyObject *obj) | |
| 256 | +{ | |
| 257 | + PyBufferProcs *pb = obj->ob_type->tp_as_buffer; | |
| 258 | + | |
| 259 | + if (pb == NULL || | |
| 260 | + pb->bf_getreadbuffer == NULL || | |
| 261 | + pb->bf_getsegcount == NULL || | |
| 262 | + (*pb->bf_getsegcount)(obj, NULL) != 1) | |
| 263 | + return 0; | |
| 264 | + return 1; | |
| 265 | +} | |
| 266 | + | |
| 267 | +int PyObject_AsReadBuffer(PyObject *obj, | |
| 268 | + const void **buffer, | |
| 269 | + Py_ssize_t *buffer_len) | |
| 270 | +{ | |
| 271 | + PyBufferProcs *pb; | |
| 272 | + void *pp; | |
| 273 | + Py_ssize_t len; | |
| 274 | + | |
| 275 | + if (obj == NULL || buffer == NULL || buffer_len == NULL) { | |
| 276 | + null_error(); | |
| 277 | + return -1; | |
| 278 | + } | |
| 279 | + pb = obj->ob_type->tp_as_buffer; | |
| 280 | + if (pb == NULL || | |
| 281 | + pb->bf_getreadbuffer == NULL || | |
| 282 | + pb->bf_getsegcount == NULL) { | |
| 283 | + PyErr_SetString(PyExc_TypeError, | |
| 284 | + "expected a readable buffer object"); | |
| 285 | + return -1; | |
| 286 | + } | |
| 287 | + if ((*pb->bf_getsegcount)(obj, NULL) != 1) { | |
| 288 | + PyErr_SetString(PyExc_TypeError, | |
| 289 | + "expected a single-segment buffer object"); | |
| 290 | + return -1; | |
| 291 | + } | |
| 292 | + len = (*pb->bf_getreadbuffer)(obj, 0, &pp); | |
| 293 | + if (len < 0) | |
| 294 | + return -1; | |
| 295 | + *buffer = pp; | |
| 296 | + *buffer_len = len; | |
| 297 | + return 0; | |
| 298 | +} | |
| 299 | + | |
| 300 | +int PyObject_AsWriteBuffer(PyObject *obj, | |
| 301 | + void **buffer, | |
| 302 | + Py_ssize_t *buffer_len) | |
| 303 | +{ | |
| 304 | + PyBufferProcs *pb; | |
| 305 | + void*pp; | |
| 306 | + Py_ssize_t len; | |
| 307 | + | |
| 308 | + if (obj == NULL || buffer == NULL || buffer_len == NULL) { | |
| 309 | + null_error(); | |
| 310 | + return -1; | |
| 311 | + } | |
| 312 | + pb = obj->ob_type->tp_as_buffer; | |
| 313 | + if (pb == NULL || | |
| 314 | + pb->bf_getwritebuffer == NULL || | |
| 315 | + pb->bf_getsegcount == NULL) { | |
| 316 | + PyErr_SetString(PyExc_TypeError, | |
| 317 | + "expected a writeable buffer object"); | |
| 318 | + return -1; | |
| 319 | + } | |
| 320 | + if ((*pb->bf_getsegcount)(obj, NULL) != 1) { | |
| 321 | + PyErr_SetString(PyExc_TypeError, | |
| 322 | + "expected a single-segment buffer object"); | |
| 323 | + return -1; | |
| 324 | + } | |
| 325 | + len = (*pb->bf_getwritebuffer)(obj,0,&pp); | |
| 326 | + if (len < 0) | |
| 327 | + return -1; | |
| 328 | + *buffer = pp; | |
| 329 | + *buffer_len = len; | |
| 330 | + return 0; | |
| 331 | +} | |
| 332 | + | |
| 333 | +/* Operations on numbers */ | |
| 334 | + | |
| 335 | +int | |
| 336 | +PyNumber_Check(PyObject *o) | |
| 337 | +{ | |
| 338 | + return o && o->ob_type->tp_as_number && | |
| 339 | + (o->ob_type->tp_as_number->nb_int || | |
| 340 | + o->ob_type->tp_as_number->nb_float); | |
| 341 | +} | |
| 342 | + | |
| 343 | +/* Binary operators */ | |
| 344 | + | |
| 345 | +/* New style number protocol support */ | |
| 346 | + | |
| 347 | +#define NB_SLOT(x) offsetof(PyNumberMethods, x) | |
| 348 | +#define NB_BINOP(nb_methods, slot) \ | |
| 349 | + (*(binaryfunc*)(& ((char*)nb_methods)[slot])) | |
| 350 | +#define NB_TERNOP(nb_methods, slot) \ | |
| 351 | + (*(ternaryfunc*)(& ((char*)nb_methods)[slot])) | |
| 352 | + | |
| 353 | +/* | |
| 354 | + Calling scheme used for binary operations: | |
| 355 | + | |
| 356 | + v w Action | |
| 357 | + ------------------------------------------------------------------- | |
| 358 | + new new w.op(v,w)[*], v.op(v,w), w.op(v,w) | |
| 359 | + new old v.op(v,w), coerce(v,w), v.op(v,w) | |
| 360 | + old new w.op(v,w), coerce(v,w), v.op(v,w) | |
| 361 | + old old coerce(v,w), v.op(v,w) | |
| 362 | + | |
| 363 | + [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of | |
| 364 | + v->ob_type | |
| 365 | + | |
| 366 | + Legend: | |
| 367 | + ------- | |
| 368 | + * new == new style number | |
| 369 | + * old == old style number | |
| 370 | + * Action indicates the order in which operations are tried until either | |
| 371 | + a valid result is produced or an error occurs. | |
| 372 | + | |
| 373 | + */ | |
| 374 | + | |
| 375 | +static PyObject * | |
| 376 | +binary_op1(PyObject *v, PyObject *w, const int op_slot) | |
| 377 | +{ | |
| 378 | + PyObject *x; | |
| 379 | + binaryfunc slotv = NULL; | |
| 380 | + binaryfunc slotw = NULL; | |
| 381 | + | |
| 382 | + if (v->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(v)) | |
| 383 | + slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot); | |
| 384 | + if (w->ob_type != v->ob_type && | |
| 385 | + w->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(w)) { | |
| 386 | + slotw = NB_BINOP(w->ob_type->tp_as_number, op_slot); | |
| 387 | + if (slotw == slotv) | |
| 388 | + slotw = NULL; | |
| 389 | + } | |
| 390 | + if (slotv) { | |
| 391 | + if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { | |
| 392 | + x = slotw(v, w); | |
| 393 | + if (x != Py_NotImplemented) | |
| 394 | + return x; | |
| 395 | + Py_DECREF(x); /* can't do it */ | |
| 396 | + slotw = NULL; | |
| 397 | + } | |
| 398 | + x = slotv(v, w); | |
| 399 | + if (x != Py_NotImplemented) | |
| 400 | + return x; | |
| 401 | + Py_DECREF(x); /* can't do it */ | |
| 402 | + } | |
| 403 | + if (slotw) { | |
| 404 | + x = slotw(v, w); | |
| 405 | + if (x != Py_NotImplemented) | |
| 406 | + return x; | |
| 407 | + Py_DECREF(x); /* can't do it */ | |
| 408 | + } | |
| 409 | + if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w)) { | |
| 410 | + int err = PyNumber_CoerceEx(&v, &w); | |
| 411 | + if (err < 0) { | |
| 412 | + return NULL; | |
| 413 | + } | |
| 414 | + if (err == 0) { | |
| 415 | + PyNumberMethods *mv = v->ob_type->tp_as_number; | |
| 416 | + if (mv) { | |
| 417 | + binaryfunc slot; | |
| 418 | + slot = NB_BINOP(mv, op_slot); | |
| 419 | + if (slot) { | |
| 420 | + x = slot(v, w); | |
| 421 | + Py_DECREF(v); | |
| 422 | + Py_DECREF(w); | |
| 423 | + return x; | |
| 424 | + } | |
| 425 | + } | |
| 426 | + /* CoerceEx incremented the reference counts */ | |
| 427 | + Py_DECREF(v); | |
| 428 | + Py_DECREF(w); | |
| 429 | + } | |
| 430 | + } | |
| 431 | + Py_INCREF(Py_NotImplemented); | |
| 432 | + return Py_NotImplemented; | |
| 433 | +} | |
| 434 | + | |
| 435 | +static PyObject * | |
| 436 | +binop_type_error(PyObject *v, PyObject *w, const char *op_name) | |
| 437 | +{ | |
| 438 | + PyErr_Format(PyExc_TypeError, | |
| 439 | + "unsupported operand type(s) for %.100s: " | |
| 440 | + "'%.100s' and '%.100s'", | |
| 441 | + op_name, | |
| 442 | + v->ob_type->tp_name, | |
| 443 | + w->ob_type->tp_name); | |
| 444 | + return NULL; | |
| 445 | +} | |
| 446 | + | |
| 447 | +static PyObject * | |
| 448 | +binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) | |
| 449 | +{ | |
| 450 | + PyObject *result = binary_op1(v, w, op_slot); | |
| 451 | + if (result == Py_NotImplemented) { | |
| 452 | + Py_DECREF(result); | |
| 453 | + return binop_type_error(v, w, op_name); | |
| 454 | + } | |
| 455 | + return result; | |
| 456 | +} | |
| 457 | + | |
| 458 | + | |
| 459 | +/* | |
| 460 | + Calling scheme used for ternary operations: | |
| 461 | + | |
| 462 | + *** In some cases, w.op is called before v.op; see binary_op1. *** | |
| 463 | + | |
| 464 | + v w z Action | |
| 465 | + ------------------------------------------------------------------- | |
| 466 | + new new new v.op(v,w,z), w.op(v,w,z), z.op(v,w,z) | |
| 467 | + new old new v.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z) | |
| 468 | + old new new w.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z) | |
| 469 | + old old new z.op(v,w,z), coerce(v,w,z), v.op(v,w,z) | |
| 470 | + new new old v.op(v,w,z), w.op(v,w,z), coerce(v,w,z), v.op(v,w,z) | |
| 471 | + new old old v.op(v,w,z), coerce(v,w,z), v.op(v,w,z) | |
| 472 | + old new old w.op(v,w,z), coerce(v,w,z), v.op(v,w,z) | |
| 473 | + old old old coerce(v,w,z), v.op(v,w,z) | |
| 474 | + | |
| 475 | + Legend: | |
| 476 | + ------- | |
| 477 | + * new == new style number | |
| 478 | + * old == old style number | |
| 479 | + * Action indicates the order in which operations are tried until either | |
| 480 | + a valid result is produced or an error occurs. | |
| 481 | + * coerce(v,w,z) actually does: coerce(v,w), coerce(v,z), coerce(w,z) and | |
| 482 | + only if z != Py_None; if z == Py_None, then it is treated as absent | |
| 483 | + variable and only coerce(v,w) is tried. | |
| 484 | + | |
| 485 | + */ | |
| 486 | + | |
| 487 | +static PyObject * | |
| 488 | +ternary_op(PyObject *v, | |
| 489 | + PyObject *w, | |
| 490 | + PyObject *z, | |
| 491 | + const int op_slot, | |
| 492 | + const char *op_name) | |
| 493 | +{ | |
| 494 | + PyNumberMethods *mv, *mw, *mz; | |
| 495 | + PyObject *x = NULL; | |
| 496 | + ternaryfunc slotv = NULL; | |
| 497 | + ternaryfunc slotw = NULL; | |
| 498 | + ternaryfunc slotz = NULL; | |
| 499 | + | |
| 500 | + mv = v->ob_type->tp_as_number; | |
| 501 | + mw = w->ob_type->tp_as_number; | |
| 502 | + if (mv != NULL && NEW_STYLE_NUMBER(v)) | |
| 503 | + slotv = NB_TERNOP(mv, op_slot); | |
| 504 | + if (w->ob_type != v->ob_type && | |
| 505 | + mw != NULL && NEW_STYLE_NUMBER(w)) { | |
| 506 | + slotw = NB_TERNOP(mw, op_slot); | |
| 507 | + if (slotw == slotv) | |
| 508 | + slotw = NULL; | |
| 509 | + } | |
| 510 | + if (slotv) { | |
| 511 | + if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { | |
| 512 | + x = slotw(v, w, z); | |
| 513 | + if (x != Py_NotImplemented) | |
| 514 | + return x; | |
| 515 | + Py_DECREF(x); /* can't do it */ | |
| 516 | + slotw = NULL; | |
| 517 | + } | |
| 518 | + x = slotv(v, w, z); | |
| 519 | + if (x != Py_NotImplemented) | |
| 520 | + return x; | |
| 521 | + Py_DECREF(x); /* can't do it */ | |
| 522 | + } | |
| 523 | + if (slotw) { | |
| 524 | + x = slotw(v, w, z); | |
| 525 | + if (x != Py_NotImplemented) | |
| 526 | + return x; | |
| 527 | + Py_DECREF(x); /* can't do it */ | |
| 528 | + } | |
| 529 | + mz = z->ob_type->tp_as_number; | |
| 530 | + if (mz != NULL && NEW_STYLE_NUMBER(z)) { | |
| 531 | + slotz = NB_TERNOP(mz, op_slot); | |
| 532 | + if (slotz == slotv || slotz == slotw) | |
| 533 | + slotz = NULL; | |
| 534 | + if (slotz) { | |
| 535 | + x = slotz(v, w, z); | |
| 536 | + if (x != Py_NotImplemented) | |
| 537 | + return x; | |
| 538 | + Py_DECREF(x); /* can't do it */ | |
| 539 | + } | |
| 540 | + } | |
| 541 | + | |
| 542 | + if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w) || | |
| 543 | + (z != Py_None && !NEW_STYLE_NUMBER(z))) { | |
| 544 | + /* we have an old style operand, coerce */ | |
| 545 | + PyObject *v1, *z1, *w2, *z2; | |
| 546 | + int c; | |
| 547 | + | |
| 548 | + c = PyNumber_Coerce(&v, &w); | |
| 549 | + if (c != 0) | |
| 550 | + goto error3; | |
| 551 | + | |
| 552 | + /* Special case: if the third argument is None, it is | |
| 553 | + treated as absent argument and not coerced. */ | |
| 554 | + if (z == Py_None) { | |
| 555 | + if (v->ob_type->tp_as_number) { | |
| 556 | + slotz = NB_TERNOP(v->ob_type->tp_as_number, | |
| 557 | + op_slot); | |
| 558 | + if (slotz) | |
| 559 | + x = slotz(v, w, z); | |
| 560 | + else | |
| 561 | + c = -1; | |
| 562 | + } | |
| 563 | + else | |
| 564 | + c = -1; | |
| 565 | + goto error2; | |
| 566 | + } | |
| 567 | + v1 = v; | |
| 568 | + z1 = z; | |
| 569 | + c = PyNumber_Coerce(&v1, &z1); | |
| 570 | + if (c != 0) | |
| 571 | + goto error2; | |
| 572 | + w2 = w; | |
| 573 | + z2 = z1; | |
| 574 | + c = PyNumber_Coerce(&w2, &z2); | |
| 575 | + if (c != 0) | |
| 576 | + goto error1; | |
| 577 | + | |
| 578 | + if (v1->ob_type->tp_as_number != NULL) { | |
| 579 | + slotv = NB_TERNOP(v1->ob_type->tp_as_number, | |
| 580 | + op_slot); | |
| 581 | + if (slotv) | |
| 582 | + x = slotv(v1, w2, z2); | |
| 583 | + else | |
| 584 | + c = -1; | |
| 585 | + } | |
| 586 | + else | |
| 587 | + c = -1; | |
| 588 | + | |
| 589 | + Py_DECREF(w2); | |
| 590 | + Py_DECREF(z2); | |
| 591 | + error1: | |
| 592 | + Py_DECREF(v1); | |
| 593 | + Py_DECREF(z1); | |
| 594 | + error2: | |
| 595 | + Py_DECREF(v); | |
| 596 | + Py_DECREF(w); | |
| 597 | + error3: | |
| 598 | + if (c >= 0) | |
| 599 | + return x; | |
| 600 | + } | |
| 601 | + | |
| 602 | + if (z == Py_None) | |
| 603 | + PyErr_Format( | |
| 604 | + PyExc_TypeError, | |
| 605 | + "unsupported operand type(s) for ** or pow(): " | |
| 606 | + "'%.100s' and '%.100s'", | |
| 607 | + v->ob_type->tp_name, | |
| 608 | + w->ob_type->tp_name); | |
| 609 | + else | |
| 610 | + PyErr_Format( | |
| 611 | + PyExc_TypeError, | |
| 612 | + "unsupported operand type(s) for pow(): " | |
| 613 | + "'%.100s', '%.100s', '%.100s'", | |
| 614 | + v->ob_type->tp_name, | |
| 615 | + w->ob_type->tp_name, | |
| 616 | + z->ob_type->tp_name); | |
| 617 | + return NULL; | |
| 618 | +} | |
| 619 | + | |
| 620 | +#define BINARY_FUNC(func, op, op_name) \ | |
| 621 | + PyObject * \ | |
| 622 | + func(PyObject *v, PyObject *w) { \ | |
| 623 | + return binary_op(v, w, NB_SLOT(op), op_name); \ | |
| 624 | + } | |
| 625 | + | |
| 626 | +BINARY_FUNC(PyNumber_Or, nb_or, "|") | |
| 627 | +BINARY_FUNC(PyNumber_Xor, nb_xor, "^") | |
| 628 | +BINARY_FUNC(PyNumber_And, nb_and, "&") | |
| 629 | +BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<") | |
| 630 | +BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>") | |
| 631 | +BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-") | |
| 632 | +BINARY_FUNC(PyNumber_Divide, nb_divide, "/") | |
| 633 | +BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()") | |
| 634 | + | |
| 635 | +PyObject * | |
| 636 | +PyNumber_Add(PyObject *v, PyObject *w) | |
| 637 | +{ | |
| 638 | + PyObject *result = binary_op1(v, w, NB_SLOT(nb_add)); | |
| 639 | + if (result == Py_NotImplemented) { | |
| 640 | + PySequenceMethods *m = v->ob_type->tp_as_sequence; | |
| 641 | + Py_DECREF(result); | |
| 642 | + if (m && m->sq_concat) { | |
| 643 | + return (*m->sq_concat)(v, w); | |
| 644 | + } | |
| 645 | + result = binop_type_error(v, w, "+"); | |
| 646 | + } | |
| 647 | + return result; | |
| 648 | +} | |
| 649 | + | |
| 650 | +static PyObject * | |
| 651 | +sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n) | |
| 652 | +{ | |
| 653 | + Py_ssize_t count; | |
| 654 | + if (PyIndex_Check(n)) { | |
| 655 | + count = PyNumber_AsSsize_t(n, PyExc_OverflowError); | |
| 656 | + if (count == -1 && PyErr_Occurred()) | |
| 657 | + return NULL; | |
| 658 | + } | |
| 659 | + else { | |
| 660 | + return type_error("can't multiply sequence by " | |
| 661 | + "non-int of type '%.200s'", n); | |
| 662 | + } | |
| 663 | + return (*repeatfunc)(seq, count); | |
| 664 | +} | |
| 665 | + | |
| 666 | +PyObject * | |
| 667 | +PyNumber_Multiply(PyObject *v, PyObject *w) | |
| 668 | +{ | |
| 669 | + PyObject *result = binary_op1(v, w, NB_SLOT(nb_multiply)); | |
| 670 | + if (result == Py_NotImplemented) { | |
| 671 | + PySequenceMethods *mv = v->ob_type->tp_as_sequence; | |
| 672 | + PySequenceMethods *mw = w->ob_type->tp_as_sequence; | |
| 673 | + Py_DECREF(result); | |
| 674 | + if (mv && mv->sq_repeat) { | |
| 675 | + return sequence_repeat(mv->sq_repeat, v, w); | |
| 676 | + } | |
| 677 | + else if (mw && mw->sq_repeat) { | |
| 678 | + return sequence_repeat(mw->sq_repeat, w, v); | |
| 679 | + } | |
| 680 | + result = binop_type_error(v, w, "*"); | |
| 681 | + } | |
| 682 | + return result; | |
| 683 | +} | |
| 684 | + | |
| 685 | +PyObject * | |
| 686 | +PyNumber_FloorDivide(PyObject *v, PyObject *w) | |
| 687 | +{ | |
| 688 | + /* XXX tp_flags test */ | |
| 689 | + return binary_op(v, w, NB_SLOT(nb_floor_divide), "//"); | |
| 690 | +} | |
| 691 | + | |
| 692 | +PyObject * | |
| 693 | +PyNumber_TrueDivide(PyObject *v, PyObject *w) | |
| 694 | +{ | |
| 695 | + /* XXX tp_flags test */ | |
| 696 | + return binary_op(v, w, NB_SLOT(nb_true_divide), "/"); | |
| 697 | +} | |
| 698 | + | |
| 699 | +PyObject * | |
| 700 | +PyNumber_Remainder(PyObject *v, PyObject *w) | |
| 701 | +{ | |
| 702 | + return binary_op(v, w, NB_SLOT(nb_remainder), "%"); | |
| 703 | +} | |
| 704 | + | |
| 705 | +PyObject * | |
| 706 | +PyNumber_Power(PyObject *v, PyObject *w, PyObject *z) | |
| 707 | +{ | |
| 708 | + return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()"); | |
| 709 | +} | |
| 710 | + | |
| 711 | +/* Binary in-place operators */ | |
| 712 | + | |
| 713 | +/* The in-place operators are defined to fall back to the 'normal', | |
| 714 | + non in-place operations, if the in-place methods are not in place. | |
| 715 | + | |
| 716 | + - If the left hand object has the appropriate struct members, and | |
| 717 | + they are filled, call the appropriate function and return the | |
| 718 | + result. No coercion is done on the arguments; the left-hand object | |
| 719 | + is the one the operation is performed on, and it's up to the | |
| 720 | + function to deal with the right-hand object. | |
| 721 | + | |
| 722 | + - Otherwise, in-place modification is not supported. Handle it exactly as | |
| 723 | + a non in-place operation of the same kind. | |
| 724 | + | |
| 725 | + */ | |
| 726 | + | |
| 727 | +#define HASINPLACE(t) \ | |
| 728 | + PyType_HasFeature((t)->ob_type, Py_TPFLAGS_HAVE_INPLACEOPS) | |
| 729 | + | |
| 730 | +static PyObject * | |
| 731 | +binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot) | |
| 732 | +{ | |
| 733 | + PyNumberMethods *mv = v->ob_type->tp_as_number; | |
| 734 | + if (mv != NULL && HASINPLACE(v)) { | |
| 735 | + binaryfunc slot = NB_BINOP(mv, iop_slot); | |
| 736 | + if (slot) { | |
| 737 | + PyObject *x = (slot)(v, w); | |
| 738 | + if (x != Py_NotImplemented) { | |
| 739 | + return x; | |
| 740 | + } | |
| 741 | + Py_DECREF(x); | |
| 742 | + } | |
| 743 | + } | |
| 744 | + return binary_op1(v, w, op_slot); | |
| 745 | +} | |
| 746 | + | |
| 747 | +static PyObject * | |
| 748 | +binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot, | |
| 749 | + const char *op_name) | |
| 750 | +{ | |
| 751 | + PyObject *result = binary_iop1(v, w, iop_slot, op_slot); | |
| 752 | + if (result == Py_NotImplemented) { | |
| 753 | + Py_DECREF(result); | |
| 754 | + return binop_type_error(v, w, op_name); | |
| 755 | + } | |
| 756 | + return result; | |
| 757 | +} | |
| 758 | + | |
| 759 | +#define INPLACE_BINOP(func, iop, op, op_name) \ | |
| 760 | + PyObject * \ | |
| 761 | + func(PyObject *v, PyObject *w) { \ | |
| 762 | + return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \ | |
| 763 | + } | |
| 764 | + | |
| 765 | +INPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=") | |
| 766 | +INPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=") | |
| 767 | +INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=") | |
| 768 | +INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=") | |
| 769 | +INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=") | |
| 770 | +INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=") | |
| 771 | +INPLACE_BINOP(PyNumber_InPlaceDivide, nb_inplace_divide, nb_divide, "/=") | |
| 772 | + | |
| 773 | +PyObject * | |
| 774 | +PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w) | |
| 775 | +{ | |
| 776 | + /* XXX tp_flags test */ | |
| 777 | + return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide), | |
| 778 | + NB_SLOT(nb_floor_divide), "//="); | |
| 779 | +} | |
| 780 | + | |
| 781 | +PyObject * | |
| 782 | +PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w) | |
| 783 | +{ | |
| 784 | + /* XXX tp_flags test */ | |
| 785 | + return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide), | |
| 786 | + NB_SLOT(nb_true_divide), "/="); | |
| 787 | +} | |
| 788 | + | |
| 789 | +PyObject * | |
| 790 | +PyNumber_InPlaceAdd(PyObject *v, PyObject *w) | |
| 791 | +{ | |
| 792 | + PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add), | |
| 793 | + NB_SLOT(nb_add)); | |
| 794 | + if (result == Py_NotImplemented) { | |
| 795 | + PySequenceMethods *m = v->ob_type->tp_as_sequence; | |
| 796 | + Py_DECREF(result); | |
| 797 | + if (m != NULL) { | |
| 798 | + binaryfunc f = NULL; | |
| 799 | + if (HASINPLACE(v)) | |
| 800 | + f = m->sq_inplace_concat; | |
| 801 | + if (f == NULL) | |
| 802 | + f = m->sq_concat; | |
| 803 | + if (f != NULL) | |
| 804 | + return (*f)(v, w); | |
| 805 | + } | |
| 806 | + result = binop_type_error(v, w, "+="); | |
| 807 | + } | |
| 808 | + return result; | |
| 809 | +} | |
| 810 | + | |
| 811 | +PyObject * | |
| 812 | +PyNumber_InPlaceMultiply(PyObject *v, PyObject *w) | |
| 813 | +{ | |
| 814 | + PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply), | |
| 815 | + NB_SLOT(nb_multiply)); | |
| 816 | + if (result == Py_NotImplemented) { | |
| 817 | + ssizeargfunc f = NULL; | |
| 818 | + PySequenceMethods *mv = v->ob_type->tp_as_sequence; | |
| 819 | + PySequenceMethods *mw = w->ob_type->tp_as_sequence; | |
| 820 | + Py_DECREF(result); | |
| 821 | + if (mv != NULL) { | |
| 822 | + if (HASINPLACE(v)) | |
| 823 | + f = mv->sq_inplace_repeat; | |
| 824 | + if (f == NULL) | |
| 825 | + f = mv->sq_repeat; | |
| 826 | + if (f != NULL) | |
| 827 | + return sequence_repeat(f, v, w); | |
| 828 | + } | |
| 829 | + else if (mw != NULL) { | |
| 830 | + /* Note that the right hand operand should not be | |
| 831 | + * mutated in this case so sq_inplace_repeat is not | |
| 832 | + * used. */ | |
| 833 | + if (mw->sq_repeat) | |
| 834 | + return sequence_repeat(mw->sq_repeat, w, v); | |
| 835 | + } | |
| 836 | + result = binop_type_error(v, w, "*="); | |
| 837 | + } | |
| 838 | + return result; | |
| 839 | +} | |
| 840 | + | |
| 841 | +PyObject * | |
| 842 | +PyNumber_InPlaceRemainder(PyObject *v, PyObject *w) | |
| 843 | +{ | |
| 844 | + return binary_iop(v, w, NB_SLOT(nb_inplace_remainder), | |
| 845 | + NB_SLOT(nb_remainder), "%="); | |
| 846 | +} | |
| 847 | + | |
| 848 | +PyObject * | |
| 849 | +PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) | |
| 850 | +{ | |
| 851 | + if (HASINPLACE(v) && v->ob_type->tp_as_number && | |
| 852 | + v->ob_type->tp_as_number->nb_inplace_power != NULL) { | |
| 853 | + return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**="); | |
| 854 | + } | |
| 855 | + else { | |
| 856 | + return ternary_op(v, w, z, NB_SLOT(nb_power), "**="); | |
| 857 | + } | |
| 858 | +} | |
| 859 | + | |
| 860 | + | |
| 861 | +/* Unary operators and functions */ | |
| 862 | + | |
| 863 | +PyObject * | |
| 864 | +PyNumber_Negative(PyObject *o) | |
| 865 | +{ | |
| 866 | + PyNumberMethods *m; | |
| 867 | + | |
| 868 | + if (o == NULL) | |
| 869 | + return null_error(); | |
| 870 | + m = o->ob_type->tp_as_number; | |
| 871 | + if (m && m->nb_negative) | |
| 872 | + return (*m->nb_negative)(o); | |
| 873 | + | |
| 874 | + return type_error("bad operand type for unary -: '%.200s'", o); | |
| 875 | +} | |
| 876 | + | |
| 877 | +PyObject * | |
| 878 | +PyNumber_Positive(PyObject *o) | |
| 879 | +{ | |
| 880 | + PyNumberMethods *m; | |
| 881 | + | |
| 882 | + if (o == NULL) | |
| 883 | + return null_error(); | |
| 884 | + m = o->ob_type->tp_as_number; | |
| 885 | + if (m && m->nb_positive) | |
| 886 | + return (*m->nb_positive)(o); | |
| 887 | + | |
| 888 | + return type_error("bad operand type for unary +: '%.200s'", o); | |
| 889 | +} | |
| 890 | + | |
| 891 | +PyObject * | |
| 892 | +PyNumber_Invert(PyObject *o) | |
| 893 | +{ | |
| 894 | + PyNumberMethods *m; | |
| 895 | + | |
| 896 | + if (o == NULL) | |
| 897 | + return null_error(); | |
| 898 | + m = o->ob_type->tp_as_number; | |
| 899 | + if (m && m->nb_invert) | |
| 900 | + return (*m->nb_invert)(o); | |
| 901 | + | |
| 902 | + return type_error("bad operand type for unary ~: '%.200s'", o); | |
| 903 | +} | |
| 904 | + | |
| 905 | +PyObject * | |
| 906 | +PyNumber_Absolute(PyObject *o) | |
| 907 | +{ | |
| 908 | + PyNumberMethods *m; | |
| 909 | + | |
| 910 | + if (o == NULL) | |
| 911 | + return null_error(); | |
| 912 | + m = o->ob_type->tp_as_number; | |
| 913 | + if (m && m->nb_absolute) | |
| 914 | + return m->nb_absolute(o); | |
| 915 | + | |
| 916 | + return type_error("bad operand type for abs(): '%.200s'", o); | |
| 917 | +} | |
| 918 | + | |
| 919 | +/* Add a check for embedded NULL-bytes in the argument. */ | |
| 920 | +static PyObject * | |
| 921 | +int_from_string(const char *s, Py_ssize_t len) | |
| 922 | +{ | |
| 923 | + char *end; | |
| 924 | + PyObject *x; | |
| 925 | + | |
| 926 | + x = PyInt_FromString((char*)s, &end, 10); | |
| 927 | + if (x == NULL) | |
| 928 | + return NULL; | |
| 929 | + if (end != s + len) { | |
| 930 | + PyErr_SetString(PyExc_ValueError, | |
| 931 | + "null byte in argument for int()"); | |
| 932 | + Py_DECREF(x); | |
| 933 | + return NULL; | |
| 934 | + } | |
| 935 | + return x; | |
| 936 | +} | |
| 937 | + | |
| 938 | +/* Return a Python Int or Long from the object item | |
| 939 | + Raise TypeError if the result is not an int-or-long | |
| 940 | + or if the object cannot be interpreted as an index. | |
| 941 | +*/ | |
| 942 | +PyObject * | |
| 943 | +PyNumber_Index(PyObject *item) | |
| 944 | +{ | |
| 945 | + PyObject *result = NULL; | |
| 946 | + if (item == NULL) | |
| 947 | + return null_error(); | |
| 948 | + if (PyInt_Check(item) || PyLong_Check(item)) { | |
| 949 | + Py_INCREF(item); | |
| 950 | + return item; | |
| 951 | + } | |
| 952 | + if (PyIndex_Check(item)) { | |
| 953 | + result = item->ob_type->tp_as_number->nb_index(item); | |
| 954 | + if (result && | |
| 955 | + !PyInt_Check(result) && !PyLong_Check(result)) { | |
| 956 | + PyErr_Format(PyExc_TypeError, | |
| 957 | + "__index__ returned non-(int,long) " \ | |
| 958 | + "(type %.200s)", | |
| 959 | + result->ob_type->tp_name); | |
| 960 | + Py_DECREF(result); | |
| 961 | + return NULL; | |
| 962 | + } | |
| 963 | + } | |
| 964 | + else { | |
| 965 | + PyErr_Format(PyExc_TypeError, | |
| 966 | + "'%.200s' object cannot be interpreted " | |
| 967 | + "as an index", item->ob_type->tp_name); | |
| 968 | + } | |
| 969 | + return result; | |
| 970 | +} | |
| 971 | + | |
| 972 | +/* Return an error on Overflow only if err is not NULL*/ | |
| 973 | + | |
| 974 | +Py_ssize_t | |
| 975 | +PyNumber_AsSsize_t(PyObject *item, PyObject *err) | |
| 976 | +{ | |
| 977 | + Py_ssize_t result; | |
| 978 | + PyObject *runerr; | |
| 979 | + PyObject *value = PyNumber_Index(item); | |
| 980 | + if (value == NULL) | |
| 981 | + return -1; | |
| 982 | + | |
| 983 | + /* We're done if PyInt_AsSsize_t() returns without error. */ | |
| 984 | + result = PyInt_AsSsize_t(value); | |
| 985 | + if (result != -1 || !(runerr = PyErr_Occurred())) | |
| 986 | + goto finish; | |
| 987 | + | |
| 988 | + /* Error handling code -- only manage OverflowError differently */ | |
| 989 | + if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) | |
| 990 | + goto finish; | |
| 991 | + | |
| 992 | + PyErr_Clear(); | |
| 993 | + /* If no error-handling desired then the default clipping | |
| 994 | + is sufficient. | |
| 995 | + */ | |
| 996 | + if (!err) { | |
| 997 | + assert(PyLong_Check(value)); | |
| 998 | + /* Whether or not it is less than or equal to | |
| 999 | + zero is determined by the sign of ob_size | |
| 1000 | + */ | |
| 1001 | + if (_PyLong_Sign(value) < 0) | |
| 1002 | + result = PY_SSIZE_T_MIN; | |
| 1003 | + else | |
| 1004 | + result = PY_SSIZE_T_MAX; | |
| 1005 | + } | |
| 1006 | + else { | |
| 1007 | + /* Otherwise replace the error with caller's error object. */ | |
| 1008 | + PyErr_Format(err, | |
| 1009 | + "cannot fit '%.200s' into an index-sized integer", | |
| 1010 | + item->ob_type->tp_name); | |
| 1011 | + } | |
| 1012 | + | |
| 1013 | + finish: | |
| 1014 | + Py_DECREF(value); | |
| 1015 | + return result; | |
| 1016 | +} | |
| 1017 | + | |
| 1018 | + | |
| 1019 | +PyObject * | |
| 1020 | +PyNumber_Int(PyObject *o) | |
| 1021 | +{ | |
| 1022 | + PyNumberMethods *m; | |
| 1023 | + const char *buffer; | |
| 1024 | + Py_ssize_t buffer_len; | |
| 1025 | + | |
| 1026 | + if (o == NULL) | |
| 1027 | + return null_error(); | |
| 1028 | + if (PyInt_CheckExact(o)) { | |
| 1029 | + Py_INCREF(o); | |
| 1030 | + return o; | |
| 1031 | + } | |
| 1032 | + m = o->ob_type->tp_as_number; | |
| 1033 | + if (m && m->nb_int) { /* This should include subclasses of int */ | |
| 1034 | + PyObject *res = m->nb_int(o); | |
| 1035 | + if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { | |
| 1036 | + PyErr_Format(PyExc_TypeError, | |
| 1037 | + "__int__ returned non-int (type %.200s)", | |
| 1038 | + res->ob_type->tp_name); | |
| 1039 | + Py_DECREF(res); | |
| 1040 | + return NULL; | |
| 1041 | + } | |
| 1042 | + return res; | |
| 1043 | + } | |
| 1044 | + if (PyInt_Check(o)) { /* A int subclass without nb_int */ | |
| 1045 | + PyIntObject *io = (PyIntObject*)o; | |
| 1046 | + return PyInt_FromLong(io->ob_ival); | |
| 1047 | + } | |
| 1048 | + if (PyString_Check(o)) | |
| 1049 | + return int_from_string(PyString_AS_STRING(o), | |
| 1050 | + PyString_GET_SIZE(o)); | |
| 1051 | +#ifdef Py_USING_UNICODE | |
| 1052 | + if (PyUnicode_Check(o)) | |
| 1053 | + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o), | |
| 1054 | + PyUnicode_GET_SIZE(o), | |
| 1055 | + 10); | |
| 1056 | +#endif | |
| 1057 | + if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) | |
| 1058 | + return int_from_string((char*)buffer, buffer_len); | |
| 1059 | + | |
| 1060 | + return type_error("int() argument must be a string or a " | |
| 1061 | + "number, not '%.200s'", o); | |
| 1062 | +} | |
| 1063 | + | |
| 1064 | +/* Add a check for embedded NULL-bytes in the argument. */ | |
| 1065 | +static PyObject * | |
| 1066 | +long_from_string(const char *s, Py_ssize_t len) | |
| 1067 | +{ | |
| 1068 | + char *end; | |
| 1069 | + PyObject *x; | |
| 1070 | + | |
| 1071 | + x = PyLong_FromString((char*)s, &end, 10); | |
| 1072 | + if (x == NULL) | |
| 1073 | + return NULL; | |
| 1074 | + if (end != s + len) { | |
| 1075 | + PyErr_SetString(PyExc_ValueError, | |
| 1076 | + "null byte in argument for long()"); | |
| 1077 | + Py_DECREF(x); | |
| 1078 | + return NULL; | |
| 1079 | + } | |
| 1080 | + return x; | |
| 1081 | +} | |
| 1082 | + | |
| 1083 | +PyObject * | |
| 1084 | +PyNumber_Long(PyObject *o) | |
| 1085 | +{ | |
| 1086 | + PyNumberMethods *m; | |
| 1087 | + const char *buffer; | |
| 1088 | + Py_ssize_t buffer_len; | |
| 1089 | + | |
| 1090 | + if (o == NULL) | |
| 1091 | + return null_error(); | |
| 1092 | + m = o->ob_type->tp_as_number; | |
| 1093 | + if (m && m->nb_long) { /* This should include subclasses of long */ | |
| 1094 | + PyObject *res = m->nb_long(o); | |
| 1095 | + if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { | |
| 1096 | + PyErr_Format(PyExc_TypeError, | |
| 1097 | + "__long__ returned non-long (type %.200s)", | |
| 1098 | + res->ob_type->tp_name); | |
| 1099 | + Py_DECREF(res); | |
| 1100 | + return NULL; | |
| 1101 | + } | |
| 1102 | + return res; | |
| 1103 | + } | |
| 1104 | + if (PyLong_Check(o)) /* A long subclass without nb_long */ | |
| 1105 | + return _PyLong_Copy((PyLongObject *)o); | |
| 1106 | + if (PyString_Check(o)) | |
| 1107 | + /* need to do extra error checking that PyLong_FromString() | |
| 1108 | + * doesn't do. In particular long('9.5') must raise an | |
| 1109 | + * exception, not truncate the float. | |
| 1110 | + */ | |
| 1111 | + return long_from_string(PyString_AS_STRING(o), | |
| 1112 | + PyString_GET_SIZE(o)); | |
| 1113 | +#ifdef Py_USING_UNICODE | |
| 1114 | + if (PyUnicode_Check(o)) | |
| 1115 | + /* The above check is done in PyLong_FromUnicode(). */ | |
| 1116 | + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o), | |
| 1117 | + PyUnicode_GET_SIZE(o), | |
| 1118 | + 10); | |
| 1119 | +#endif | |
| 1120 | + if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) | |
| 1121 | + return long_from_string(buffer, buffer_len); | |
| 1122 | + | |
| 1123 | + return type_error("long() argument must be a string or a " | |
| 1124 | + "number, not '%.200s'", o); | |
| 1125 | +} | |
| 1126 | + | |
| 1127 | +PyObject * | |
| 1128 | +PyNumber_Float(PyObject *o) | |
| 1129 | +{ | |
| 1130 | + PyNumberMethods *m; | |
| 1131 | + | |
| 1132 | + if (o == NULL) | |
| 1133 | + return null_error(); | |
| 1134 | + m = o->ob_type->tp_as_number; | |
| 1135 | + if (m && m->nb_float) { /* This should include subclasses of float */ | |
| 1136 | + PyObject *res = m->nb_float(o); | |
| 1137 | + if (res && !PyFloat_Check(res)) { | |
| 1138 | + PyErr_Format(PyExc_TypeError, | |
| 1139 | + "__float__ returned non-float (type %.200s)", | |
| 1140 | + res->ob_type->tp_name); | |
| 1141 | + Py_DECREF(res); | |
| 1142 | + return NULL; | |
| 1143 | + } | |
| 1144 | + return res; | |
| 1145 | + } | |
| 1146 | + if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */ | |
| 1147 | + PyFloatObject *po = (PyFloatObject *)o; | |
| 1148 | + return PyFloat_FromDouble(po->ob_fval); | |
| 1149 | + } | |
| 1150 | + return PyFloat_FromString(o, NULL); | |
| 1151 | +} | |
| 1152 | + | |
| 1153 | +/* Operations on sequences */ | |
| 1154 | + | |
| 1155 | +int | |
| 1156 | +PySequence_Check(PyObject *s) | |
| 1157 | +{ | |
| 1158 | + if (s && PyInstance_Check(s)) | |
| 1159 | + return PyObject_HasAttrString(s, "__getitem__"); | |
| 1160 | + if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type)) | |
| 1161 | + return 0; | |
| 1162 | + return s != NULL && s->ob_type->tp_as_sequence && | |
| 1163 | + s->ob_type->tp_as_sequence->sq_item != NULL; | |
| 1164 | +} | |
| 1165 | + | |
| 1166 | +Py_ssize_t | |
| 1167 | +PySequence_Size(PyObject *s) | |
| 1168 | +{ | |
| 1169 | + PySequenceMethods *m; | |
| 1170 | + | |
| 1171 | + if (s == NULL) { | |
| 1172 | + null_error(); | |
| 1173 | + return -1; | |
| 1174 | + } | |
| 1175 | + | |
| 1176 | + m = s->ob_type->tp_as_sequence; | |
| 1177 | + if (m && m->sq_length) | |
| 1178 | + return m->sq_length(s); | |
| 1179 | + | |
| 1180 | + type_error("object of type '%.200s' has no len()", s); | |
| 1181 | + return -1; | |
| 1182 | +} | |
| 1183 | + | |
| 1184 | +#undef PySequence_Length | |
| 1185 | +Py_ssize_t | |
| 1186 | +PySequence_Length(PyObject *s) | |
| 1187 | +{ | |
| 1188 | + return PySequence_Size(s); | |
| 1189 | +} | |
| 1190 | +#define PySequence_Length PySequence_Size | |
| 1191 | + | |
| 1192 | +PyObject * | |
| 1193 | +PySequence_Concat(PyObject *s, PyObject *o) | |
| 1194 | +{ | |
| 1195 | + PySequenceMethods *m; | |
| 1196 | + | |
| 1197 | + if (s == NULL || o == NULL) | |
| 1198 | + return null_error(); | |
| 1199 | + | |
| 1200 | + m = s->ob_type->tp_as_sequence; | |
| 1201 | + if (m && m->sq_concat) | |
| 1202 | + return m->sq_concat(s, o); | |
| 1203 | + | |
| 1204 | + /* Instances of user classes defining an __add__() method only | |
| 1205 | + have an nb_add slot, not an sq_concat slot. So we fall back | |
| 1206 | + to nb_add if both arguments appear to be sequences. */ | |
| 1207 | + if (PySequence_Check(s) && PySequence_Check(o)) { | |
| 1208 | + PyObject *result = binary_op1(s, o, NB_SLOT(nb_add)); | |
| 1209 | + if (result != Py_NotImplemented) | |
| 1210 | + return result; | |
| 1211 | + Py_DECREF(result); | |
| 1212 | + } | |
| 1213 | + return type_error("'%.200s' object can't be concatenated", s); | |
| 1214 | +} | |
| 1215 | + | |
| 1216 | +PyObject * | |
| 1217 | +PySequence_Repeat(PyObject *o, Py_ssize_t count) | |
| 1218 | +{ | |
| 1219 | + PySequenceMethods *m; | |
| 1220 | + | |
| 1221 | + if (o == NULL) | |
| 1222 | + return null_error(); | |
| 1223 | + | |
| 1224 | + m = o->ob_type->tp_as_sequence; | |
| 1225 | + if (m && m->sq_repeat) | |
| 1226 | + return m->sq_repeat(o, count); | |
| 1227 | + | |
| 1228 | + /* Instances of user classes defining a __mul__() method only | |
| 1229 | + have an nb_multiply slot, not an sq_repeat slot. so we fall back | |
| 1230 | + to nb_multiply if o appears to be a sequence. */ | |
| 1231 | + if (PySequence_Check(o)) { | |
| 1232 | + PyObject *n, *result; | |
| 1233 | + n = PyInt_FromSsize_t(count); | |
| 1234 | + if (n == NULL) | |
| 1235 | + return NULL; | |
| 1236 | + result = binary_op1(o, n, NB_SLOT(nb_multiply)); | |
| 1237 | + Py_DECREF(n); | |
| 1238 | + if (result != Py_NotImplemented) | |
| 1239 | + return result; | |
| 1240 | + Py_DECREF(result); | |
| 1241 | + } | |
| 1242 | + return type_error("'%.200s' object can't be repeated", o); | |
| 1243 | +} | |
| 1244 | + | |
| 1245 | +PyObject * | |
| 1246 | +PySequence_InPlaceConcat(PyObject *s, PyObject *o) | |
| 1247 | +{ | |
| 1248 | + PySequenceMethods *m; | |
| 1249 | + | |
| 1250 | + if (s == NULL || o == NULL) | |
| 1251 | + return null_error(); | |
| 1252 | + | |
| 1253 | + m = s->ob_type->tp_as_sequence; | |
| 1254 | + if (m && HASINPLACE(s) && m->sq_inplace_concat) | |
| 1255 | + return m->sq_inplace_concat(s, o); | |
| 1256 | + if (m && m->sq_concat) | |
| 1257 | + return m->sq_concat(s, o); | |
| 1258 | + | |
| 1259 | + if (PySequence_Check(s) && PySequence_Check(o)) { | |
| 1260 | + PyObject *result = binary_iop1(s, o, NB_SLOT(nb_inplace_add), | |
| 1261 | + NB_SLOT(nb_add)); | |
| 1262 | + if (result != Py_NotImplemented) | |
| 1263 | + return result; | |
| 1264 | + Py_DECREF(result); | |
| 1265 | + } | |
| 1266 | + return type_error("'%.200s' object can't be concatenated", s); | |
| 1267 | +} | |
| 1268 | + | |
| 1269 | +PyObject * | |
| 1270 | +PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) | |
| 1271 | +{ | |
| 1272 | + PySequenceMethods *m; | |
| 1273 | + | |
| 1274 | + if (o == NULL) | |
| 1275 | + return null_error(); | |
| 1276 | + | |
| 1277 | + m = o->ob_type->tp_as_sequence; | |
| 1278 | + if (m && HASINPLACE(o) && m->sq_inplace_repeat) | |
| 1279 | + return m->sq_inplace_repeat(o, count); | |
| 1280 | + if (m && m->sq_repeat) | |
| 1281 | + return m->sq_repeat(o, count); | |
| 1282 | + | |
| 1283 | + if (PySequence_Check(o)) { | |
| 1284 | + PyObject *n, *result; | |
| 1285 | + n = PyInt_FromSsize_t(count); | |
| 1286 | + if (n == NULL) | |
| 1287 | + return NULL; | |
| 1288 | + result = binary_iop1(o, n, NB_SLOT(nb_inplace_multiply), | |
| 1289 | + NB_SLOT(nb_multiply)); | |
| 1290 | + Py_DECREF(n); | |
| 1291 | + if (result != Py_NotImplemented) | |
| 1292 | + return result; | |
| 1293 | + Py_DECREF(result); | |
| 1294 | + } | |
| 1295 | + return type_error("'%.200s' object can't be repeated", o); | |
| 1296 | +} | |
| 1297 | + | |
| 1298 | +PyObject * | |
| 1299 | +PySequence_GetItem(PyObject *s, Py_ssize_t i) | |
| 1300 | +{ | |
| 1301 | + PySequenceMethods *m; | |
| 1302 | + | |
| 1303 | + if (s == NULL) | |
| 1304 | + return null_error(); | |
| 1305 | + | |
| 1306 | + m = s->ob_type->tp_as_sequence; | |
| 1307 | + if (m && m->sq_item) { | |
| 1308 | + if (i < 0) { | |
| 1309 | + if (m->sq_length) { | |
| 1310 | + Py_ssize_t l = (*m->sq_length)(s); | |
| 1311 | + if (l < 0) | |
| 1312 | + return NULL; | |
| 1313 | + i += l; | |
| 1314 | + } | |
| 1315 | + } | |
| 1316 | + return m->sq_item(s, i); | |
| 1317 | + } | |
| 1318 | + | |
| 1319 | + return type_error("'%.200s' object is unindexable", s); | |
| 1320 | +} | |
| 1321 | + | |
| 1322 | +PyObject * | |
| 1323 | +PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) | |
| 1324 | +{ | |
| 1325 | + PySequenceMethods *m; | |
| 1326 | + PyMappingMethods *mp; | |
| 1327 | + | |
| 1328 | + if (!s) return null_error(); | |
| 1329 | + | |
| 1330 | + m = s->ob_type->tp_as_sequence; | |
| 1331 | + if (m && m->sq_slice) { | |
| 1332 | + if (i1 < 0 || i2 < 0) { | |
| 1333 | + if (m->sq_length) { | |
| 1334 | + Py_ssize_t l = (*m->sq_length)(s); | |
| 1335 | + if (l < 0) | |
| 1336 | + return NULL; | |
| 1337 | + if (i1 < 0) | |
| 1338 | + i1 += l; | |
| 1339 | + if (i2 < 0) | |
| 1340 | + i2 += l; | |
| 1341 | + } | |
| 1342 | + } | |
| 1343 | + return m->sq_slice(s, i1, i2); | |
| 1344 | + } else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) { | |
| 1345 | + PyObject *res; | |
| 1346 | + PyObject *slice = _PySlice_FromIndices(i1, i2); | |
| 1347 | + if (!slice) | |
| 1348 | + return NULL; | |
| 1349 | + res = mp->mp_subscript(s, slice); | |
| 1350 | + Py_DECREF(slice); | |
| 1351 | + return res; | |
| 1352 | + } | |
| 1353 | + | |
| 1354 | + return type_error("'%.200s' object is unsliceable", s); | |
| 1355 | +} | |
| 1356 | + | |
| 1357 | +int | |
| 1358 | +PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) | |
| 1359 | +{ | |
| 1360 | + PySequenceMethods *m; | |
| 1361 | + | |
| 1362 | + if (s == NULL) { | |
| 1363 | + null_error(); | |
| 1364 | + return -1; | |
| 1365 | + } | |
| 1366 | + | |
| 1367 | + m = s->ob_type->tp_as_sequence; | |
| 1368 | + if (m && m->sq_ass_item) { | |
| 1369 | + if (i < 0) { | |
| 1370 | + if (m->sq_length) { | |
| 1371 | + Py_ssize_t l = (*m->sq_length)(s); | |
| 1372 | + if (l < 0) | |
| 1373 | + return -1; | |
| 1374 | + i += l; | |
| 1375 | + } | |
| 1376 | + } | |
| 1377 | + return m->sq_ass_item(s, i, o); | |
| 1378 | + } | |
| 1379 | + | |
| 1380 | + type_error("'%.200s' object does not support item assignment", s); | |
| 1381 | + return -1; | |
| 1382 | +} | |
| 1383 | + | |
| 1384 | +int | |
| 1385 | +PySequence_DelItem(PyObject *s, Py_ssize_t i) | |
| 1386 | +{ | |
| 1387 | + PySequenceMethods *m; | |
| 1388 | + | |
| 1389 | + if (s == NULL) { | |
| 1390 | + null_error(); | |
| 1391 | + return -1; | |
| 1392 | + } | |
| 1393 | + | |
| 1394 | + m = s->ob_type->tp_as_sequence; | |
| 1395 | + if (m && m->sq_ass_item) { | |
| 1396 | + if (i < 0) { | |
| 1397 | + if (m->sq_length) { | |
| 1398 | + Py_ssize_t l = (*m->sq_length)(s); | |
| 1399 | + if (l < 0) | |
| 1400 | + return -1; | |
| 1401 | + i += l; | |
| 1402 | + } | |
| 1403 | + } | |
| 1404 | + return m->sq_ass_item(s, i, (PyObject *)NULL); | |
| 1405 | + } | |
| 1406 | + | |
| 1407 | + type_error("'%.200s' object doesn't support item deletion", s); | |
| 1408 | + return -1; | |
| 1409 | +} | |
| 1410 | + | |
| 1411 | +int | |
| 1412 | +PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o) | |
| 1413 | +{ | |
| 1414 | + PySequenceMethods *m; | |
| 1415 | + PyMappingMethods *mp; | |
| 1416 | + | |
| 1417 | + if (s == NULL) { | |
| 1418 | + null_error(); | |
| 1419 | + return -1; | |
| 1420 | + } | |
| 1421 | + | |
| 1422 | + m = s->ob_type->tp_as_sequence; | |
| 1423 | + if (m && m->sq_ass_slice) { | |
| 1424 | + if (i1 < 0 || i2 < 0) { | |
| 1425 | + if (m->sq_length) { | |
| 1426 | + Py_ssize_t l = (*m->sq_length)(s); | |
| 1427 | + if (l < 0) | |
| 1428 | + return -1; | |
| 1429 | + if (i1 < 0) | |
| 1430 | + i1 += l; | |
| 1431 | + if (i2 < 0) | |
| 1432 | + i2 += l; | |
| 1433 | + } | |
| 1434 | + } | |
| 1435 | + return m->sq_ass_slice(s, i1, i2, o); | |
| 1436 | + } else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) { | |
| 1437 | + int res; | |
| 1438 | + PyObject *slice = _PySlice_FromIndices(i1, i2); | |
| 1439 | + if (!slice) | |
| 1440 | + return -1; | |
| 1441 | + res = mp->mp_ass_subscript(s, slice, o); | |
| 1442 | + Py_DECREF(slice); | |
| 1443 | + return res; | |
| 1444 | + } | |
| 1445 | + | |
| 1446 | + type_error("'%.200s' object doesn't support slice assignment", s); | |
| 1447 | + return -1; | |
| 1448 | +} | |
| 1449 | + | |
| 1450 | +int | |
| 1451 | +PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) | |
| 1452 | +{ | |
| 1453 | + PySequenceMethods *m; | |
| 1454 | + | |
| 1455 | + if (s == NULL) { | |
| 1456 | + null_error(); | |
| 1457 | + return -1; | |
| 1458 | + } | |
| 1459 | + | |
| 1460 | + m = s->ob_type->tp_as_sequence; | |
| 1461 | + if (m && m->sq_ass_slice) { | |
| 1462 | + if (i1 < 0 || i2 < 0) { | |
| 1463 | + if (m->sq_length) { | |
| 1464 | + Py_ssize_t l = (*m->sq_length)(s); | |
| 1465 | + if (l < 0) | |
| 1466 | + return -1; | |
| 1467 | + if (i1 < 0) | |
| 1468 | + i1 += l; | |
| 1469 | + if (i2 < 0) | |
| 1470 | + i2 += l; | |
| 1471 | + } | |
| 1472 | + } | |
| 1473 | + return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL); | |
| 1474 | + } | |
| 1475 | + type_error("'%.200s' object doesn't support slice deletion", s); | |
| 1476 | + return -1; | |
| 1477 | +} | |
| 1478 | + | |
| 1479 | +PyObject * | |
| 1480 | +PySequence_Tuple(PyObject *v) | |
| 1481 | +{ | |
| 1482 | + PyObject *it; /* iter(v) */ | |
| 1483 | + Py_ssize_t n; /* guess for result tuple size */ | |
| 1484 | + PyObject *result; | |
| 1485 | + Py_ssize_t j; | |
| 1486 | + | |
| 1487 | + if (v == NULL) | |
| 1488 | + return null_error(); | |
| 1489 | + | |
| 1490 | + /* Special-case the common tuple and list cases, for efficiency. */ | |
| 1491 | + if (PyTuple_CheckExact(v)) { | |
| 1492 | + /* Note that we can't know whether it's safe to return | |
| 1493 | + a tuple *subclass* instance as-is, hence the restriction | |
| 1494 | + to exact tuples here. In contrast, lists always make | |
| 1495 | + a copy, so there's no need for exactness below. */ | |
| 1496 | + Py_INCREF(v); | |
| 1497 | + return v; | |
| 1498 | + } | |
| 1499 | + if (PyList_Check(v)) | |
| 1500 | + return PyList_AsTuple(v); | |
| 1501 | + | |
| 1502 | + /* Get iterator. */ | |
| 1503 | + it = PyObject_GetIter(v); | |
| 1504 | + if (it == NULL) | |
| 1505 | + return NULL; | |
| 1506 | + | |
| 1507 | + /* Guess result size and allocate space. */ | |
| 1508 | + n = _PyObject_LengthHint(v); | |
| 1509 | + if (n < 0) { | |
| 1510 | + if (!PyErr_ExceptionMatches(PyExc_TypeError) && | |
| 1511 | + !PyErr_ExceptionMatches(PyExc_AttributeError)) { | |
| 1512 | + Py_DECREF(it); | |
| 1513 | + return NULL; | |
| 1514 | + } | |
| 1515 | + PyErr_Clear(); | |
| 1516 | + n = 10; /* arbitrary */ | |
| 1517 | + } | |
| 1518 | + result = PyTuple_New(n); | |
| 1519 | + if (result == NULL) | |
| 1520 | + goto Fail; | |
| 1521 | + | |
| 1522 | + /* Fill the tuple. */ | |
| 1523 | + for (j = 0; ; ++j) { | |
| 1524 | + PyObject *item = PyIter_Next(it); | |
| 1525 | + if (item == NULL) { | |
| 1526 | + if (PyErr_Occurred()) | |
| 1527 | + goto Fail; | |
| 1528 | + break; | |
| 1529 | + } | |
| 1530 | + if (j >= n) { | |
| 1531 | + Py_ssize_t oldn = n; | |
| 1532 | + /* The over-allocation strategy can grow a bit faster | |
| 1533 | + than for lists because unlike lists the | |
| 1534 | + over-allocation isn't permanent -- we reclaim | |
| 1535 | + the excess before the end of this routine. | |
| 1536 | + So, grow by ten and then add 25%. | |
| 1537 | + */ | |
| 1538 | + n += 10; | |
| 1539 | + n += n >> 2; | |
| 1540 | + if (n < oldn) { | |
| 1541 | + /* Check for overflow */ | |
| 1542 | + PyErr_NoMemory(); | |
| 1543 | + Py_DECREF(item); | |
| 1544 | + goto Fail; | |
| 1545 | + } | |
| 1546 | + if (_PyTuple_Resize(&result, n) != 0) { | |
| 1547 | + Py_DECREF(item); | |
| 1548 | + goto Fail; | |
| 1549 | + } | |
| 1550 | + } | |
| 1551 | + PyTuple_SET_ITEM(result, j, item); | |
| 1552 | + } | |
| 1553 | + | |
| 1554 | + /* Cut tuple back if guess was too large. */ | |
| 1555 | + if (j < n && | |
| 1556 | + _PyTuple_Resize(&result, j) != 0) | |
| 1557 | + goto Fail; | |
| 1558 | + | |
| 1559 | + Py_DECREF(it); | |
| 1560 | + return result; | |
| 1561 | + | |
| 1562 | +Fail: | |
| 1563 | + Py_XDECREF(result); | |
| 1564 | + Py_DECREF(it); | |
| 1565 | + return NULL; | |
| 1566 | +} | |
| 1567 | + | |
| 1568 | +PyObject * | |
| 1569 | +PySequence_List(PyObject *v) | |
| 1570 | +{ | |
| 1571 | + PyObject *result; /* result list */ | |
| 1572 | + PyObject *rv; /* return value from PyList_Extend */ | |
| 1573 | + | |
| 1574 | + if (v == NULL) | |
| 1575 | + return null_error(); | |
| 1576 | + | |
| 1577 | + result = PyList_New(0); | |
| 1578 | + if (result == NULL) | |
| 1579 | + return NULL; | |
| 1580 | + | |
| 1581 | + rv = _PyList_Extend((PyListObject *)result, v); | |
| 1582 | + if (rv == NULL) { | |
| 1583 | + Py_DECREF(result); | |
| 1584 | + return NULL; | |
| 1585 | + } | |
| 1586 | + Py_DECREF(rv); | |
| 1587 | + return result; | |
| 1588 | +} | |
| 1589 | + | |
| 1590 | +PyObject * | |
| 1591 | +PySequence_Fast(PyObject *v, const char *m) | |
| 1592 | +{ | |
| 1593 | + PyObject *it; | |
| 1594 | + | |
| 1595 | + if (v == NULL) | |
| 1596 | + return null_error(); | |
| 1597 | + | |
| 1598 | + if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) { | |
| 1599 | + Py_INCREF(v); | |
| 1600 | + return v; | |
| 1601 | + } | |
| 1602 | + | |
| 1603 | + it = PyObject_GetIter(v); | |
| 1604 | + if (it == NULL) { | |
| 1605 | + if (PyErr_ExceptionMatches(PyExc_TypeError)) | |
| 1606 | + PyErr_SetString(PyExc_TypeError, m); | |
| 1607 | + return NULL; | |
| 1608 | + } | |
| 1609 | + | |
| 1610 | + v = PySequence_List(it); | |
| 1611 | + Py_DECREF(it); | |
| 1612 | + | |
| 1613 | + return v; | |
| 1614 | +} | |
| 1615 | + | |
| 1616 | +/* Iterate over seq. Result depends on the operation: | |
| 1617 | + PY_ITERSEARCH_COUNT: -1 if error, else # of times obj appears in seq. | |
| 1618 | + PY_ITERSEARCH_INDEX: 0-based index of first occurence of obj in seq; | |
| 1619 | + set ValueError and return -1 if none found; also return -1 on error. | |
| 1620 | + Py_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on error. | |
| 1621 | +*/ | |
| 1622 | +Py_ssize_t | |
| 1623 | +_PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation) | |
| 1624 | +{ | |
| 1625 | + Py_ssize_t n; | |
| 1626 | + int wrapped; /* for PY_ITERSEARCH_INDEX, true iff n wrapped around */ | |
| 1627 | + PyObject *it; /* iter(seq) */ | |
| 1628 | + | |
| 1629 | + if (seq == NULL || obj == NULL) { | |
| 1630 | + null_error(); | |
| 1631 | + return -1; | |
| 1632 | + } | |
| 1633 | + | |
| 1634 | + it = PyObject_GetIter(seq); | |
| 1635 | + if (it == NULL) { | |
| 1636 | + type_error("argument of type '%.200s' is not iterable", seq); | |
| 1637 | + return -1; | |
| 1638 | + } | |
| 1639 | + | |
| 1640 | + n = wrapped = 0; | |
| 1641 | + for (;;) { | |
| 1642 | + int cmp; | |
| 1643 | + PyObject *item = PyIter_Next(it); | |
| 1644 | + if (item == NULL) { | |
| 1645 | + if (PyErr_Occurred()) | |
| 1646 | + goto Fail; | |
| 1647 | + break; | |
| 1648 | + } | |
| 1649 | + | |
| 1650 | + cmp = PyObject_RichCompareBool(obj, item, Py_EQ); | |
| 1651 | + Py_DECREF(item); | |
| 1652 | + if (cmp < 0) | |
| 1653 | + goto Fail; | |
| 1654 | + if (cmp > 0) { | |
| 1655 | + switch (operation) { | |
| 1656 | + case PY_ITERSEARCH_COUNT: | |
| 1657 | + if (n == PY_SSIZE_T_MAX) { | |
| 1658 | + PyErr_SetString(PyExc_OverflowError, | |
| 1659 | + "count exceeds C integer size"); | |
| 1660 | + goto Fail; | |
| 1661 | + } | |
| 1662 | + ++n; | |
| 1663 | + break; | |
| 1664 | + | |
| 1665 | + case PY_ITERSEARCH_INDEX: | |
| 1666 | + if (wrapped) { | |
| 1667 | + PyErr_SetString(PyExc_OverflowError, | |
| 1668 | + "index exceeds C integer size"); | |
| 1669 | + goto Fail; | |
| 1670 | + } | |
| 1671 | + goto Done; | |
| 1672 | + | |
| 1673 | + case PY_ITERSEARCH_CONTAINS: | |
| 1674 | + n = 1; | |
| 1675 | + goto Done; | |
| 1676 | + | |
| 1677 | + default: | |
| 1678 | + assert(!"unknown operation"); | |
| 1679 | + } | |
| 1680 | + } | |
| 1681 | + | |
| 1682 | + if (operation == PY_ITERSEARCH_INDEX) { | |
| 1683 | + if (n == PY_SSIZE_T_MAX) | |
| 1684 | + wrapped = 1; | |
| 1685 | + ++n; | |
| 1686 | + } | |
| 1687 | + } | |
| 1688 | + | |
| 1689 | + if (operation != PY_ITERSEARCH_INDEX) | |
| 1690 | + goto Done; | |
| 1691 | + | |
| 1692 | + PyErr_SetString(PyExc_ValueError, | |
| 1693 | + "sequence.index(x): x not in sequence"); | |
| 1694 | + /* fall into failure code */ | |
| 1695 | +Fail: | |
| 1696 | + n = -1; | |
| 1697 | + /* fall through */ | |
| 1698 | +Done: | |
| 1699 | + Py_DECREF(it); | |
| 1700 | + return n; | |
| 1701 | + | |
| 1702 | +} | |
| 1703 | + | |
| 1704 | +/* Return # of times o appears in s. */ | |
| 1705 | +Py_ssize_t | |
| 1706 | +PySequence_Count(PyObject *s, PyObject *o) | |
| 1707 | +{ | |
| 1708 | + return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT); | |
| 1709 | +} | |
| 1710 | + | |
| 1711 | +/* Return -1 if error; 1 if ob in seq; 0 if ob not in seq. | |
| 1712 | + * Use sq_contains if possible, else defer to _PySequence_IterSearch(). | |
| 1713 | + */ | |
| 1714 | +int | |
| 1715 | +PySequence_Contains(PyObject *seq, PyObject *ob) | |
| 1716 | +{ | |
| 1717 | + Py_ssize_t result; | |
| 1718 | + if (PyType_HasFeature(seq->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) { | |
| 1719 | + PySequenceMethods *sqm = seq->ob_type->tp_as_sequence; | |
| 1720 | + if (sqm != NULL && sqm->sq_contains != NULL) | |
| 1721 | + return (*sqm->sq_contains)(seq, ob); | |
| 1722 | + } | |
| 1723 | + result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS); | |
| 1724 | + return Py_SAFE_DOWNCAST(result, Py_ssize_t, int); | |
| 1725 | +} | |
| 1726 | + | |
| 1727 | +/* Backwards compatibility */ | |
| 1728 | +#undef PySequence_In | |
| 1729 | +int | |
| 1730 | +PySequence_In(PyObject *w, PyObject *v) | |
| 1731 | +{ | |
| 1732 | + return PySequence_Contains(w, v); | |
| 1733 | +} | |
| 1734 | + | |
| 1735 | +Py_ssize_t | |
| 1736 | +PySequence_Index(PyObject *s, PyObject *o) | |
| 1737 | +{ | |
| 1738 | + return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX); | |
| 1739 | +} | |
| 1740 | + | |
| 1741 | +/* Operations on mappings */ | |
| 1742 | + | |
| 1743 | +int | |
| 1744 | +PyMapping_Check(PyObject *o) | |
| 1745 | +{ | |
| 1746 | + if (o && PyInstance_Check(o)) | |
| 1747 | + return PyObject_HasAttrString(o, "__getitem__"); | |
| 1748 | + | |
| 1749 | + return o && o->ob_type->tp_as_mapping && | |
| 1750 | + o->ob_type->tp_as_mapping->mp_subscript && | |
| 1751 | + !(o->ob_type->tp_as_sequence && | |
| 1752 | + o->ob_type->tp_as_sequence->sq_slice); | |
| 1753 | +} | |
| 1754 | + | |
| 1755 | +Py_ssize_t | |
| 1756 | +PyMapping_Size(PyObject *o) | |
| 1757 | +{ | |
| 1758 | + PyMappingMethods *m; | |
| 1759 | + | |
| 1760 | + if (o == NULL) { | |
| 1761 | + null_error(); | |
| 1762 | + return -1; | |
| 1763 | + } | |
| 1764 | + | |
| 1765 | + m = o->ob_type->tp_as_mapping; | |
| 1766 | + if (m && m->mp_length) | |
| 1767 | + return m->mp_length(o); | |
| 1768 | + | |
| 1769 | + type_error("object of type '%.200s' has no len()", o); | |
| 1770 | + return -1; | |
| 1771 | +} | |
| 1772 | + | |
| 1773 | +#undef PyMapping_Length | |
| 1774 | +Py_ssize_t | |
| 1775 | +PyMapping_Length(PyObject *o) | |
| 1776 | +{ | |
| 1777 | + return PyMapping_Size(o); | |
| 1778 | +} | |
| 1779 | +#define PyMapping_Length PyMapping_Size | |
| 1780 | + | |
| 1781 | +PyObject * | |
| 1782 | +PyMapping_GetItemString(PyObject *o, char *key) | |
| 1783 | +{ | |
| 1784 | + PyObject *okey, *r; | |
| 1785 | + | |
| 1786 | + if (key == NULL) | |
| 1787 | + return null_error(); | |
| 1788 | + | |
| 1789 | + okey = PyString_FromString(key); | |
| 1790 | + if (okey == NULL) | |
| 1791 | + return NULL; | |
| 1792 | + r = PyObject_GetItem(o, okey); | |
| 1793 | + Py_DECREF(okey); | |
| 1794 | + return r; | |
| 1795 | +} | |
| 1796 | + | |
| 1797 | +int | |
| 1798 | +PyMapping_SetItemString(PyObject *o, char *key, PyObject *value) | |
| 1799 | +{ | |
| 1800 | + PyObject *okey; | |
| 1801 | + int r; | |
| 1802 | + | |
| 1803 | + if (key == NULL) { | |
| 1804 | + null_error(); | |
| 1805 | + return -1; | |
| 1806 | + } | |
| 1807 | + | |
| 1808 | + okey = PyString_FromString(key); | |
| 1809 | + if (okey == NULL) | |
| 1810 | + return -1; | |
| 1811 | + r = PyObject_SetItem(o, okey, value); | |
| 1812 | + Py_DECREF(okey); | |
| 1813 | + return r; | |
| 1814 | +} | |
| 1815 | + | |
| 1816 | +int | |
| 1817 | +PyMapping_HasKeyString(PyObject *o, char *key) | |
| 1818 | +{ | |
| 1819 | + PyObject *v; | |
| 1820 | + | |
| 1821 | + v = PyMapping_GetItemString(o, key); | |
| 1822 | + if (v) { | |
| 1823 | + Py_DECREF(v); | |
| 1824 | + return 1; | |
| 1825 | + } | |
| 1826 | + PyErr_Clear(); | |
| 1827 | + return 0; | |
| 1828 | +} | |
| 1829 | + | |
| 1830 | +int | |
| 1831 | +PyMapping_HasKey(PyObject *o, PyObject *key) | |
| 1832 | +{ | |
| 1833 | + PyObject *v; | |
| 1834 | + | |
| 1835 | + v = PyObject_GetItem(o, key); | |
| 1836 | + if (v) { | |
| 1837 | + Py_DECREF(v); | |
| 1838 | + return 1; | |
| 1839 | + } | |
| 1840 | + PyErr_Clear(); | |
| 1841 | + return 0; | |
| 1842 | +} | |
| 1843 | + | |
| 1844 | +/* Operations on callable objects */ | |
| 1845 | + | |
| 1846 | +/* XXX PyCallable_Check() is in object.c */ | |
| 1847 | + | |
| 1848 | +PyObject * | |
| 1849 | +PyObject_CallObject(PyObject *o, PyObject *a) | |
| 1850 | +{ | |
| 1851 | + return PyEval_CallObjectWithKeywords(o, a, NULL); | |
| 1852 | +} | |
| 1853 | + | |
| 1854 | +PyObject * | |
| 1855 | +PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) | |
| 1856 | +{ | |
| 1857 | + ternaryfunc call; | |
| 1858 | + | |
| 1859 | + if ((call = func->ob_type->tp_call) != NULL) { | |
| 1860 | + PyObject *result = (*call)(func, arg, kw); | |
| 1861 | + if (result == NULL && !PyErr_Occurred()) | |
| 1862 | + PyErr_SetString( | |
| 1863 | + PyExc_SystemError, | |
| 1864 | + "NULL result without error in PyObject_Call"); | |
| 1865 | + return result; | |
| 1866 | + } | |
| 1867 | + PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", | |
| 1868 | + func->ob_type->tp_name); | |
| 1869 | + return NULL; | |
| 1870 | +} | |
| 1871 | + | |
| 1872 | +static PyObject* | |
| 1873 | +call_function_tail(PyObject *callable, PyObject *args) | |
| 1874 | +{ | |
| 1875 | + PyObject *retval; | |
| 1876 | + | |
| 1877 | + if (args == NULL) | |
| 1878 | + return NULL; | |
| 1879 | + | |
| 1880 | + if (!PyTuple_Check(args)) { | |
| 1881 | + PyObject *a; | |
| 1882 | + | |
| 1883 | + a = PyTuple_New(1); | |
| 1884 | + if (a == NULL) { | |
| 1885 | + Py_DECREF(args); | |
| 1886 | + return NULL; | |
| 1887 | + } | |
| 1888 | + PyTuple_SET_ITEM(a, 0, args); | |
| 1889 | + args = a; | |
| 1890 | + } | |
| 1891 | + retval = PyObject_Call(callable, args, NULL); | |
| 1892 | + | |
| 1893 | + Py_DECREF(args); | |
| 1894 | + | |
| 1895 | + return retval; | |
| 1896 | +} | |
| 1897 | + | |
| 1898 | +PyObject * | |
| 1899 | +PyObject_CallFunction(PyObject *callable, char *format, ...) | |
| 1900 | +{ | |
| 1901 | + va_list va; | |
| 1902 | + PyObject *args; | |
| 1903 | + | |
| 1904 | + if (callable == NULL) | |
| 1905 | + return null_error(); | |
| 1906 | + | |
| 1907 | + if (format && *format) { | |
| 1908 | + va_start(va, format); | |
| 1909 | + args = Py_VaBuildValue(format, va); | |
| 1910 | + va_end(va); | |
| 1911 | + } | |
| 1912 | + else | |
| 1913 | + args = PyTuple_New(0); | |
| 1914 | + | |
| 1915 | + return call_function_tail(callable, args); | |
| 1916 | +} | |
| 1917 | + | |
| 1918 | +PyObject * | |
| 1919 | +_PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...) | |
| 1920 | +{ | |
| 1921 | + va_list va; | |
| 1922 | + PyObject *args; | |
| 1923 | + | |
| 1924 | + if (callable == NULL) | |
| 1925 | + return null_error(); | |
| 1926 | + | |
| 1927 | + if (format && *format) { | |
| 1928 | + va_start(va, format); | |
| 1929 | + args = _Py_VaBuildValue_SizeT(format, va); | |
| 1930 | + va_end(va); | |
| 1931 | + } | |
| 1932 | + else | |
| 1933 | + args = PyTuple_New(0); | |
| 1934 | + | |
| 1935 | + return call_function_tail(callable, args); | |
| 1936 | +} | |
| 1937 | + | |
| 1938 | +PyObject * | |
| 1939 | +PyObject_CallMethod(PyObject *o, char *name, char *format, ...) | |
| 1940 | +{ | |
| 1941 | + va_list va; | |
| 1942 | + PyObject *args; | |
| 1943 | + PyObject *func = NULL; | |
| 1944 | + PyObject *retval = NULL; | |
| 1945 | + | |
| 1946 | + if (o == NULL || name == NULL) | |
| 1947 | + return null_error(); | |
| 1948 | + | |
| 1949 | + func = PyObject_GetAttrString(o, name); | |
| 1950 | + if (func == NULL) { | |
| 1951 | + PyErr_SetString(PyExc_AttributeError, name); | |
| 1952 | + return 0; | |
| 1953 | + } | |
| 1954 | + | |
| 1955 | + if (!PyCallable_Check(func)) { | |
| 1956 | + type_error("attribute of type '%.200s' is not callable", func); | |
| 1957 | + goto exit; | |
| 1958 | + } | |
| 1959 | + | |
| 1960 | + if (format && *format) { | |
| 1961 | + va_start(va, format); | |
| 1962 | + args = Py_VaBuildValue(format, va); | |
| 1963 | + va_end(va); | |
| 1964 | + } | |
| 1965 | + else | |
| 1966 | + args = PyTuple_New(0); | |
| 1967 | + | |
| 1968 | + retval = call_function_tail(func, args); | |
| 1969 | + | |
| 1970 | + exit: | |
| 1971 | + /* args gets consumed in call_function_tail */ | |
| 1972 | + Py_XDECREF(func); | |
| 1973 | + | |
| 1974 | + return retval; | |
| 1975 | +} | |
| 1976 | + | |
| 1977 | +PyObject * | |
| 1978 | +_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...) | |
| 1979 | +{ | |
| 1980 | + va_list va; | |
| 1981 | + PyObject *args; | |
| 1982 | + PyObject *func = NULL; | |
| 1983 | + PyObject *retval = NULL; | |
| 1984 | + | |
| 1985 | + if (o == NULL || name == NULL) | |
| 1986 | + return null_error(); | |
| 1987 | + | |
| 1988 | + func = PyObject_GetAttrString(o, name); | |
| 1989 | + if (func == NULL) { | |
| 1990 | + PyErr_SetString(PyExc_AttributeError, name); | |
| 1991 | + return 0; | |
| 1992 | + } | |
| 1993 | + | |
| 1994 | + if (!PyCallable_Check(func)) { | |
| 1995 | + type_error("attribute of type '%.200s' is not callable", func); | |
| 1996 | + goto exit; | |
| 1997 | + } | |
| 1998 | + | |
| 1999 | + if (format && *format) { | |
| 2000 | + va_start(va, format); | |
| 2001 | + args = _Py_VaBuildValue_SizeT(format, va); | |
| 2002 | + va_end(va); | |
| 2003 | + } | |
| 2004 | + else | |
| 2005 | + args = PyTuple_New(0); | |
| 2006 | + | |
| 2007 | + retval = call_function_tail(func, args); | |
| 2008 | + | |
| 2009 | + exit: | |
| 2010 | + /* args gets consumed in call_function_tail */ | |
| 2011 | + Py_XDECREF(func); | |
| 2012 | + | |
| 2013 | + return retval; | |
| 2014 | +} | |
| 2015 | + | |
| 2016 | + | |
| 2017 | +static PyObject * | |
| 2018 | +objargs_mktuple(va_list va) | |
| 2019 | +{ | |
| 2020 | + int i, n = 0; | |
| 2021 | + va_list countva; | |
| 2022 | + PyObject *result, *tmp; | |
| 2023 | + | |
| 2024 | +#ifdef VA_LIST_IS_ARRAY | |
| 2025 | + memcpy(countva, va, sizeof(va_list)); | |
| 2026 | +#else | |
| 2027 | +#ifdef __va_copy | |
| 2028 | + __va_copy(countva, va); | |
| 2029 | +#else | |
| 2030 | + countva = va; | |
| 2031 | +#endif | |
| 2032 | +#endif | |
| 2033 | + | |
| 2034 | + while (((PyObject *)va_arg(countva, PyObject *)) != NULL) | |
| 2035 | + ++n; | |
| 2036 | + result = PyTuple_New(n); | |
| 2037 | + if (result != NULL && n > 0) { | |
| 2038 | + for (i = 0; i < n; ++i) { | |
| 2039 | + tmp = (PyObject *)va_arg(va, PyObject *); | |
| 2040 | + PyTuple_SET_ITEM(result, i, tmp); | |
| 2041 | + Py_INCREF(tmp); | |
| 2042 | + } | |
| 2043 | + } | |
| 2044 | + return result; | |
| 2045 | +} | |
| 2046 | + | |
| 2047 | +PyObject * | |
| 2048 | +PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...) | |
| 2049 | +{ | |
| 2050 | + PyObject *args, *tmp; | |
| 2051 | + va_list vargs; | |
| 2052 | + | |
| 2053 | + if (callable == NULL || name == NULL) | |
| 2054 | + return null_error(); | |
| 2055 | + | |
| 2056 | + callable = PyObject_GetAttr(callable, name); | |
| 2057 | + if (callable == NULL) | |
| 2058 | + return NULL; | |
| 2059 | + | |
| 2060 | + /* count the args */ | |
| 2061 | + va_start(vargs, name); | |
| 2062 | + args = objargs_mktuple(vargs); | |
| 2063 | + va_end(vargs); | |
| 2064 | + if (args == NULL) { | |
| 2065 | + Py_DECREF(callable); | |
| 2066 | + return NULL; | |
| 2067 | + } | |
| 2068 | + tmp = PyObject_Call(callable, args, NULL); | |
| 2069 | + Py_DECREF(args); | |
| 2070 | + Py_DECREF(callable); | |
| 2071 | + | |
| 2072 | + return tmp; | |
| 2073 | +} | |
| 2074 | + | |
| 2075 | +PyObject * | |
| 2076 | +PyObject_CallFunctionObjArgs(PyObject *callable, ...) | |
| 2077 | +{ | |
| 2078 | + PyObject *args, *tmp; | |
| 2079 | + va_list vargs; | |
| 2080 | + | |
| 2081 | + if (callable == NULL) | |
| 2082 | + return null_error(); | |
| 2083 | + | |
| 2084 | + /* count the args */ | |
| 2085 | + va_start(vargs, callable); | |
| 2086 | + args = objargs_mktuple(vargs); | |
| 2087 | + va_end(vargs); | |
| 2088 | + if (args == NULL) | |
| 2089 | + return NULL; | |
| 2090 | + tmp = PyObject_Call(callable, args, NULL); | |
| 2091 | + Py_DECREF(args); | |
| 2092 | + | |
| 2093 | + return tmp; | |
| 2094 | +} | |
| 2095 | + | |
| 2096 | + | |
| 2097 | +/* isinstance(), issubclass() */ | |
| 2098 | + | |
| 2099 | +/* abstract_get_bases() has logically 4 return states, with a sort of 0th | |
| 2100 | + * state that will almost never happen. | |
| 2101 | + * | |
| 2102 | + * 0. creating the __bases__ static string could get a MemoryError | |
| 2103 | + * 1. getattr(cls, '__bases__') could raise an AttributeError | |
| 2104 | + * 2. getattr(cls, '__bases__') could raise some other exception | |
| 2105 | + * 3. getattr(cls, '__bases__') could return a tuple | |
| 2106 | + * 4. getattr(cls, '__bases__') could return something other than a tuple | |
| 2107 | + * | |
| 2108 | + * Only state #3 is a non-error state and only it returns a non-NULL object | |
| 2109 | + * (it returns the retrieved tuple). | |
| 2110 | + * | |
| 2111 | + * Any raised AttributeErrors are masked by clearing the exception and | |
| 2112 | + * returning NULL. If an object other than a tuple comes out of __bases__, | |
| 2113 | + * then again, the return value is NULL. So yes, these two situations | |
| 2114 | + * produce exactly the same results: NULL is returned and no error is set. | |
| 2115 | + * | |
| 2116 | + * If some exception other than AttributeError is raised, then NULL is also | |
| 2117 | + * returned, but the exception is not cleared. That's because we want the | |
| 2118 | + * exception to be propagated along. | |
| 2119 | + * | |
| 2120 | + * Callers are expected to test for PyErr_Occurred() when the return value | |
| 2121 | + * is NULL to decide whether a valid exception should be propagated or not. | |
| 2122 | + * When there's no exception to propagate, it's customary for the caller to | |
| 2123 | + * set a TypeError. | |
| 2124 | + */ | |
| 2125 | +static PyObject * | |
| 2126 | +abstract_get_bases(PyObject *cls) | |
| 2127 | +{ | |
| 2128 | + static PyObject *__bases__ = NULL; | |
| 2129 | + PyObject *bases; | |
| 2130 | + | |
| 2131 | + if (__bases__ == NULL) { | |
| 2132 | + __bases__ = PyString_FromString("__bases__"); | |
| 2133 | + if (__bases__ == NULL) | |
| 2134 | + return NULL; | |
| 2135 | + } | |
| 2136 | + bases = PyObject_GetAttr(cls, __bases__); | |
| 2137 | + if (bases == NULL) { | |
| 2138 | + if (PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 2139 | + PyErr_Clear(); | |
| 2140 | + return NULL; | |
| 2141 | + } | |
| 2142 | + if (!PyTuple_Check(bases)) { | |
| 2143 | + Py_DECREF(bases); | |
| 2144 | + return NULL; | |
| 2145 | + } | |
| 2146 | + return bases; | |
| 2147 | +} | |
| 2148 | + | |
| 2149 | + | |
| 2150 | +static int | |
| 2151 | +abstract_issubclass(PyObject *derived, PyObject *cls) | |
| 2152 | +{ | |
| 2153 | + PyObject *bases; | |
| 2154 | + Py_ssize_t i, n; | |
| 2155 | + int r = 0; | |
| 2156 | + | |
| 2157 | + | |
| 2158 | + if (derived == cls) | |
| 2159 | + return 1; | |
| 2160 | + | |
| 2161 | + if (PyTuple_Check(cls)) { | |
| 2162 | + /* Not a general sequence -- that opens up the road to | |
| 2163 | + recursion and stack overflow. */ | |
| 2164 | + n = PyTuple_GET_SIZE(cls); | |
| 2165 | + for (i = 0; i < n; i++) { | |
| 2166 | + if (derived == PyTuple_GET_ITEM(cls, i)) | |
| 2167 | + return 1; | |
| 2168 | + } | |
| 2169 | + } | |
| 2170 | + bases = abstract_get_bases(derived); | |
| 2171 | + if (bases == NULL) { | |
| 2172 | + if (PyErr_Occurred()) | |
| 2173 | + return -1; | |
| 2174 | + return 0; | |
| 2175 | + } | |
| 2176 | + n = PyTuple_GET_SIZE(bases); | |
| 2177 | + for (i = 0; i < n; i++) { | |
| 2178 | + r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls); | |
| 2179 | + if (r != 0) | |
| 2180 | + break; | |
| 2181 | + } | |
| 2182 | + | |
| 2183 | + Py_DECREF(bases); | |
| 2184 | + | |
| 2185 | + return r; | |
| 2186 | +} | |
| 2187 | + | |
| 2188 | +static int | |
| 2189 | +check_class(PyObject *cls, const char *error) | |
| 2190 | +{ | |
| 2191 | + PyObject *bases = abstract_get_bases(cls); | |
| 2192 | + if (bases == NULL) { | |
| 2193 | + /* Do not mask errors. */ | |
| 2194 | + if (!PyErr_Occurred()) | |
| 2195 | + PyErr_SetString(PyExc_TypeError, error); | |
| 2196 | + return 0; | |
| 2197 | + } | |
| 2198 | + Py_DECREF(bases); | |
| 2199 | + return -1; | |
| 2200 | +} | |
| 2201 | + | |
| 2202 | +static int | |
| 2203 | +recursive_isinstance(PyObject *inst, PyObject *cls, int recursion_depth) | |
| 2204 | +{ | |
| 2205 | + PyObject *icls; | |
| 2206 | + static PyObject *__class__ = NULL; | |
| 2207 | + int retval = 0; | |
| 2208 | + | |
| 2209 | + if (__class__ == NULL) { | |
| 2210 | + __class__ = PyString_FromString("__class__"); | |
| 2211 | + if (__class__ == NULL) | |
| 2212 | + return -1; | |
| 2213 | + } | |
| 2214 | + | |
| 2215 | + if (PyClass_Check(cls) && PyInstance_Check(inst)) { | |
| 2216 | + PyObject *inclass = | |
| 2217 | + (PyObject*)((PyInstanceObject*)inst)->in_class; | |
| 2218 | + retval = PyClass_IsSubclass(inclass, cls); | |
| 2219 | + } | |
| 2220 | + else if (PyType_Check(cls)) { | |
| 2221 | + retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); | |
| 2222 | + if (retval == 0) { | |
| 2223 | + PyObject *c = PyObject_GetAttr(inst, __class__); | |
| 2224 | + if (c == NULL) { | |
| 2225 | + PyErr_Clear(); | |
| 2226 | + } | |
| 2227 | + else { | |
| 2228 | + if (c != (PyObject *)(inst->ob_type) && | |
| 2229 | + PyType_Check(c)) | |
| 2230 | + retval = PyType_IsSubtype( | |
| 2231 | + (PyTypeObject *)c, | |
| 2232 | + (PyTypeObject *)cls); | |
| 2233 | + Py_DECREF(c); | |
| 2234 | + } | |
| 2235 | + } | |
| 2236 | + } | |
| 2237 | + else if (PyTuple_Check(cls)) { | |
| 2238 | + Py_ssize_t i, n; | |
| 2239 | + | |
| 2240 | + if (!recursion_depth) { | |
| 2241 | + PyErr_SetString(PyExc_RuntimeError, | |
| 2242 | + "nest level of tuple too deep"); | |
| 2243 | + return -1; | |
| 2244 | + } | |
| 2245 | + | |
| 2246 | + n = PyTuple_GET_SIZE(cls); | |
| 2247 | + for (i = 0; i < n; i++) { | |
| 2248 | + retval = recursive_isinstance( | |
| 2249 | + inst, | |
| 2250 | + PyTuple_GET_ITEM(cls, i), | |
| 2251 | + recursion_depth-1); | |
| 2252 | + if (retval != 0) | |
| 2253 | + break; | |
| 2254 | + } | |
| 2255 | + } | |
| 2256 | + else { | |
| 2257 | + if (!check_class(cls, | |
| 2258 | + "isinstance() arg 2 must be a class, type," | |
| 2259 | + " or tuple of classes and types")) | |
| 2260 | + return -1; | |
| 2261 | + icls = PyObject_GetAttr(inst, __class__); | |
| 2262 | + if (icls == NULL) { | |
| 2263 | + PyErr_Clear(); | |
| 2264 | + retval = 0; | |
| 2265 | + } | |
| 2266 | + else { | |
| 2267 | + retval = abstract_issubclass(icls, cls); | |
| 2268 | + Py_DECREF(icls); | |
| 2269 | + } | |
| 2270 | + } | |
| 2271 | + | |
| 2272 | + return retval; | |
| 2273 | +} | |
| 2274 | + | |
| 2275 | +int | |
| 2276 | +PyObject_IsInstance(PyObject *inst, PyObject *cls) | |
| 2277 | +{ | |
| 2278 | + return recursive_isinstance(inst, cls, Py_GetRecursionLimit()); | |
| 2279 | +} | |
| 2280 | + | |
| 2281 | +static int | |
| 2282 | +recursive_issubclass(PyObject *derived, PyObject *cls, int recursion_depth) | |
| 2283 | +{ | |
| 2284 | + int retval; | |
| 2285 | + | |
| 2286 | + if (!PyClass_Check(derived) || !PyClass_Check(cls)) { | |
| 2287 | + if (!check_class(derived, | |
| 2288 | + "issubclass() arg 1 must be a class")) | |
| 2289 | + return -1; | |
| 2290 | + | |
| 2291 | + if (PyTuple_Check(cls)) { | |
| 2292 | + Py_ssize_t i; | |
| 2293 | + Py_ssize_t n = PyTuple_GET_SIZE(cls); | |
| 2294 | + | |
| 2295 | + if (!recursion_depth) { | |
| 2296 | + PyErr_SetString(PyExc_RuntimeError, | |
| 2297 | + "nest level of tuple too deep"); | |
| 2298 | + return -1; | |
| 2299 | + } | |
| 2300 | + for (i = 0; i < n; ++i) { | |
| 2301 | + retval = recursive_issubclass( | |
| 2302 | + derived, | |
| 2303 | + PyTuple_GET_ITEM(cls, i), | |
| 2304 | + recursion_depth-1); | |
| 2305 | + if (retval != 0) { | |
| 2306 | + /* either found it, or got an error */ | |
| 2307 | + return retval; | |
| 2308 | + } | |
| 2309 | + } | |
| 2310 | + return 0; | |
| 2311 | + } | |
| 2312 | + else { | |
| 2313 | + if (!check_class(cls, | |
| 2314 | + "issubclass() arg 2 must be a class" | |
| 2315 | + " or tuple of classes")) | |
| 2316 | + return -1; | |
| 2317 | + } | |
| 2318 | + | |
| 2319 | + retval = abstract_issubclass(derived, cls); | |
| 2320 | + } | |
| 2321 | + else { | |
| 2322 | + /* shortcut */ | |
| 2323 | + if (!(retval = (derived == cls))) | |
| 2324 | + retval = PyClass_IsSubclass(derived, cls); | |
| 2325 | + } | |
| 2326 | + | |
| 2327 | + return retval; | |
| 2328 | +} | |
| 2329 | + | |
| 2330 | +int | |
| 2331 | +PyObject_IsSubclass(PyObject *derived, PyObject *cls) | |
| 2332 | +{ | |
| 2333 | + return recursive_issubclass(derived, cls, Py_GetRecursionLimit()); | |
| 2334 | +} | |
| 2335 | + | |
| 2336 | + | |
| 2337 | +PyObject * | |
| 2338 | +PyObject_GetIter(PyObject *o) | |
| 2339 | +{ | |
| 2340 | + PyTypeObject *t = o->ob_type; | |
| 2341 | + getiterfunc f = NULL; | |
| 2342 | + if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER)) | |
| 2343 | + f = t->tp_iter; | |
| 2344 | + if (f == NULL) { | |
| 2345 | + if (PySequence_Check(o)) | |
| 2346 | + return PySeqIter_New(o); | |
| 2347 | + return type_error("'%.200s' object is not iterable", o); | |
| 2348 | + } | |
| 2349 | + else { | |
| 2350 | + PyObject *res = (*f)(o); | |
| 2351 | + if (res != NULL && !PyIter_Check(res)) { | |
| 2352 | + PyErr_Format(PyExc_TypeError, | |
| 2353 | + "iter() returned non-iterator " | |
| 2354 | + "of type '%.100s'", | |
| 2355 | + res->ob_type->tp_name); | |
| 2356 | + Py_DECREF(res); | |
| 2357 | + res = NULL; | |
| 2358 | + } | |
| 2359 | + return res; | |
| 2360 | + } | |
| 2361 | +} | |
| 2362 | + | |
| 2363 | +/* Return next item. | |
| 2364 | + * If an error occurs, return NULL. PyErr_Occurred() will be true. | |
| 2365 | + * If the iteration terminates normally, return NULL and clear the | |
| 2366 | + * PyExc_StopIteration exception (if it was set). PyErr_Occurred() | |
| 2367 | + * will be false. | |
| 2368 | + * Else return the next object. PyErr_Occurred() will be false. | |
| 2369 | + */ | |
| 2370 | +PyObject * | |
| 2371 | +PyIter_Next(PyObject *iter) | |
| 2372 | +{ | |
| 2373 | + PyObject *result; | |
| 2374 | + assert(PyIter_Check(iter)); | |
| 2375 | + result = (*iter->ob_type->tp_iternext)(iter); | |
| 2376 | + if (result == NULL && | |
| 2377 | + PyErr_Occurred() && | |
| 2378 | + PyErr_ExceptionMatches(PyExc_StopIteration)) | |
| 2379 | + PyErr_Clear(); | |
| 2380 | + return result; | |
| 2381 | +} | |
| @@ -0,0 +1,201 @@ | ||
| 1 | +/* Boolean type, a subtype of int */ | |
| 2 | + | |
| 3 | +#include "Python.h" | |
| 4 | + | |
| 5 | +/* We need to define bool_print to override int_print */ | |
| 6 | + | |
| 7 | +static int | |
| 8 | +bool_print(PyBoolObject *self, FILE *fp, int flags) | |
| 9 | +{ | |
| 10 | + fputs(self->ob_ival == 0 ? "False" : "True", fp); | |
| 11 | + return 0; | |
| 12 | +} | |
| 13 | + | |
| 14 | +/* We define bool_repr to return "False" or "True" */ | |
| 15 | + | |
| 16 | +static PyObject *false_str = NULL; | |
| 17 | +static PyObject *true_str = NULL; | |
| 18 | + | |
| 19 | +static PyObject * | |
| 20 | +bool_repr(PyBoolObject *self) | |
| 21 | +{ | |
| 22 | + PyObject *s; | |
| 23 | + | |
| 24 | + if (self->ob_ival) | |
| 25 | + s = true_str ? true_str : | |
| 26 | + (true_str = PyString_InternFromString("True")); | |
| 27 | + else | |
| 28 | + s = false_str ? false_str : | |
| 29 | + (false_str = PyString_InternFromString("False")); | |
| 30 | + Py_XINCREF(s); | |
| 31 | + return s; | |
| 32 | +} | |
| 33 | + | |
| 34 | +/* Function to return a bool from a C long */ | |
| 35 | + | |
| 36 | +PyObject *PyBool_FromLong(long ok) | |
| 37 | +{ | |
| 38 | + PyObject *result; | |
| 39 | + | |
| 40 | + if (ok) | |
| 41 | + result = Py_True; | |
| 42 | + else | |
| 43 | + result = Py_False; | |
| 44 | + Py_INCREF(result); | |
| 45 | + return result; | |
| 46 | +} | |
| 47 | + | |
| 48 | +/* We define bool_new to always return either Py_True or Py_False */ | |
| 49 | + | |
| 50 | +static PyObject * | |
| 51 | +bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 52 | +{ | |
| 53 | + static char *kwlist[] = {"x", 0}; | |
| 54 | + PyObject *x = Py_False; | |
| 55 | + long ok; | |
| 56 | + | |
| 57 | + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", kwlist, &x)) | |
| 58 | + return NULL; | |
| 59 | + ok = PyObject_IsTrue(x); | |
| 60 | + if (ok < 0) | |
| 61 | + return NULL; | |
| 62 | + return PyBool_FromLong(ok); | |
| 63 | +} | |
| 64 | + | |
| 65 | +/* Arithmetic operations redefined to return bool if both args are bool. */ | |
| 66 | + | |
| 67 | +static PyObject * | |
| 68 | +bool_and(PyObject *a, PyObject *b) | |
| 69 | +{ | |
| 70 | + if (!PyBool_Check(a) || !PyBool_Check(b)) | |
| 71 | + return PyInt_Type.tp_as_number->nb_and(a, b); | |
| 72 | + return PyBool_FromLong( | |
| 73 | + ((PyBoolObject *)a)->ob_ival & ((PyBoolObject *)b)->ob_ival); | |
| 74 | +} | |
| 75 | + | |
| 76 | +static PyObject * | |
| 77 | +bool_or(PyObject *a, PyObject *b) | |
| 78 | +{ | |
| 79 | + if (!PyBool_Check(a) || !PyBool_Check(b)) | |
| 80 | + return PyInt_Type.tp_as_number->nb_or(a, b); | |
| 81 | + return PyBool_FromLong( | |
| 82 | + ((PyBoolObject *)a)->ob_ival | ((PyBoolObject *)b)->ob_ival); | |
| 83 | +} | |
| 84 | + | |
| 85 | +static PyObject * | |
| 86 | +bool_xor(PyObject *a, PyObject *b) | |
| 87 | +{ | |
| 88 | + if (!PyBool_Check(a) || !PyBool_Check(b)) | |
| 89 | + return PyInt_Type.tp_as_number->nb_xor(a, b); | |
| 90 | + return PyBool_FromLong( | |
| 91 | + ((PyBoolObject *)a)->ob_ival ^ ((PyBoolObject *)b)->ob_ival); | |
| 92 | +} | |
| 93 | + | |
| 94 | +/* Doc string */ | |
| 95 | + | |
| 96 | +PyDoc_STRVAR(bool_doc, | |
| 97 | +"bool(x) -> bool\n\ | |
| 98 | +\n\ | |
| 99 | +Returns True when the argument x is true, False otherwise.\n\ | |
| 100 | +The builtins True and False are the only two instances of the class bool.\n\ | |
| 101 | +The class bool is a subclass of the class int, and cannot be subclassed."); | |
| 102 | + | |
| 103 | +/* Arithmetic methods -- only so we can override &, |, ^. */ | |
| 104 | + | |
| 105 | +static PyNumberMethods bool_as_number = { | |
| 106 | + 0, /* nb_add */ | |
| 107 | + 0, /* nb_subtract */ | |
| 108 | + 0, /* nb_multiply */ | |
| 109 | + 0, /* nb_divide */ | |
| 110 | + 0, /* nb_remainder */ | |
| 111 | + 0, /* nb_divmod */ | |
| 112 | + 0, /* nb_power */ | |
| 113 | + 0, /* nb_negative */ | |
| 114 | + 0, /* nb_positive */ | |
| 115 | + 0, /* nb_absolute */ | |
| 116 | + 0, /* nb_nonzero */ | |
| 117 | + 0, /* nb_invert */ | |
| 118 | + 0, /* nb_lshift */ | |
| 119 | + 0, /* nb_rshift */ | |
| 120 | + bool_and, /* nb_and */ | |
| 121 | + bool_xor, /* nb_xor */ | |
| 122 | + bool_or, /* nb_or */ | |
| 123 | + 0, /* nb_coerce */ | |
| 124 | + 0, /* nb_int */ | |
| 125 | + 0, /* nb_long */ | |
| 126 | + 0, /* nb_float */ | |
| 127 | + 0, /* nb_oct */ | |
| 128 | + 0, /* nb_hex */ | |
| 129 | + 0, /* nb_inplace_add */ | |
| 130 | + 0, /* nb_inplace_subtract */ | |
| 131 | + 0, /* nb_inplace_multiply */ | |
| 132 | + 0, /* nb_inplace_divide */ | |
| 133 | + 0, /* nb_inplace_remainder */ | |
| 134 | + 0, /* nb_inplace_power */ | |
| 135 | + 0, /* nb_inplace_lshift */ | |
| 136 | + 0, /* nb_inplace_rshift */ | |
| 137 | + 0, /* nb_inplace_and */ | |
| 138 | + 0, /* nb_inplace_xor */ | |
| 139 | + 0, /* nb_inplace_or */ | |
| 140 | + 0, /* nb_floor_divide */ | |
| 141 | + 0, /* nb_true_divide */ | |
| 142 | + 0, /* nb_inplace_floor_divide */ | |
| 143 | + 0, /* nb_inplace_true_divide */ | |
| 144 | +}; | |
| 145 | + | |
| 146 | +/* The type object for bool. Note that this cannot be subclassed! */ | |
| 147 | + | |
| 148 | +PyTypeObject PyBool_Type = { | |
| 149 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 150 | + 0, | |
| 151 | + "bool", | |
| 152 | + sizeof(PyIntObject), | |
| 153 | + 0, | |
| 154 | + 0, /* tp_dealloc */ | |
| 155 | + (printfunc)bool_print, /* tp_print */ | |
| 156 | + 0, /* tp_getattr */ | |
| 157 | + 0, /* tp_setattr */ | |
| 158 | + 0, /* tp_compare */ | |
| 159 | + (reprfunc)bool_repr, /* tp_repr */ | |
| 160 | + &bool_as_number, /* tp_as_number */ | |
| 161 | + 0, /* tp_as_sequence */ | |
| 162 | + 0, /* tp_as_mapping */ | |
| 163 | + 0, /* tp_hash */ | |
| 164 | + 0, /* tp_call */ | |
| 165 | + (reprfunc)bool_repr, /* tp_str */ | |
| 166 | + 0, /* tp_getattro */ | |
| 167 | + 0, /* tp_setattro */ | |
| 168 | + 0, /* tp_as_buffer */ | |
| 169 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ | |
| 170 | + bool_doc, /* tp_doc */ | |
| 171 | + 0, /* tp_traverse */ | |
| 172 | + 0, /* tp_clear */ | |
| 173 | + 0, /* tp_richcompare */ | |
| 174 | + 0, /* tp_weaklistoffset */ | |
| 175 | + 0, /* tp_iter */ | |
| 176 | + 0, /* tp_iternext */ | |
| 177 | + 0, /* tp_methods */ | |
| 178 | + 0, /* tp_members */ | |
| 179 | + 0, /* tp_getset */ | |
| 180 | + &PyInt_Type, /* tp_base */ | |
| 181 | + 0, /* tp_dict */ | |
| 182 | + 0, /* tp_descr_get */ | |
| 183 | + 0, /* tp_descr_set */ | |
| 184 | + 0, /* tp_dictoffset */ | |
| 185 | + 0, /* tp_init */ | |
| 186 | + 0, /* tp_alloc */ | |
| 187 | + bool_new, /* tp_new */ | |
| 188 | +}; | |
| 189 | + | |
| 190 | +/* The objects representing bool values False and True */ | |
| 191 | + | |
| 192 | +/* Named Zero for link-level compatibility */ | |
| 193 | +PyIntObject _Py_ZeroStruct = { | |
| 194 | + PyObject_HEAD_INIT(&PyBool_Type) | |
| 195 | + 0 | |
| 196 | +}; | |
| 197 | + | |
| 198 | +PyIntObject _Py_TrueStruct = { | |
| 199 | + PyObject_HEAD_INIT(&PyBool_Type) | |
| 200 | + 1 | |
| 201 | +}; | |
| @@ -0,0 +1,706 @@ | ||
| 1 | + | |
| 2 | +/* Buffer object implementation */ | |
| 3 | + | |
| 4 | +#include "Python.h" | |
| 5 | + | |
| 6 | + | |
| 7 | +typedef struct { | |
| 8 | + PyObject_HEAD | |
| 9 | + PyObject *b_base; | |
| 10 | + void *b_ptr; | |
| 11 | + Py_ssize_t b_size; | |
| 12 | + Py_ssize_t b_offset; | |
| 13 | + int b_readonly; | |
| 14 | + long b_hash; | |
| 15 | +} PyBufferObject; | |
| 16 | + | |
| 17 | + | |
| 18 | +enum buffer_t { | |
| 19 | + READ_BUFFER, | |
| 20 | + WRITE_BUFFER, | |
| 21 | + CHAR_BUFFER, | |
| 22 | + ANY_BUFFER, | |
| 23 | +}; | |
| 24 | + | |
| 25 | +static int | |
| 26 | +get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size, | |
| 27 | + enum buffer_t buffer_type) | |
| 28 | +{ | |
| 29 | + if (self->b_base == NULL) { | |
| 30 | + assert (ptr != NULL); | |
| 31 | + *ptr = self->b_ptr; | |
| 32 | + *size = self->b_size; | |
| 33 | + } | |
| 34 | + else { | |
| 35 | + Py_ssize_t count, offset; | |
| 36 | + readbufferproc proc = 0; | |
| 37 | + PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer; | |
| 38 | + if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) { | |
| 39 | + PyErr_SetString(PyExc_TypeError, | |
| 40 | + "single-segment buffer object expected"); | |
| 41 | + return 0; | |
| 42 | + } | |
| 43 | + if ((buffer_type == READ_BUFFER) || | |
| 44 | + ((buffer_type == ANY_BUFFER) && self->b_readonly)) | |
| 45 | + proc = bp->bf_getreadbuffer; | |
| 46 | + else if ((buffer_type == WRITE_BUFFER) || | |
| 47 | + (buffer_type == ANY_BUFFER)) | |
| 48 | + proc = (readbufferproc)bp->bf_getwritebuffer; | |
| 49 | + else if (buffer_type == CHAR_BUFFER) { | |
| 50 | + if (!PyType_HasFeature(self->ob_type, | |
| 51 | + Py_TPFLAGS_HAVE_GETCHARBUFFER)) { | |
| 52 | + PyErr_SetString(PyExc_TypeError, | |
| 53 | + "Py_TPFLAGS_HAVE_GETCHARBUFFER needed"); | |
| 54 | + return 0; | |
| 55 | + } | |
| 56 | + proc = (readbufferproc)bp->bf_getcharbuffer; | |
| 57 | + } | |
| 58 | + if (!proc) { | |
| 59 | + char *buffer_type_name; | |
| 60 | + switch (buffer_type) { | |
| 61 | + case READ_BUFFER: | |
| 62 | + buffer_type_name = "read"; | |
| 63 | + break; | |
| 64 | + case WRITE_BUFFER: | |
| 65 | + buffer_type_name = "write"; | |
| 66 | + break; | |
| 67 | + case CHAR_BUFFER: | |
| 68 | + buffer_type_name = "char"; | |
| 69 | + break; | |
| 70 | + default: | |
| 71 | + buffer_type_name = "no"; | |
| 72 | + break; | |
| 73 | + } | |
| 74 | + PyErr_Format(PyExc_TypeError, | |
| 75 | + "%s buffer type not available", | |
| 76 | + buffer_type_name); | |
| 77 | + return 0; | |
| 78 | + } | |
| 79 | + if ((count = (*proc)(self->b_base, 0, ptr)) < 0) | |
| 80 | + return 0; | |
| 81 | + /* apply constraints to the start/end */ | |
| 82 | + if (self->b_offset > count) | |
| 83 | + offset = count; | |
| 84 | + else | |
| 85 | + offset = self->b_offset; | |
| 86 | + *(char **)ptr = *(char **)ptr + offset; | |
| 87 | + if (self->b_size == Py_END_OF_BUFFER) | |
| 88 | + *size = count; | |
| 89 | + else | |
| 90 | + *size = self->b_size; | |
| 91 | + if (offset + *size > count) | |
| 92 | + *size = count - offset; | |
| 93 | + } | |
| 94 | + return 1; | |
| 95 | +} | |
| 96 | + | |
| 97 | + | |
| 98 | +static PyObject * | |
| 99 | +buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr, | |
| 100 | + int readonly) | |
| 101 | +{ | |
| 102 | + PyBufferObject * b; | |
| 103 | + | |
| 104 | + if (size < 0 && size != Py_END_OF_BUFFER) { | |
| 105 | + PyErr_SetString(PyExc_ValueError, | |
| 106 | + "size must be zero or positive"); | |
| 107 | + return NULL; | |
| 108 | + } | |
| 109 | + if (offset < 0) { | |
| 110 | + PyErr_SetString(PyExc_ValueError, | |
| 111 | + "offset must be zero or positive"); | |
| 112 | + return NULL; | |
| 113 | + } | |
| 114 | + | |
| 115 | + b = PyObject_NEW(PyBufferObject, &PyBuffer_Type); | |
| 116 | + if ( b == NULL ) | |
| 117 | + return NULL; | |
| 118 | + | |
| 119 | + Py_XINCREF(base); | |
| 120 | + b->b_base = base; | |
| 121 | + b->b_ptr = ptr; | |
| 122 | + b->b_size = size; | |
| 123 | + b->b_offset = offset; | |
| 124 | + b->b_readonly = readonly; | |
| 125 | + b->b_hash = -1; | |
| 126 | + | |
| 127 | + return (PyObject *) b; | |
| 128 | +} | |
| 129 | + | |
| 130 | +static PyObject * | |
| 131 | +buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly) | |
| 132 | +{ | |
| 133 | + if (offset < 0) { | |
| 134 | + PyErr_SetString(PyExc_ValueError, | |
| 135 | + "offset must be zero or positive"); | |
| 136 | + return NULL; | |
| 137 | + } | |
| 138 | + if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) { | |
| 139 | + /* another buffer, refer to the base object */ | |
| 140 | + PyBufferObject *b = (PyBufferObject *)base; | |
| 141 | + if (b->b_size != Py_END_OF_BUFFER) { | |
| 142 | + Py_ssize_t base_size = b->b_size - offset; | |
| 143 | + if (base_size < 0) | |
| 144 | + base_size = 0; | |
| 145 | + if (size == Py_END_OF_BUFFER || size > base_size) | |
| 146 | + size = base_size; | |
| 147 | + } | |
| 148 | + offset += b->b_offset; | |
| 149 | + base = b->b_base; | |
| 150 | + } | |
| 151 | + return buffer_from_memory(base, size, offset, NULL, readonly); | |
| 152 | +} | |
| 153 | + | |
| 154 | + | |
| 155 | +PyObject * | |
| 156 | +PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) | |
| 157 | +{ | |
| 158 | + PyBufferProcs *pb = base->ob_type->tp_as_buffer; | |
| 159 | + | |
| 160 | + if ( pb == NULL || | |
| 161 | + pb->bf_getreadbuffer == NULL || | |
| 162 | + pb->bf_getsegcount == NULL ) | |
| 163 | + { | |
| 164 | + PyErr_SetString(PyExc_TypeError, "buffer object expected"); | |
| 165 | + return NULL; | |
| 166 | + } | |
| 167 | + | |
| 168 | + return buffer_from_object(base, size, offset, 1); | |
| 169 | +} | |
| 170 | + | |
| 171 | +PyObject * | |
| 172 | +PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) | |
| 173 | +{ | |
| 174 | + PyBufferProcs *pb = base->ob_type->tp_as_buffer; | |
| 175 | + | |
| 176 | + if ( pb == NULL || | |
| 177 | + pb->bf_getwritebuffer == NULL || | |
| 178 | + pb->bf_getsegcount == NULL ) | |
| 179 | + { | |
| 180 | + PyErr_SetString(PyExc_TypeError, "buffer object expected"); | |
| 181 | + return NULL; | |
| 182 | + } | |
| 183 | + | |
| 184 | + return buffer_from_object(base, size, offset, 0); | |
| 185 | +} | |
| 186 | + | |
| 187 | +PyObject * | |
| 188 | +PyBuffer_FromMemory(void *ptr, Py_ssize_t size) | |
| 189 | +{ | |
| 190 | + return buffer_from_memory(NULL, size, 0, ptr, 1); | |
| 191 | +} | |
| 192 | + | |
| 193 | +PyObject * | |
| 194 | +PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size) | |
| 195 | +{ | |
| 196 | + return buffer_from_memory(NULL, size, 0, ptr, 0); | |
| 197 | +} | |
| 198 | + | |
| 199 | +PyObject * | |
| 200 | +PyBuffer_New(Py_ssize_t size) | |
| 201 | +{ | |
| 202 | + PyObject *o; | |
| 203 | + PyBufferObject * b; | |
| 204 | + | |
| 205 | + if (size < 0) { | |
| 206 | + PyErr_SetString(PyExc_ValueError, | |
| 207 | + "size must be zero or positive"); | |
| 208 | + return NULL; | |
| 209 | + } | |
| 210 | + /* XXX: check for overflow in multiply */ | |
| 211 | + /* Inline PyObject_New */ | |
| 212 | + o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size); | |
| 213 | + if ( o == NULL ) | |
| 214 | + return PyErr_NoMemory(); | |
| 215 | + b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type); | |
| 216 | + | |
| 217 | + b->b_base = NULL; | |
| 218 | + b->b_ptr = (void *)(b + 1); | |
| 219 | + b->b_size = size; | |
| 220 | + b->b_offset = 0; | |
| 221 | + b->b_readonly = 0; | |
| 222 | + b->b_hash = -1; | |
| 223 | + | |
| 224 | + return o; | |
| 225 | +} | |
| 226 | + | |
| 227 | +/* Methods */ | |
| 228 | + | |
| 229 | +static PyObject * | |
| 230 | +buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw) | |
| 231 | +{ | |
| 232 | + PyObject *ob; | |
| 233 | + Py_ssize_t offset = 0; | |
| 234 | + Py_ssize_t size = Py_END_OF_BUFFER; | |
| 235 | + | |
| 236 | + if (!_PyArg_NoKeywords("buffer()", kw)) | |
| 237 | + return NULL; | |
| 238 | + | |
| 239 | + if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size)) | |
| 240 | + return NULL; | |
| 241 | + return PyBuffer_FromObject(ob, offset, size); | |
| 242 | +} | |
| 243 | + | |
| 244 | +PyDoc_STRVAR(buffer_doc, | |
| 245 | +"buffer(object [, offset[, size]])\n\ | |
| 246 | +\n\ | |
| 247 | +Create a new buffer object which references the given object.\n\ | |
| 248 | +The buffer will reference a slice of the target object from the\n\ | |
| 249 | +start of the object (or at the specified offset). The slice will\n\ | |
| 250 | +extend to the end of the target object (or with the specified size)."); | |
| 251 | + | |
| 252 | + | |
| 253 | +static void | |
| 254 | +buffer_dealloc(PyBufferObject *self) | |
| 255 | +{ | |
| 256 | + Py_XDECREF(self->b_base); | |
| 257 | + PyObject_DEL(self); | |
| 258 | +} | |
| 259 | + | |
| 260 | +static int | |
| 261 | +buffer_compare(PyBufferObject *self, PyBufferObject *other) | |
| 262 | +{ | |
| 263 | + void *p1, *p2; | |
| 264 | + Py_ssize_t len_self, len_other, min_len; | |
| 265 | + int cmp; | |
| 266 | + | |
| 267 | + if (!get_buf(self, &p1, &len_self, ANY_BUFFER)) | |
| 268 | + return -1; | |
| 269 | + if (!get_buf(other, &p2, &len_other, ANY_BUFFER)) | |
| 270 | + return -1; | |
| 271 | + min_len = (len_self < len_other) ? len_self : len_other; | |
| 272 | + if (min_len > 0) { | |
| 273 | + cmp = memcmp(p1, p2, min_len); | |
| 274 | + if (cmp != 0) | |
| 275 | + return cmp < 0 ? -1 : 1; | |
| 276 | + } | |
| 277 | + return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0; | |
| 278 | +} | |
| 279 | + | |
| 280 | +static PyObject * | |
| 281 | +buffer_repr(PyBufferObject *self) | |
| 282 | +{ | |
| 283 | + const char *status = self->b_readonly ? "read-only" : "read-write"; | |
| 284 | + | |
| 285 | + if ( self->b_base == NULL ) | |
| 286 | + return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>", | |
| 287 | + status, | |
| 288 | + self->b_ptr, | |
| 289 | + self->b_size, | |
| 290 | + self); | |
| 291 | + else | |
| 292 | + return PyString_FromFormat( | |
| 293 | + "<%s buffer for %p, size %zd, offset %zd at %p>", | |
| 294 | + status, | |
| 295 | + self->b_base, | |
| 296 | + self->b_size, | |
| 297 | + self->b_offset, | |
| 298 | + self); | |
| 299 | +} | |
| 300 | + | |
| 301 | +static long | |
| 302 | +buffer_hash(PyBufferObject *self) | |
| 303 | +{ | |
| 304 | + void *ptr; | |
| 305 | + Py_ssize_t size; | |
| 306 | + register Py_ssize_t len; | |
| 307 | + register unsigned char *p; | |
| 308 | + register long x; | |
| 309 | + | |
| 310 | + if ( self->b_hash != -1 ) | |
| 311 | + return self->b_hash; | |
| 312 | + | |
| 313 | + /* XXX potential bugs here, a readonly buffer does not imply that the | |
| 314 | + * underlying memory is immutable. b_readonly is a necessary but not | |
| 315 | + * sufficient condition for a buffer to be hashable. Perhaps it would | |
| 316 | + * be better to only allow hashing if the underlying object is known to | |
| 317 | + * be immutable (e.g. PyString_Check() is true). Another idea would | |
| 318 | + * be to call tp_hash on the underlying object and see if it raises | |
| 319 | + * an error. */ | |
| 320 | + if ( !self->b_readonly ) | |
| 321 | + { | |
| 322 | + PyErr_SetString(PyExc_TypeError, | |
| 323 | + "writable buffers are not hashable"); | |
| 324 | + return -1; | |
| 325 | + } | |
| 326 | + | |
| 327 | + if (!get_buf(self, &ptr, &size, ANY_BUFFER)) | |
| 328 | + return -1; | |
| 329 | + p = (unsigned char *) ptr; | |
| 330 | + len = size; | |
| 331 | + x = *p << 7; | |
| 332 | + while (--len >= 0) | |
| 333 | + x = (1000003*x) ^ *p++; | |
| 334 | + x ^= size; | |
| 335 | + if (x == -1) | |
| 336 | + x = -2; | |
| 337 | + self->b_hash = x; | |
| 338 | + return x; | |
| 339 | +} | |
| 340 | + | |
| 341 | +static PyObject * | |
| 342 | +buffer_str(PyBufferObject *self) | |
| 343 | +{ | |
| 344 | + void *ptr; | |
| 345 | + Py_ssize_t size; | |
| 346 | + if (!get_buf(self, &ptr, &size, ANY_BUFFER)) | |
| 347 | + return NULL; | |
| 348 | + return PyString_FromStringAndSize((const char *)ptr, size); | |
| 349 | +} | |
| 350 | + | |
| 351 | +/* Sequence methods */ | |
| 352 | + | |
| 353 | +static Py_ssize_t | |
| 354 | +buffer_length(PyBufferObject *self) | |
| 355 | +{ | |
| 356 | + void *ptr; | |
| 357 | + Py_ssize_t size; | |
| 358 | + if (!get_buf(self, &ptr, &size, ANY_BUFFER)) | |
| 359 | + return -1; | |
| 360 | + return size; | |
| 361 | +} | |
| 362 | + | |
| 363 | +static PyObject * | |
| 364 | +buffer_concat(PyBufferObject *self, PyObject *other) | |
| 365 | +{ | |
| 366 | + PyBufferProcs *pb = other->ob_type->tp_as_buffer; | |
| 367 | + void *ptr1, *ptr2; | |
| 368 | + char *p; | |
| 369 | + PyObject *ob; | |
| 370 | + Py_ssize_t size, count; | |
| 371 | + | |
| 372 | + if ( pb == NULL || | |
| 373 | + pb->bf_getreadbuffer == NULL || | |
| 374 | + pb->bf_getsegcount == NULL ) | |
| 375 | + { | |
| 376 | + PyErr_BadArgument(); | |
| 377 | + return NULL; | |
| 378 | + } | |
| 379 | + if ( (*pb->bf_getsegcount)(other, NULL) != 1 ) | |
| 380 | + { | |
| 381 | + /* ### use a different exception type/message? */ | |
| 382 | + PyErr_SetString(PyExc_TypeError, | |
| 383 | + "single-segment buffer object expected"); | |
| 384 | + return NULL; | |
| 385 | + } | |
| 386 | + | |
| 387 | + if (!get_buf(self, &ptr1, &size, ANY_BUFFER)) | |
| 388 | + return NULL; | |
| 389 | + | |
| 390 | + /* optimize special case */ | |
| 391 | + if ( size == 0 ) | |
| 392 | + { | |
| 393 | + Py_INCREF(other); | |
| 394 | + return other; | |
| 395 | + } | |
| 396 | + | |
| 397 | + if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 ) | |
| 398 | + return NULL; | |
| 399 | + | |
| 400 | + ob = PyString_FromStringAndSize(NULL, size + count); | |
| 401 | + if ( ob == NULL ) | |
| 402 | + return NULL; | |
| 403 | + p = PyString_AS_STRING(ob); | |
| 404 | + memcpy(p, ptr1, size); | |
| 405 | + memcpy(p + size, ptr2, count); | |
| 406 | + | |
| 407 | + /* there is an extra byte in the string object, so this is safe */ | |
| 408 | + p[size + count] = '\0'; | |
| 409 | + | |
| 410 | + return ob; | |
| 411 | +} | |
| 412 | + | |
| 413 | +static PyObject * | |
| 414 | +buffer_repeat(PyBufferObject *self, Py_ssize_t count) | |
| 415 | +{ | |
| 416 | + PyObject *ob; | |
| 417 | + register char *p; | |
| 418 | + void *ptr; | |
| 419 | + Py_ssize_t size; | |
| 420 | + | |
| 421 | + if ( count < 0 ) | |
| 422 | + count = 0; | |
| 423 | + if (!get_buf(self, &ptr, &size, ANY_BUFFER)) | |
| 424 | + return NULL; | |
| 425 | + ob = PyString_FromStringAndSize(NULL, size * count); | |
| 426 | + if ( ob == NULL ) | |
| 427 | + return NULL; | |
| 428 | + | |
| 429 | + p = PyString_AS_STRING(ob); | |
| 430 | + while ( count-- ) | |
| 431 | + { | |
| 432 | + memcpy(p, ptr, size); | |
| 433 | + p += size; | |
| 434 | + } | |
| 435 | + | |
| 436 | + /* there is an extra byte in the string object, so this is safe */ | |
| 437 | + *p = '\0'; | |
| 438 | + | |
| 439 | + return ob; | |
| 440 | +} | |
| 441 | + | |
| 442 | +static PyObject * | |
| 443 | +buffer_item(PyBufferObject *self, Py_ssize_t idx) | |
| 444 | +{ | |
| 445 | + void *ptr; | |
| 446 | + Py_ssize_t size; | |
| 447 | + if (!get_buf(self, &ptr, &size, ANY_BUFFER)) | |
| 448 | + return NULL; | |
| 449 | + if ( idx < 0 || idx >= size ) { | |
| 450 | + PyErr_SetString(PyExc_IndexError, "buffer index out of range"); | |
| 451 | + return NULL; | |
| 452 | + } | |
| 453 | + return PyString_FromStringAndSize((char *)ptr + idx, 1); | |
| 454 | +} | |
| 455 | + | |
| 456 | +static PyObject * | |
| 457 | +buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right) | |
| 458 | +{ | |
| 459 | + void *ptr; | |
| 460 | + Py_ssize_t size; | |
| 461 | + if (!get_buf(self, &ptr, &size, ANY_BUFFER)) | |
| 462 | + return NULL; | |
| 463 | + if ( left < 0 ) | |
| 464 | + left = 0; | |
| 465 | + if ( right < 0 ) | |
| 466 | + right = 0; | |
| 467 | + if ( right > size ) | |
| 468 | + right = size; | |
| 469 | + if ( right < left ) | |
| 470 | + right = left; | |
| 471 | + return PyString_FromStringAndSize((char *)ptr + left, | |
| 472 | + right - left); | |
| 473 | +} | |
| 474 | + | |
| 475 | +static int | |
| 476 | +buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other) | |
| 477 | +{ | |
| 478 | + PyBufferProcs *pb; | |
| 479 | + void *ptr1, *ptr2; | |
| 480 | + Py_ssize_t size; | |
| 481 | + Py_ssize_t count; | |
| 482 | + | |
| 483 | + if ( self->b_readonly ) { | |
| 484 | + PyErr_SetString(PyExc_TypeError, | |
| 485 | + "buffer is read-only"); | |
| 486 | + return -1; | |
| 487 | + } | |
| 488 | + | |
| 489 | + if (!get_buf(self, &ptr1, &size, ANY_BUFFER)) | |
| 490 | + return -1; | |
| 491 | + | |
| 492 | + if (idx < 0 || idx >= size) { | |
| 493 | + PyErr_SetString(PyExc_IndexError, | |
| 494 | + "buffer assignment index out of range"); | |
| 495 | + return -1; | |
| 496 | + } | |
| 497 | + | |
| 498 | + pb = other ? other->ob_type->tp_as_buffer : NULL; | |
| 499 | + if ( pb == NULL || | |
| 500 | + pb->bf_getreadbuffer == NULL || | |
| 501 | + pb->bf_getsegcount == NULL ) | |
| 502 | + { | |
| 503 | + PyErr_BadArgument(); | |
| 504 | + return -1; | |
| 505 | + } | |
| 506 | + if ( (*pb->bf_getsegcount)(other, NULL) != 1 ) | |
| 507 | + { | |
| 508 | + /* ### use a different exception type/message? */ | |
| 509 | + PyErr_SetString(PyExc_TypeError, | |
| 510 | + "single-segment buffer object expected"); | |
| 511 | + return -1; | |
| 512 | + } | |
| 513 | + | |
| 514 | + if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 ) | |
| 515 | + return -1; | |
| 516 | + if ( count != 1 ) { | |
| 517 | + PyErr_SetString(PyExc_TypeError, | |
| 518 | + "right operand must be a single byte"); | |
| 519 | + return -1; | |
| 520 | + } | |
| 521 | + | |
| 522 | + ((char *)ptr1)[idx] = *(char *)ptr2; | |
| 523 | + return 0; | |
| 524 | +} | |
| 525 | + | |
| 526 | +static int | |
| 527 | +buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other) | |
| 528 | +{ | |
| 529 | + PyBufferProcs *pb; | |
| 530 | + void *ptr1, *ptr2; | |
| 531 | + Py_ssize_t size; | |
| 532 | + Py_ssize_t slice_len; | |
| 533 | + Py_ssize_t count; | |
| 534 | + | |
| 535 | + if ( self->b_readonly ) { | |
| 536 | + PyErr_SetString(PyExc_TypeError, | |
| 537 | + "buffer is read-only"); | |
| 538 | + return -1; | |
| 539 | + } | |
| 540 | + | |
| 541 | + pb = other ? other->ob_type->tp_as_buffer : NULL; | |
| 542 | + if ( pb == NULL || | |
| 543 | + pb->bf_getreadbuffer == NULL || | |
| 544 | + pb->bf_getsegcount == NULL ) | |
| 545 | + { | |
| 546 | + PyErr_BadArgument(); | |
| 547 | + return -1; | |
| 548 | + } | |
| 549 | + if ( (*pb->bf_getsegcount)(other, NULL) != 1 ) | |
| 550 | + { | |
| 551 | + /* ### use a different exception type/message? */ | |
| 552 | + PyErr_SetString(PyExc_TypeError, | |
| 553 | + "single-segment buffer object expected"); | |
| 554 | + return -1; | |
| 555 | + } | |
| 556 | + if (!get_buf(self, &ptr1, &size, ANY_BUFFER)) | |
| 557 | + return -1; | |
| 558 | + if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 ) | |
| 559 | + return -1; | |
| 560 | + | |
| 561 | + if ( left < 0 ) | |
| 562 | + left = 0; | |
| 563 | + else if ( left > size ) | |
| 564 | + left = size; | |
| 565 | + if ( right < left ) | |
| 566 | + right = left; | |
| 567 | + else if ( right > size ) | |
| 568 | + right = size; | |
| 569 | + slice_len = right - left; | |
| 570 | + | |
| 571 | + if ( count != slice_len ) { | |
| 572 | + PyErr_SetString( | |
| 573 | + PyExc_TypeError, | |
| 574 | + "right operand length must match slice length"); | |
| 575 | + return -1; | |
| 576 | + } | |
| 577 | + | |
| 578 | + if ( slice_len ) | |
| 579 | + memcpy((char *)ptr1 + left, ptr2, slice_len); | |
| 580 | + | |
| 581 | + return 0; | |
| 582 | +} | |
| 583 | + | |
| 584 | +/* Buffer methods */ | |
| 585 | + | |
| 586 | +static Py_ssize_t | |
| 587 | +buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp) | |
| 588 | +{ | |
| 589 | + Py_ssize_t size; | |
| 590 | + if ( idx != 0 ) { | |
| 591 | + PyErr_SetString(PyExc_SystemError, | |
| 592 | + "accessing non-existent buffer segment"); | |
| 593 | + return -1; | |
| 594 | + } | |
| 595 | + if (!get_buf(self, pp, &size, READ_BUFFER)) | |
| 596 | + return -1; | |
| 597 | + return size; | |
| 598 | +} | |
| 599 | + | |
| 600 | +static Py_ssize_t | |
| 601 | +buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp) | |
| 602 | +{ | |
| 603 | + Py_ssize_t size; | |
| 604 | + | |
| 605 | + if ( self->b_readonly ) | |
| 606 | + { | |
| 607 | + PyErr_SetString(PyExc_TypeError, "buffer is read-only"); | |
| 608 | + return -1; | |
| 609 | + } | |
| 610 | + | |
| 611 | + if ( idx != 0 ) { | |
| 612 | + PyErr_SetString(PyExc_SystemError, | |
| 613 | + "accessing non-existent buffer segment"); | |
| 614 | + return -1; | |
| 615 | + } | |
| 616 | + if (!get_buf(self, pp, &size, WRITE_BUFFER)) | |
| 617 | + return -1; | |
| 618 | + return size; | |
| 619 | +} | |
| 620 | + | |
| 621 | +static Py_ssize_t | |
| 622 | +buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp) | |
| 623 | +{ | |
| 624 | + void *ptr; | |
| 625 | + Py_ssize_t size; | |
| 626 | + if (!get_buf(self, &ptr, &size, ANY_BUFFER)) | |
| 627 | + return -1; | |
| 628 | + if (lenp) | |
| 629 | + *lenp = size; | |
| 630 | + return 1; | |
| 631 | +} | |
| 632 | + | |
| 633 | +static Py_ssize_t | |
| 634 | +buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp) | |
| 635 | +{ | |
| 636 | + void *ptr; | |
| 637 | + Py_ssize_t size; | |
| 638 | + if ( idx != 0 ) { | |
| 639 | + PyErr_SetString(PyExc_SystemError, | |
| 640 | + "accessing non-existent buffer segment"); | |
| 641 | + return -1; | |
| 642 | + } | |
| 643 | + if (!get_buf(self, &ptr, &size, CHAR_BUFFER)) | |
| 644 | + return -1; | |
| 645 | + *pp = (const char *)ptr; | |
| 646 | + return size; | |
| 647 | +} | |
| 648 | + | |
| 649 | +static PySequenceMethods buffer_as_sequence = { | |
| 650 | + (lenfunc)buffer_length, /*sq_length*/ | |
| 651 | + (binaryfunc)buffer_concat, /*sq_concat*/ | |
| 652 | + (ssizeargfunc)buffer_repeat, /*sq_repeat*/ | |
| 653 | + (ssizeargfunc)buffer_item, /*sq_item*/ | |
| 654 | + (ssizessizeargfunc)buffer_slice, /*sq_slice*/ | |
| 655 | + (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/ | |
| 656 | + (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/ | |
| 657 | +}; | |
| 658 | + | |
| 659 | +static PyBufferProcs buffer_as_buffer = { | |
| 660 | + (readbufferproc)buffer_getreadbuf, | |
| 661 | + (writebufferproc)buffer_getwritebuf, | |
| 662 | + (segcountproc)buffer_getsegcount, | |
| 663 | + (charbufferproc)buffer_getcharbuf, | |
| 664 | +}; | |
| 665 | + | |
| 666 | +PyTypeObject PyBuffer_Type = { | |
| 667 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 668 | + 0, | |
| 669 | + "buffer", | |
| 670 | + sizeof(PyBufferObject), | |
| 671 | + 0, | |
| 672 | + (destructor)buffer_dealloc, /* tp_dealloc */ | |
| 673 | + 0, /* tp_print */ | |
| 674 | + 0, /* tp_getattr */ | |
| 675 | + 0, /* tp_setattr */ | |
| 676 | + (cmpfunc)buffer_compare, /* tp_compare */ | |
| 677 | + (reprfunc)buffer_repr, /* tp_repr */ | |
| 678 | + 0, /* tp_as_number */ | |
| 679 | + &buffer_as_sequence, /* tp_as_sequence */ | |
| 680 | + 0, /* tp_as_mapping */ | |
| 681 | + (hashfunc)buffer_hash, /* tp_hash */ | |
| 682 | + 0, /* tp_call */ | |
| 683 | + (reprfunc)buffer_str, /* tp_str */ | |
| 684 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 685 | + 0, /* tp_setattro */ | |
| 686 | + &buffer_as_buffer, /* tp_as_buffer */ | |
| 687 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */ | |
| 688 | + buffer_doc, /* tp_doc */ | |
| 689 | + 0, /* tp_traverse */ | |
| 690 | + 0, /* tp_clear */ | |
| 691 | + 0, /* tp_richcompare */ | |
| 692 | + 0, /* tp_weaklistoffset */ | |
| 693 | + 0, /* tp_iter */ | |
| 694 | + 0, /* tp_iternext */ | |
| 695 | + 0, /* tp_methods */ | |
| 696 | + 0, /* tp_members */ | |
| 697 | + 0, /* tp_getset */ | |
| 698 | + 0, /* tp_base */ | |
| 699 | + 0, /* tp_dict */ | |
| 700 | + 0, /* tp_descr_get */ | |
| 701 | + 0, /* tp_descr_set */ | |
| 702 | + 0, /* tp_dictoffset */ | |
| 703 | + 0, /* tp_init */ | |
| 704 | + 0, /* tp_alloc */ | |
| 705 | + buffer_new, /* tp_new */ | |
| 706 | +}; | |
| @@ -0,0 +1,133 @@ | ||
| 1 | +/* Cell object implementation */ | |
| 2 | + | |
| 3 | +#include "Python.h" | |
| 4 | + | |
| 5 | +PyObject * | |
| 6 | +PyCell_New(PyObject *obj) | |
| 7 | +{ | |
| 8 | + PyCellObject *op; | |
| 9 | + | |
| 10 | + op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type); | |
| 11 | + if (op == NULL) | |
| 12 | + return NULL; | |
| 13 | + op->ob_ref = obj; | |
| 14 | + Py_XINCREF(obj); | |
| 15 | + | |
| 16 | + _PyObject_GC_TRACK(op); | |
| 17 | + return (PyObject *)op; | |
| 18 | +} | |
| 19 | + | |
| 20 | +PyObject * | |
| 21 | +PyCell_Get(PyObject *op) | |
| 22 | +{ | |
| 23 | + if (!PyCell_Check(op)) { | |
| 24 | + PyErr_BadInternalCall(); | |
| 25 | + return NULL; | |
| 26 | + } | |
| 27 | + Py_XINCREF(((PyCellObject*)op)->ob_ref); | |
| 28 | + return PyCell_GET(op); | |
| 29 | +} | |
| 30 | + | |
| 31 | +int | |
| 32 | +PyCell_Set(PyObject *op, PyObject *obj) | |
| 33 | +{ | |
| 34 | + if (!PyCell_Check(op)) { | |
| 35 | + PyErr_BadInternalCall(); | |
| 36 | + return -1; | |
| 37 | + } | |
| 38 | + Py_XDECREF(((PyCellObject*)op)->ob_ref); | |
| 39 | + Py_XINCREF(obj); | |
| 40 | + PyCell_SET(op, obj); | |
| 41 | + return 0; | |
| 42 | +} | |
| 43 | + | |
| 44 | +static void | |
| 45 | +cell_dealloc(PyCellObject *op) | |
| 46 | +{ | |
| 47 | + _PyObject_GC_UNTRACK(op); | |
| 48 | + Py_XDECREF(op->ob_ref); | |
| 49 | + PyObject_GC_Del(op); | |
| 50 | +} | |
| 51 | + | |
| 52 | +static int | |
| 53 | +cell_compare(PyCellObject *a, PyCellObject *b) | |
| 54 | +{ | |
| 55 | + if (a->ob_ref == NULL) { | |
| 56 | + if (b->ob_ref == NULL) | |
| 57 | + return 0; | |
| 58 | + return -1; | |
| 59 | + } else if (b->ob_ref == NULL) | |
| 60 | + return 1; | |
| 61 | + return PyObject_Compare(a->ob_ref, b->ob_ref); | |
| 62 | +} | |
| 63 | + | |
| 64 | +static PyObject * | |
| 65 | +cell_repr(PyCellObject *op) | |
| 66 | +{ | |
| 67 | + if (op->ob_ref == NULL) | |
| 68 | + return PyString_FromFormat("<cell at %p: empty>", op); | |
| 69 | + | |
| 70 | + return PyString_FromFormat("<cell at %p: %.80s object at %p>", | |
| 71 | + op, op->ob_ref->ob_type->tp_name, | |
| 72 | + op->ob_ref); | |
| 73 | +} | |
| 74 | + | |
| 75 | +static int | |
| 76 | +cell_traverse(PyCellObject *op, visitproc visit, void *arg) | |
| 77 | +{ | |
| 78 | + Py_VISIT(op->ob_ref); | |
| 79 | + return 0; | |
| 80 | +} | |
| 81 | + | |
| 82 | +static int | |
| 83 | +cell_clear(PyCellObject *op) | |
| 84 | +{ | |
| 85 | + Py_CLEAR(op->ob_ref); | |
| 86 | + return 0; | |
| 87 | +} | |
| 88 | + | |
| 89 | +static PyObject * | |
| 90 | +cell_get_contents(PyCellObject *op, void *closure) | |
| 91 | +{ | |
| 92 | + Py_XINCREF(op->ob_ref); | |
| 93 | + return op->ob_ref; | |
| 94 | +} | |
| 95 | + | |
| 96 | +static PyGetSetDef cell_getsetlist[] = { | |
| 97 | + {"cell_contents", (getter)cell_get_contents, NULL}, | |
| 98 | + {NULL} /* sentinel */ | |
| 99 | +}; | |
| 100 | + | |
| 101 | +PyTypeObject PyCell_Type = { | |
| 102 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 103 | + 0, | |
| 104 | + "cell", | |
| 105 | + sizeof(PyCellObject), | |
| 106 | + 0, | |
| 107 | + (destructor)cell_dealloc, /* tp_dealloc */ | |
| 108 | + 0, /* tp_print */ | |
| 109 | + 0, /* tp_getattr */ | |
| 110 | + 0, /* tp_setattr */ | |
| 111 | + (cmpfunc)cell_compare, /* tp_compare */ | |
| 112 | + (reprfunc)cell_repr, /* tp_repr */ | |
| 113 | + 0, /* tp_as_number */ | |
| 114 | + 0, /* tp_as_sequence */ | |
| 115 | + 0, /* tp_as_mapping */ | |
| 116 | + 0, /* tp_hash */ | |
| 117 | + 0, /* tp_call */ | |
| 118 | + 0, /* tp_str */ | |
| 119 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 120 | + 0, /* tp_setattro */ | |
| 121 | + 0, /* tp_as_buffer */ | |
| 122 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | |
| 123 | + 0, /* tp_doc */ | |
| 124 | + (traverseproc)cell_traverse, /* tp_traverse */ | |
| 125 | + (inquiry)cell_clear, /* tp_clear */ | |
| 126 | + 0, /* tp_richcompare */ | |
| 127 | + 0, /* tp_weaklistoffset */ | |
| 128 | + 0, /* tp_iter */ | |
| 129 | + 0, /* tp_iternext */ | |
| 130 | + 0, /* tp_methods */ | |
| 131 | + 0, /* tp_members */ | |
| 132 | + cell_getsetlist, /* tp_getset */ | |
| 133 | +}; | |
| @@ -0,0 +1,2580 @@ | ||
| 1 | + | |
| 2 | +/* Class object implementation */ | |
| 3 | + | |
| 4 | +#include "Python.h" | |
| 5 | +#include "structmember.h" | |
| 6 | + | |
| 7 | +#define TP_DESCR_GET(t) \ | |
| 8 | + (PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL) | |
| 9 | + | |
| 10 | + | |
| 11 | +/* Forward */ | |
| 12 | +static PyObject *class_lookup(PyClassObject *, PyObject *, | |
| 13 | + PyClassObject **); | |
| 14 | +static PyObject *instance_getattr1(PyInstanceObject *, PyObject *); | |
| 15 | +static PyObject *instance_getattr2(PyInstanceObject *, PyObject *); | |
| 16 | + | |
| 17 | +static PyObject *getattrstr, *setattrstr, *delattrstr; | |
| 18 | + | |
| 19 | + | |
| 20 | +PyObject * | |
| 21 | +PyClass_New(PyObject *bases, PyObject *dict, PyObject *name) | |
| 22 | + /* bases is NULL or tuple of classobjects! */ | |
| 23 | +{ | |
| 24 | + PyClassObject *op, *dummy; | |
| 25 | + static PyObject *docstr, *modstr, *namestr; | |
| 26 | + if (docstr == NULL) { | |
| 27 | + docstr= PyString_InternFromString("__doc__"); | |
| 28 | + if (docstr == NULL) | |
| 29 | + return NULL; | |
| 30 | + } | |
| 31 | + if (modstr == NULL) { | |
| 32 | + modstr= PyString_InternFromString("__module__"); | |
| 33 | + if (modstr == NULL) | |
| 34 | + return NULL; | |
| 35 | + } | |
| 36 | + if (namestr == NULL) { | |
| 37 | + namestr= PyString_InternFromString("__name__"); | |
| 38 | + if (namestr == NULL) | |
| 39 | + return NULL; | |
| 40 | + } | |
| 41 | + if (name == NULL || !PyString_Check(name)) { | |
| 42 | + PyErr_SetString(PyExc_TypeError, | |
| 43 | + "PyClass_New: name must be a string"); | |
| 44 | + return NULL; | |
| 45 | + } | |
| 46 | + if (dict == NULL || !PyDict_Check(dict)) { | |
| 47 | + PyErr_SetString(PyExc_TypeError, | |
| 48 | + "PyClass_New: dict must be a dictionary"); | |
| 49 | + return NULL; | |
| 50 | + } | |
| 51 | + if (PyDict_GetItem(dict, docstr) == NULL) { | |
| 52 | + if (PyDict_SetItem(dict, docstr, Py_None) < 0) | |
| 53 | + return NULL; | |
| 54 | + } | |
| 55 | + if (PyDict_GetItem(dict, modstr) == NULL) { | |
| 56 | + PyObject *globals = PyEval_GetGlobals(); | |
| 57 | + if (globals != NULL) { | |
| 58 | + PyObject *modname = PyDict_GetItem(globals, namestr); | |
| 59 | + if (modname != NULL) { | |
| 60 | + if (PyDict_SetItem(dict, modstr, modname) < 0) | |
| 61 | + return NULL; | |
| 62 | + } | |
| 63 | + } | |
| 64 | + } | |
| 65 | + if (bases == NULL) { | |
| 66 | + bases = PyTuple_New(0); | |
| 67 | + if (bases == NULL) | |
| 68 | + return NULL; | |
| 69 | + } | |
| 70 | + else { | |
| 71 | + Py_ssize_t i, n; | |
| 72 | + PyObject *base; | |
| 73 | + if (!PyTuple_Check(bases)) { | |
| 74 | + PyErr_SetString(PyExc_TypeError, | |
| 75 | + "PyClass_New: bases must be a tuple"); | |
| 76 | + return NULL; | |
| 77 | + } | |
| 78 | + n = PyTuple_Size(bases); | |
| 79 | + for (i = 0; i < n; i++) { | |
| 80 | + base = PyTuple_GET_ITEM(bases, i); | |
| 81 | + if (!PyClass_Check(base)) { | |
| 82 | + if (PyCallable_Check( | |
| 83 | + (PyObject *) base->ob_type)) | |
| 84 | + return PyObject_CallFunctionObjArgs( | |
| 85 | + (PyObject *) base->ob_type, | |
| 86 | + name, bases, dict, NULL); | |
| 87 | + PyErr_SetString(PyExc_TypeError, | |
| 88 | + "PyClass_New: base must be a class"); | |
| 89 | + return NULL; | |
| 90 | + } | |
| 91 | + } | |
| 92 | + Py_INCREF(bases); | |
| 93 | + } | |
| 94 | + | |
| 95 | + if (getattrstr == NULL) { | |
| 96 | + getattrstr = PyString_InternFromString("__getattr__"); | |
| 97 | + if (getattrstr == NULL) | |
| 98 | + goto alloc_error; | |
| 99 | + setattrstr = PyString_InternFromString("__setattr__"); | |
| 100 | + if (setattrstr == NULL) | |
| 101 | + goto alloc_error; | |
| 102 | + delattrstr = PyString_InternFromString("__delattr__"); | |
| 103 | + if (delattrstr == NULL) | |
| 104 | + goto alloc_error; | |
| 105 | + } | |
| 106 | + | |
| 107 | + op = PyObject_GC_New(PyClassObject, &PyClass_Type); | |
| 108 | + if (op == NULL) { | |
| 109 | +alloc_error: | |
| 110 | + Py_DECREF(bases); | |
| 111 | + return NULL; | |
| 112 | + } | |
| 113 | + op->cl_bases = bases; | |
| 114 | + Py_INCREF(dict); | |
| 115 | + op->cl_dict = dict; | |
| 116 | + Py_XINCREF(name); | |
| 117 | + op->cl_name = name; | |
| 118 | + | |
| 119 | + op->cl_getattr = class_lookup(op, getattrstr, &dummy); | |
| 120 | + op->cl_setattr = class_lookup(op, setattrstr, &dummy); | |
| 121 | + op->cl_delattr = class_lookup(op, delattrstr, &dummy); | |
| 122 | + Py_XINCREF(op->cl_getattr); | |
| 123 | + Py_XINCREF(op->cl_setattr); | |
| 124 | + Py_XINCREF(op->cl_delattr); | |
| 125 | + _PyObject_GC_TRACK(op); | |
| 126 | + return (PyObject *) op; | |
| 127 | +} | |
| 128 | + | |
| 129 | +PyObject * | |
| 130 | +PyMethod_Function(PyObject *im) | |
| 131 | +{ | |
| 132 | + if (!PyMethod_Check(im)) { | |
| 133 | + PyErr_BadInternalCall(); | |
| 134 | + return NULL; | |
| 135 | + } | |
| 136 | + return ((PyMethodObject *)im)->im_func; | |
| 137 | +} | |
| 138 | + | |
| 139 | +PyObject * | |
| 140 | +PyMethod_Self(PyObject *im) | |
| 141 | +{ | |
| 142 | + if (!PyMethod_Check(im)) { | |
| 143 | + PyErr_BadInternalCall(); | |
| 144 | + return NULL; | |
| 145 | + } | |
| 146 | + return ((PyMethodObject *)im)->im_self; | |
| 147 | +} | |
| 148 | + | |
| 149 | +PyObject * | |
| 150 | +PyMethod_Class(PyObject *im) | |
| 151 | +{ | |
| 152 | + if (!PyMethod_Check(im)) { | |
| 153 | + PyErr_BadInternalCall(); | |
| 154 | + return NULL; | |
| 155 | + } | |
| 156 | + return ((PyMethodObject *)im)->im_class; | |
| 157 | +} | |
| 158 | + | |
| 159 | +PyDoc_STRVAR(class_doc, | |
| 160 | +"classobj(name, bases, dict)\n\ | |
| 161 | +\n\ | |
| 162 | +Create a class object. The name must be a string; the second argument\n\ | |
| 163 | +a tuple of classes, and the third a dictionary."); | |
| 164 | + | |
| 165 | +static PyObject * | |
| 166 | +class_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 167 | +{ | |
| 168 | + PyObject *name, *bases, *dict; | |
| 169 | + static char *kwlist[] = {"name", "bases", "dict", 0}; | |
| 170 | + | |
| 171 | + if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist, | |
| 172 | + &name, &bases, &dict)) | |
| 173 | + return NULL; | |
| 174 | + return PyClass_New(bases, dict, name); | |
| 175 | +} | |
| 176 | + | |
| 177 | +/* Class methods */ | |
| 178 | + | |
| 179 | +static void | |
| 180 | +class_dealloc(PyClassObject *op) | |
| 181 | +{ | |
| 182 | + _PyObject_GC_UNTRACK(op); | |
| 183 | + Py_DECREF(op->cl_bases); | |
| 184 | + Py_DECREF(op->cl_dict); | |
| 185 | + Py_XDECREF(op->cl_name); | |
| 186 | + Py_XDECREF(op->cl_getattr); | |
| 187 | + Py_XDECREF(op->cl_setattr); | |
| 188 | + Py_XDECREF(op->cl_delattr); | |
| 189 | + PyObject_GC_Del(op); | |
| 190 | +} | |
| 191 | + | |
| 192 | +static PyObject * | |
| 193 | +class_lookup(PyClassObject *cp, PyObject *name, PyClassObject **pclass) | |
| 194 | +{ | |
| 195 | + Py_ssize_t i, n; | |
| 196 | + PyObject *value = PyDict_GetItem(cp->cl_dict, name); | |
| 197 | + if (value != NULL) { | |
| 198 | + *pclass = cp; | |
| 199 | + return value; | |
| 200 | + } | |
| 201 | + n = PyTuple_Size(cp->cl_bases); | |
| 202 | + for (i = 0; i < n; i++) { | |
| 203 | + /* XXX What if one of the bases is not a class? */ | |
| 204 | + PyObject *v = class_lookup( | |
| 205 | + (PyClassObject *) | |
| 206 | + PyTuple_GetItem(cp->cl_bases, i), name, pclass); | |
| 207 | + if (v != NULL) | |
| 208 | + return v; | |
| 209 | + } | |
| 210 | + return NULL; | |
| 211 | +} | |
| 212 | + | |
| 213 | +static PyObject * | |
| 214 | +class_getattr(register PyClassObject *op, PyObject *name) | |
| 215 | +{ | |
| 216 | + register PyObject *v; | |
| 217 | + register char *sname = PyString_AsString(name); | |
| 218 | + PyClassObject *klass; | |
| 219 | + descrgetfunc f; | |
| 220 | + | |
| 221 | + if (sname[0] == '_' && sname[1] == '_') { | |
| 222 | + if (strcmp(sname, "__dict__") == 0) { | |
| 223 | + if (PyEval_GetRestricted()) { | |
| 224 | + PyErr_SetString(PyExc_RuntimeError, | |
| 225 | + "class.__dict__ not accessible in restricted mode"); | |
| 226 | + return NULL; | |
| 227 | + } | |
| 228 | + Py_INCREF(op->cl_dict); | |
| 229 | + return op->cl_dict; | |
| 230 | + } | |
| 231 | + if (strcmp(sname, "__bases__") == 0) { | |
| 232 | + Py_INCREF(op->cl_bases); | |
| 233 | + return op->cl_bases; | |
| 234 | + } | |
| 235 | + if (strcmp(sname, "__name__") == 0) { | |
| 236 | + if (op->cl_name == NULL) | |
| 237 | + v = Py_None; | |
| 238 | + else | |
| 239 | + v = op->cl_name; | |
| 240 | + Py_INCREF(v); | |
| 241 | + return v; | |
| 242 | + } | |
| 243 | + } | |
| 244 | + v = class_lookup(op, name, &klass); | |
| 245 | + if (v == NULL) { | |
| 246 | + PyErr_Format(PyExc_AttributeError, | |
| 247 | + "class %.50s has no attribute '%.400s'", | |
| 248 | + PyString_AS_STRING(op->cl_name), sname); | |
| 249 | + return NULL; | |
| 250 | + } | |
| 251 | + f = TP_DESCR_GET(v->ob_type); | |
| 252 | + if (f == NULL) | |
| 253 | + Py_INCREF(v); | |
| 254 | + else | |
| 255 | + v = f(v, (PyObject *)NULL, (PyObject *)op); | |
| 256 | + return v; | |
| 257 | +} | |
| 258 | + | |
| 259 | +static void | |
| 260 | +set_slot(PyObject **slot, PyObject *v) | |
| 261 | +{ | |
| 262 | + PyObject *temp = *slot; | |
| 263 | + Py_XINCREF(v); | |
| 264 | + *slot = v; | |
| 265 | + Py_XDECREF(temp); | |
| 266 | +} | |
| 267 | + | |
| 268 | +static void | |
| 269 | +set_attr_slots(PyClassObject *c) | |
| 270 | +{ | |
| 271 | + PyClassObject *dummy; | |
| 272 | + | |
| 273 | + set_slot(&c->cl_getattr, class_lookup(c, getattrstr, &dummy)); | |
| 274 | + set_slot(&c->cl_setattr, class_lookup(c, setattrstr, &dummy)); | |
| 275 | + set_slot(&c->cl_delattr, class_lookup(c, delattrstr, &dummy)); | |
| 276 | +} | |
| 277 | + | |
| 278 | +static char * | |
| 279 | +set_dict(PyClassObject *c, PyObject *v) | |
| 280 | +{ | |
| 281 | + if (v == NULL || !PyDict_Check(v)) | |
| 282 | + return "__dict__ must be a dictionary object"; | |
| 283 | + set_slot(&c->cl_dict, v); | |
| 284 | + set_attr_slots(c); | |
| 285 | + return ""; | |
| 286 | +} | |
| 287 | + | |
| 288 | +static char * | |
| 289 | +set_bases(PyClassObject *c, PyObject *v) | |
| 290 | +{ | |
| 291 | + Py_ssize_t i, n; | |
| 292 | + | |
| 293 | + if (v == NULL || !PyTuple_Check(v)) | |
| 294 | + return "__bases__ must be a tuple object"; | |
| 295 | + n = PyTuple_Size(v); | |
| 296 | + for (i = 0; i < n; i++) { | |
| 297 | + PyObject *x = PyTuple_GET_ITEM(v, i); | |
| 298 | + if (!PyClass_Check(x)) | |
| 299 | + return "__bases__ items must be classes"; | |
| 300 | + if (PyClass_IsSubclass(x, (PyObject *)c)) | |
| 301 | + return "a __bases__ item causes an inheritance cycle"; | |
| 302 | + } | |
| 303 | + set_slot(&c->cl_bases, v); | |
| 304 | + set_attr_slots(c); | |
| 305 | + return ""; | |
| 306 | +} | |
| 307 | + | |
| 308 | +static char * | |
| 309 | +set_name(PyClassObject *c, PyObject *v) | |
| 310 | +{ | |
| 311 | + if (v == NULL || !PyString_Check(v)) | |
| 312 | + return "__name__ must be a string object"; | |
| 313 | + if (strlen(PyString_AS_STRING(v)) != (size_t)PyString_GET_SIZE(v)) | |
| 314 | + return "__name__ must not contain null bytes"; | |
| 315 | + set_slot(&c->cl_name, v); | |
| 316 | + return ""; | |
| 317 | +} | |
| 318 | + | |
| 319 | +static int | |
| 320 | +class_setattr(PyClassObject *op, PyObject *name, PyObject *v) | |
| 321 | +{ | |
| 322 | + char *sname; | |
| 323 | + if (PyEval_GetRestricted()) { | |
| 324 | + PyErr_SetString(PyExc_RuntimeError, | |
| 325 | + "classes are read-only in restricted mode"); | |
| 326 | + return -1; | |
| 327 | + } | |
| 328 | + sname = PyString_AsString(name); | |
| 329 | + if (sname[0] == '_' && sname[1] == '_') { | |
| 330 | + Py_ssize_t n = PyString_Size(name); | |
| 331 | + if (sname[n-1] == '_' && sname[n-2] == '_') { | |
| 332 | + char *err = NULL; | |
| 333 | + if (strcmp(sname, "__dict__") == 0) | |
| 334 | + err = set_dict(op, v); | |
| 335 | + else if (strcmp(sname, "__bases__") == 0) | |
| 336 | + err = set_bases(op, v); | |
| 337 | + else if (strcmp(sname, "__name__") == 0) | |
| 338 | + err = set_name(op, v); | |
| 339 | + else if (strcmp(sname, "__getattr__") == 0) | |
| 340 | + set_slot(&op->cl_getattr, v); | |
| 341 | + else if (strcmp(sname, "__setattr__") == 0) | |
| 342 | + set_slot(&op->cl_setattr, v); | |
| 343 | + else if (strcmp(sname, "__delattr__") == 0) | |
| 344 | + set_slot(&op->cl_delattr, v); | |
| 345 | + /* For the last three, we fall through to update the | |
| 346 | + dictionary as well. */ | |
| 347 | + if (err != NULL) { | |
| 348 | + if (*err == '\0') | |
| 349 | + return 0; | |
| 350 | + PyErr_SetString(PyExc_TypeError, err); | |
| 351 | + return -1; | |
| 352 | + } | |
| 353 | + } | |
| 354 | + } | |
| 355 | + if (v == NULL) { | |
| 356 | + int rv = PyDict_DelItem(op->cl_dict, name); | |
| 357 | + if (rv < 0) | |
| 358 | + PyErr_Format(PyExc_AttributeError, | |
| 359 | + "class %.50s has no attribute '%.400s'", | |
| 360 | + PyString_AS_STRING(op->cl_name), sname); | |
| 361 | + return rv; | |
| 362 | + } | |
| 363 | + else | |
| 364 | + return PyDict_SetItem(op->cl_dict, name, v); | |
| 365 | +} | |
| 366 | + | |
| 367 | +static PyObject * | |
| 368 | +class_repr(PyClassObject *op) | |
| 369 | +{ | |
| 370 | + PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__"); | |
| 371 | + char *name; | |
| 372 | + if (op->cl_name == NULL || !PyString_Check(op->cl_name)) | |
| 373 | + name = "?"; | |
| 374 | + else | |
| 375 | + name = PyString_AsString(op->cl_name); | |
| 376 | + if (mod == NULL || !PyString_Check(mod)) | |
| 377 | + return PyString_FromFormat("<class ?.%s at %p>", name, op); | |
| 378 | + else | |
| 379 | + return PyString_FromFormat("<class %s.%s at %p>", | |
| 380 | + PyString_AsString(mod), | |
| 381 | + name, op); | |
| 382 | +} | |
| 383 | + | |
| 384 | +static PyObject * | |
| 385 | +class_str(PyClassObject *op) | |
| 386 | +{ | |
| 387 | + PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__"); | |
| 388 | + PyObject *name = op->cl_name; | |
| 389 | + PyObject *res; | |
| 390 | + Py_ssize_t m, n; | |
| 391 | + | |
| 392 | + if (name == NULL || !PyString_Check(name)) | |
| 393 | + return class_repr(op); | |
| 394 | + if (mod == NULL || !PyString_Check(mod)) { | |
| 395 | + Py_INCREF(name); | |
| 396 | + return name; | |
| 397 | + } | |
| 398 | + m = PyString_GET_SIZE(mod); | |
| 399 | + n = PyString_GET_SIZE(name); | |
| 400 | + res = PyString_FromStringAndSize((char *)NULL, m+1+n); | |
| 401 | + if (res != NULL) { | |
| 402 | + char *s = PyString_AS_STRING(res); | |
| 403 | + memcpy(s, PyString_AS_STRING(mod), m); | |
| 404 | + s += m; | |
| 405 | + *s++ = '.'; | |
| 406 | + memcpy(s, PyString_AS_STRING(name), n); | |
| 407 | + } | |
| 408 | + return res; | |
| 409 | +} | |
| 410 | + | |
| 411 | +static int | |
| 412 | +class_traverse(PyClassObject *o, visitproc visit, void *arg) | |
| 413 | +{ | |
| 414 | + Py_VISIT(o->cl_bases); | |
| 415 | + Py_VISIT(o->cl_dict); | |
| 416 | + Py_VISIT(o->cl_name); | |
| 417 | + Py_VISIT(o->cl_getattr); | |
| 418 | + Py_VISIT(o->cl_setattr); | |
| 419 | + Py_VISIT(o->cl_delattr); | |
| 420 | + return 0; | |
| 421 | +} | |
| 422 | + | |
| 423 | +PyTypeObject PyClass_Type = { | |
| 424 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 425 | + 0, | |
| 426 | + "classobj", | |
| 427 | + sizeof(PyClassObject), | |
| 428 | + 0, | |
| 429 | + (destructor)class_dealloc, /* tp_dealloc */ | |
| 430 | + 0, /* tp_print */ | |
| 431 | + 0, /* tp_getattr */ | |
| 432 | + 0, /* tp_setattr */ | |
| 433 | + 0, /* tp_compare */ | |
| 434 | + (reprfunc)class_repr, /* tp_repr */ | |
| 435 | + 0, /* tp_as_number */ | |
| 436 | + 0, /* tp_as_sequence */ | |
| 437 | + 0, /* tp_as_mapping */ | |
| 438 | + 0, /* tp_hash */ | |
| 439 | + PyInstance_New, /* tp_call */ | |
| 440 | + (reprfunc)class_str, /* tp_str */ | |
| 441 | + (getattrofunc)class_getattr, /* tp_getattro */ | |
| 442 | + (setattrofunc)class_setattr, /* tp_setattro */ | |
| 443 | + 0, /* tp_as_buffer */ | |
| 444 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | |
| 445 | + class_doc, /* tp_doc */ | |
| 446 | + (traverseproc)class_traverse, /* tp_traverse */ | |
| 447 | + 0, /* tp_clear */ | |
| 448 | + 0, /* tp_richcompare */ | |
| 449 | + 0, /* tp_weaklistoffset */ | |
| 450 | + 0, /* tp_iter */ | |
| 451 | + 0, /* tp_iternext */ | |
| 452 | + 0, /* tp_methods */ | |
| 453 | + 0, /* tp_members */ | |
| 454 | + 0, /* tp_getset */ | |
| 455 | + 0, /* tp_base */ | |
| 456 | + 0, /* tp_dict */ | |
| 457 | + 0, /* tp_descr_get */ | |
| 458 | + 0, /* tp_descr_set */ | |
| 459 | + 0, /* tp_dictoffset */ | |
| 460 | + 0, /* tp_init */ | |
| 461 | + 0, /* tp_alloc */ | |
| 462 | + class_new, /* tp_new */ | |
| 463 | +}; | |
| 464 | + | |
| 465 | +int | |
| 466 | +PyClass_IsSubclass(PyObject *klass, PyObject *base) | |
| 467 | +{ | |
| 468 | + Py_ssize_t i, n; | |
| 469 | + PyClassObject *cp; | |
| 470 | + if (klass == base) | |
| 471 | + return 1; | |
| 472 | + if (PyTuple_Check(base)) { | |
| 473 | + n = PyTuple_GET_SIZE(base); | |
| 474 | + for (i = 0; i < n; i++) { | |
| 475 | + if (PyClass_IsSubclass(klass, PyTuple_GET_ITEM(base, i))) | |
| 476 | + return 1; | |
| 477 | + } | |
| 478 | + return 0; | |
| 479 | + } | |
| 480 | + if (klass == NULL || !PyClass_Check(klass)) | |
| 481 | + return 0; | |
| 482 | + cp = (PyClassObject *)klass; | |
| 483 | + n = PyTuple_Size(cp->cl_bases); | |
| 484 | + for (i = 0; i < n; i++) { | |
| 485 | + if (PyClass_IsSubclass(PyTuple_GetItem(cp->cl_bases, i), base)) | |
| 486 | + return 1; | |
| 487 | + } | |
| 488 | + return 0; | |
| 489 | +} | |
| 490 | + | |
| 491 | + | |
| 492 | +/* Instance objects */ | |
| 493 | + | |
| 494 | +PyObject * | |
| 495 | +PyInstance_NewRaw(PyObject *klass, PyObject *dict) | |
| 496 | +{ | |
| 497 | + PyInstanceObject *inst; | |
| 498 | + | |
| 499 | + if (!PyClass_Check(klass)) { | |
| 500 | + PyErr_BadInternalCall(); | |
| 501 | + return NULL; | |
| 502 | + } | |
| 503 | + if (dict == NULL) { | |
| 504 | + dict = PyDict_New(); | |
| 505 | + if (dict == NULL) | |
| 506 | + return NULL; | |
| 507 | + } | |
| 508 | + else { | |
| 509 | + if (!PyDict_Check(dict)) { | |
| 510 | + PyErr_BadInternalCall(); | |
| 511 | + return NULL; | |
| 512 | + } | |
| 513 | + Py_INCREF(dict); | |
| 514 | + } | |
| 515 | + inst = PyObject_GC_New(PyInstanceObject, &PyInstance_Type); | |
| 516 | + if (inst == NULL) { | |
| 517 | + Py_DECREF(dict); | |
| 518 | + return NULL; | |
| 519 | + } | |
| 520 | + inst->in_weakreflist = NULL; | |
| 521 | + Py_INCREF(klass); | |
| 522 | + inst->in_class = (PyClassObject *)klass; | |
| 523 | + inst->in_dict = dict; | |
| 524 | + _PyObject_GC_TRACK(inst); | |
| 525 | + return (PyObject *)inst; | |
| 526 | +} | |
| 527 | + | |
| 528 | +PyObject * | |
| 529 | +PyInstance_New(PyObject *klass, PyObject *arg, PyObject *kw) | |
| 530 | +{ | |
| 531 | + register PyInstanceObject *inst; | |
| 532 | + PyObject *init; | |
| 533 | + static PyObject *initstr; | |
| 534 | + | |
| 535 | + if (initstr == NULL) { | |
| 536 | + initstr = PyString_InternFromString("__init__"); | |
| 537 | + if (initstr == NULL) | |
| 538 | + return NULL; | |
| 539 | + } | |
| 540 | + inst = (PyInstanceObject *) PyInstance_NewRaw(klass, NULL); | |
| 541 | + if (inst == NULL) | |
| 542 | + return NULL; | |
| 543 | + init = instance_getattr2(inst, initstr); | |
| 544 | + if (init == NULL) { | |
| 545 | + if (PyErr_Occurred()) { | |
| 546 | + Py_DECREF(inst); | |
| 547 | + return NULL; | |
| 548 | + } | |
| 549 | + if ((arg != NULL && (!PyTuple_Check(arg) || | |
| 550 | + PyTuple_Size(arg) != 0)) | |
| 551 | + || (kw != NULL && (!PyDict_Check(kw) || | |
| 552 | + PyDict_Size(kw) != 0))) { | |
| 553 | + PyErr_SetString(PyExc_TypeError, | |
| 554 | + "this constructor takes no arguments"); | |
| 555 | + Py_DECREF(inst); | |
| 556 | + inst = NULL; | |
| 557 | + } | |
| 558 | + } | |
| 559 | + else { | |
| 560 | + PyObject *res = PyEval_CallObjectWithKeywords(init, arg, kw); | |
| 561 | + Py_DECREF(init); | |
| 562 | + if (res == NULL) { | |
| 563 | + Py_DECREF(inst); | |
| 564 | + inst = NULL; | |
| 565 | + } | |
| 566 | + else { | |
| 567 | + if (res != Py_None) { | |
| 568 | + PyErr_SetString(PyExc_TypeError, | |
| 569 | + "__init__() should return None"); | |
| 570 | + Py_DECREF(inst); | |
| 571 | + inst = NULL; | |
| 572 | + } | |
| 573 | + Py_DECREF(res); | |
| 574 | + } | |
| 575 | + } | |
| 576 | + return (PyObject *)inst; | |
| 577 | +} | |
| 578 | + | |
| 579 | +/* Instance methods */ | |
| 580 | + | |
| 581 | +PyDoc_STRVAR(instance_doc, | |
| 582 | +"instance(class[, dict])\n\ | |
| 583 | +\n\ | |
| 584 | +Create an instance without calling its __init__() method.\n\ | |
| 585 | +The class must be a classic class.\n\ | |
| 586 | +If present, dict must be a dictionary or None."); | |
| 587 | + | |
| 588 | +static PyObject * | |
| 589 | +instance_new(PyTypeObject* type, PyObject* args, PyObject *kw) | |
| 590 | +{ | |
| 591 | + PyObject *klass; | |
| 592 | + PyObject *dict = Py_None; | |
| 593 | + | |
| 594 | + if (!PyArg_ParseTuple(args, "O!|O:instance", | |
| 595 | + &PyClass_Type, &klass, &dict)) | |
| 596 | + return NULL; | |
| 597 | + | |
| 598 | + if (dict == Py_None) | |
| 599 | + dict = NULL; | |
| 600 | + else if (!PyDict_Check(dict)) { | |
| 601 | + PyErr_SetString(PyExc_TypeError, | |
| 602 | + "instance() second arg must be dictionary or None"); | |
| 603 | + return NULL; | |
| 604 | + } | |
| 605 | + return PyInstance_NewRaw(klass, dict); | |
| 606 | +} | |
| 607 | + | |
| 608 | + | |
| 609 | +static void | |
| 610 | +instance_dealloc(register PyInstanceObject *inst) | |
| 611 | +{ | |
| 612 | + PyObject *error_type, *error_value, *error_traceback; | |
| 613 | + PyObject *del; | |
| 614 | + static PyObject *delstr; | |
| 615 | + | |
| 616 | + _PyObject_GC_UNTRACK(inst); | |
| 617 | + if (inst->in_weakreflist != NULL) | |
| 618 | + PyObject_ClearWeakRefs((PyObject *) inst); | |
| 619 | + | |
| 620 | + /* Temporarily resurrect the object. */ | |
| 621 | + assert(inst->ob_type == &PyInstance_Type); | |
| 622 | + assert(inst->ob_refcnt == 0); | |
| 623 | + inst->ob_refcnt = 1; | |
| 624 | + | |
| 625 | + /* Save the current exception, if any. */ | |
| 626 | + PyErr_Fetch(&error_type, &error_value, &error_traceback); | |
| 627 | + /* Execute __del__ method, if any. */ | |
| 628 | + if (delstr == NULL) { | |
| 629 | + delstr = PyString_InternFromString("__del__"); | |
| 630 | + if (delstr == NULL) | |
| 631 | + PyErr_WriteUnraisable((PyObject*)inst); | |
| 632 | + } | |
| 633 | + if (delstr && (del = instance_getattr2(inst, delstr)) != NULL) { | |
| 634 | + PyObject *res = PyEval_CallObject(del, (PyObject *)NULL); | |
| 635 | + if (res == NULL) | |
| 636 | + PyErr_WriteUnraisable(del); | |
| 637 | + else | |
| 638 | + Py_DECREF(res); | |
| 639 | + Py_DECREF(del); | |
| 640 | + } | |
| 641 | + /* Restore the saved exception. */ | |
| 642 | + PyErr_Restore(error_type, error_value, error_traceback); | |
| 643 | + | |
| 644 | + /* Undo the temporary resurrection; can't use DECREF here, it would | |
| 645 | + * cause a recursive call. | |
| 646 | + */ | |
| 647 | + assert(inst->ob_refcnt > 0); | |
| 648 | + if (--inst->ob_refcnt == 0) { | |
| 649 | + Py_DECREF(inst->in_class); | |
| 650 | + Py_XDECREF(inst->in_dict); | |
| 651 | + PyObject_GC_Del(inst); | |
| 652 | + } | |
| 653 | + else { | |
| 654 | + Py_ssize_t refcnt = inst->ob_refcnt; | |
| 655 | + /* __del__ resurrected it! Make it look like the original | |
| 656 | + * Py_DECREF never happened. | |
| 657 | + */ | |
| 658 | + _Py_NewReference((PyObject *)inst); | |
| 659 | + inst->ob_refcnt = refcnt; | |
| 660 | + _PyObject_GC_TRACK(inst); | |
| 661 | + /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so | |
| 662 | + * we need to undo that. */ | |
| 663 | + _Py_DEC_REFTOTAL; | |
| 664 | + /* If Py_TRACE_REFS, _Py_NewReference re-added self to the | |
| 665 | + * object chain, so no more to do there. | |
| 666 | + * If COUNT_ALLOCS, the original decref bumped tp_frees, and | |
| 667 | + * _Py_NewReference bumped tp_allocs: both of those need to be | |
| 668 | + * undone. | |
| 669 | + */ | |
| 670 | +#ifdef COUNT_ALLOCS | |
| 671 | + --inst->ob_type->tp_frees; | |
| 672 | + --inst->ob_type->tp_allocs; | |
| 673 | +#endif | |
| 674 | + } | |
| 675 | +} | |
| 676 | + | |
| 677 | +static PyObject * | |
| 678 | +instance_getattr1(register PyInstanceObject *inst, PyObject *name) | |
| 679 | +{ | |
| 680 | + register PyObject *v; | |
| 681 | + register char *sname = PyString_AsString(name); | |
| 682 | + if (sname[0] == '_' && sname[1] == '_') { | |
| 683 | + if (strcmp(sname, "__dict__") == 0) { | |
| 684 | + if (PyEval_GetRestricted()) { | |
| 685 | + PyErr_SetString(PyExc_RuntimeError, | |
| 686 | + "instance.__dict__ not accessible in restricted mode"); | |
| 687 | + return NULL; | |
| 688 | + } | |
| 689 | + Py_INCREF(inst->in_dict); | |
| 690 | + return inst->in_dict; | |
| 691 | + } | |
| 692 | + if (strcmp(sname, "__class__") == 0) { | |
| 693 | + Py_INCREF(inst->in_class); | |
| 694 | + return (PyObject *)inst->in_class; | |
| 695 | + } | |
| 696 | + } | |
| 697 | + v = instance_getattr2(inst, name); | |
| 698 | + if (v == NULL && !PyErr_Occurred()) { | |
| 699 | + PyErr_Format(PyExc_AttributeError, | |
| 700 | + "%.50s instance has no attribute '%.400s'", | |
| 701 | + PyString_AS_STRING(inst->in_class->cl_name), sname); | |
| 702 | + } | |
| 703 | + return v; | |
| 704 | +} | |
| 705 | + | |
| 706 | +static PyObject * | |
| 707 | +instance_getattr2(register PyInstanceObject *inst, PyObject *name) | |
| 708 | +{ | |
| 709 | + register PyObject *v; | |
| 710 | + PyClassObject *klass; | |
| 711 | + descrgetfunc f; | |
| 712 | + | |
| 713 | + v = PyDict_GetItem(inst->in_dict, name); | |
| 714 | + if (v != NULL) { | |
| 715 | + Py_INCREF(v); | |
| 716 | + return v; | |
| 717 | + } | |
| 718 | + v = class_lookup(inst->in_class, name, &klass); | |
| 719 | + if (v != NULL) { | |
| 720 | + Py_INCREF(v); | |
| 721 | + f = TP_DESCR_GET(v->ob_type); | |
| 722 | + if (f != NULL) { | |
| 723 | + PyObject *w = f(v, (PyObject *)inst, | |
| 724 | + (PyObject *)(inst->in_class)); | |
| 725 | + Py_DECREF(v); | |
| 726 | + v = w; | |
| 727 | + } | |
| 728 | + } | |
| 729 | + return v; | |
| 730 | +} | |
| 731 | + | |
| 732 | +static PyObject * | |
| 733 | +instance_getattr(register PyInstanceObject *inst, PyObject *name) | |
| 734 | +{ | |
| 735 | + register PyObject *func, *res; | |
| 736 | + res = instance_getattr1(inst, name); | |
| 737 | + if (res == NULL && (func = inst->in_class->cl_getattr) != NULL) { | |
| 738 | + PyObject *args; | |
| 739 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 740 | + return NULL; | |
| 741 | + PyErr_Clear(); | |
| 742 | + args = PyTuple_Pack(2, inst, name); | |
| 743 | + if (args == NULL) | |
| 744 | + return NULL; | |
| 745 | + res = PyEval_CallObject(func, args); | |
| 746 | + Py_DECREF(args); | |
| 747 | + } | |
| 748 | + return res; | |
| 749 | +} | |
| 750 | + | |
| 751 | +/* See classobject.h comments: this only does dict lookups, and is always | |
| 752 | + * safe to call. | |
| 753 | + */ | |
| 754 | +PyObject * | |
| 755 | +_PyInstance_Lookup(PyObject *pinst, PyObject *name) | |
| 756 | +{ | |
| 757 | + PyObject *v; | |
| 758 | + PyClassObject *klass; | |
| 759 | + PyInstanceObject *inst; /* pinst cast to the right type */ | |
| 760 | + | |
| 761 | + assert(PyInstance_Check(pinst)); | |
| 762 | + inst = (PyInstanceObject *)pinst; | |
| 763 | + | |
| 764 | + assert(PyString_Check(name)); | |
| 765 | + | |
| 766 | + v = PyDict_GetItem(inst->in_dict, name); | |
| 767 | + if (v == NULL) | |
| 768 | + v = class_lookup(inst->in_class, name, &klass); | |
| 769 | + return v; | |
| 770 | +} | |
| 771 | + | |
| 772 | +static int | |
| 773 | +instance_setattr1(PyInstanceObject *inst, PyObject *name, PyObject *v) | |
| 774 | +{ | |
| 775 | + if (v == NULL) { | |
| 776 | + int rv = PyDict_DelItem(inst->in_dict, name); | |
| 777 | + if (rv < 0) | |
| 778 | + PyErr_Format(PyExc_AttributeError, | |
| 779 | + "%.50s instance has no attribute '%.400s'", | |
| 780 | + PyString_AS_STRING(inst->in_class->cl_name), | |
| 781 | + PyString_AS_STRING(name)); | |
| 782 | + return rv; | |
| 783 | + } | |
| 784 | + else | |
| 785 | + return PyDict_SetItem(inst->in_dict, name, v); | |
| 786 | +} | |
| 787 | + | |
| 788 | +static int | |
| 789 | +instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v) | |
| 790 | +{ | |
| 791 | + PyObject *func, *args, *res, *tmp; | |
| 792 | + char *sname = PyString_AsString(name); | |
| 793 | + if (sname[0] == '_' && sname[1] == '_') { | |
| 794 | + Py_ssize_t n = PyString_Size(name); | |
| 795 | + if (sname[n-1] == '_' && sname[n-2] == '_') { | |
| 796 | + if (strcmp(sname, "__dict__") == 0) { | |
| 797 | + if (PyEval_GetRestricted()) { | |
| 798 | + PyErr_SetString(PyExc_RuntimeError, | |
| 799 | + "__dict__ not accessible in restricted mode"); | |
| 800 | + return -1; | |
| 801 | + } | |
| 802 | + if (v == NULL || !PyDict_Check(v)) { | |
| 803 | + PyErr_SetString(PyExc_TypeError, | |
| 804 | + "__dict__ must be set to a dictionary"); | |
| 805 | + return -1; | |
| 806 | + } | |
| 807 | + tmp = inst->in_dict; | |
| 808 | + Py_INCREF(v); | |
| 809 | + inst->in_dict = v; | |
| 810 | + Py_DECREF(tmp); | |
| 811 | + return 0; | |
| 812 | + } | |
| 813 | + if (strcmp(sname, "__class__") == 0) { | |
| 814 | + if (PyEval_GetRestricted()) { | |
| 815 | + PyErr_SetString(PyExc_RuntimeError, | |
| 816 | + "__class__ not accessible in restricted mode"); | |
| 817 | + return -1; | |
| 818 | + } | |
| 819 | + if (v == NULL || !PyClass_Check(v)) { | |
| 820 | + PyErr_SetString(PyExc_TypeError, | |
| 821 | + "__class__ must be set to a class"); | |
| 822 | + return -1; | |
| 823 | + } | |
| 824 | + tmp = (PyObject *)(inst->in_class); | |
| 825 | + Py_INCREF(v); | |
| 826 | + inst->in_class = (PyClassObject *)v; | |
| 827 | + Py_DECREF(tmp); | |
| 828 | + return 0; | |
| 829 | + } | |
| 830 | + } | |
| 831 | + } | |
| 832 | + if (v == NULL) | |
| 833 | + func = inst->in_class->cl_delattr; | |
| 834 | + else | |
| 835 | + func = inst->in_class->cl_setattr; | |
| 836 | + if (func == NULL) | |
| 837 | + return instance_setattr1(inst, name, v); | |
| 838 | + if (v == NULL) | |
| 839 | + args = PyTuple_Pack(2, inst, name); | |
| 840 | + else | |
| 841 | + args = PyTuple_Pack(3, inst, name, v); | |
| 842 | + if (args == NULL) | |
| 843 | + return -1; | |
| 844 | + res = PyEval_CallObject(func, args); | |
| 845 | + Py_DECREF(args); | |
| 846 | + if (res == NULL) | |
| 847 | + return -1; | |
| 848 | + Py_DECREF(res); | |
| 849 | + return 0; | |
| 850 | +} | |
| 851 | + | |
| 852 | +static PyObject * | |
| 853 | +instance_repr(PyInstanceObject *inst) | |
| 854 | +{ | |
| 855 | + PyObject *func; | |
| 856 | + PyObject *res; | |
| 857 | + static PyObject *reprstr; | |
| 858 | + | |
| 859 | + if (reprstr == NULL) { | |
| 860 | + reprstr = PyString_InternFromString("__repr__"); | |
| 861 | + if (reprstr == NULL) | |
| 862 | + return NULL; | |
| 863 | + } | |
| 864 | + func = instance_getattr(inst, reprstr); | |
| 865 | + if (func == NULL) { | |
| 866 | + PyObject *classname, *mod; | |
| 867 | + char *cname; | |
| 868 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 869 | + return NULL; | |
| 870 | + PyErr_Clear(); | |
| 871 | + classname = inst->in_class->cl_name; | |
| 872 | + mod = PyDict_GetItemString(inst->in_class->cl_dict, | |
| 873 | + "__module__"); | |
| 874 | + if (classname != NULL && PyString_Check(classname)) | |
| 875 | + cname = PyString_AsString(classname); | |
| 876 | + else | |
| 877 | + cname = "?"; | |
| 878 | + if (mod == NULL || !PyString_Check(mod)) | |
| 879 | + return PyString_FromFormat("<?.%s instance at %p>", | |
| 880 | + cname, inst); | |
| 881 | + else | |
| 882 | + return PyString_FromFormat("<%s.%s instance at %p>", | |
| 883 | + PyString_AsString(mod), | |
| 884 | + cname, inst); | |
| 885 | + } | |
| 886 | + res = PyEval_CallObject(func, (PyObject *)NULL); | |
| 887 | + Py_DECREF(func); | |
| 888 | + return res; | |
| 889 | +} | |
| 890 | + | |
| 891 | +static PyObject * | |
| 892 | +instance_str(PyInstanceObject *inst) | |
| 893 | +{ | |
| 894 | + PyObject *func; | |
| 895 | + PyObject *res; | |
| 896 | + static PyObject *strstr; | |
| 897 | + | |
| 898 | + if (strstr == NULL) { | |
| 899 | + strstr = PyString_InternFromString("__str__"); | |
| 900 | + if (strstr == NULL) | |
| 901 | + return NULL; | |
| 902 | + } | |
| 903 | + func = instance_getattr(inst, strstr); | |
| 904 | + if (func == NULL) { | |
| 905 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 906 | + return NULL; | |
| 907 | + PyErr_Clear(); | |
| 908 | + return instance_repr(inst); | |
| 909 | + } | |
| 910 | + res = PyEval_CallObject(func, (PyObject *)NULL); | |
| 911 | + Py_DECREF(func); | |
| 912 | + return res; | |
| 913 | +} | |
| 914 | + | |
| 915 | +static long | |
| 916 | +instance_hash(PyInstanceObject *inst) | |
| 917 | +{ | |
| 918 | + PyObject *func; | |
| 919 | + PyObject *res; | |
| 920 | + long outcome; | |
| 921 | + static PyObject *hashstr, *eqstr, *cmpstr; | |
| 922 | + | |
| 923 | + if (hashstr == NULL) { | |
| 924 | + hashstr = PyString_InternFromString("__hash__"); | |
| 925 | + if (hashstr == NULL) | |
| 926 | + return -1; | |
| 927 | + } | |
| 928 | + func = instance_getattr(inst, hashstr); | |
| 929 | + if (func == NULL) { | |
| 930 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 931 | + return -1; | |
| 932 | + PyErr_Clear(); | |
| 933 | + /* If there is no __eq__ and no __cmp__ method, we hash on the | |
| 934 | + address. If an __eq__ or __cmp__ method exists, there must | |
| 935 | + be a __hash__. */ | |
| 936 | + if (eqstr == NULL) { | |
| 937 | + eqstr = PyString_InternFromString("__eq__"); | |
| 938 | + if (eqstr == NULL) | |
| 939 | + return -1; | |
| 940 | + } | |
| 941 | + func = instance_getattr(inst, eqstr); | |
| 942 | + if (func == NULL) { | |
| 943 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 944 | + return -1; | |
| 945 | + PyErr_Clear(); | |
| 946 | + if (cmpstr == NULL) { | |
| 947 | + cmpstr = PyString_InternFromString("__cmp__"); | |
| 948 | + if (cmpstr == NULL) | |
| 949 | + return -1; | |
| 950 | + } | |
| 951 | + func = instance_getattr(inst, cmpstr); | |
| 952 | + if (func == NULL) { | |
| 953 | + if (!PyErr_ExceptionMatches( | |
| 954 | + PyExc_AttributeError)) | |
| 955 | + return -1; | |
| 956 | + PyErr_Clear(); | |
| 957 | + return _Py_HashPointer(inst); | |
| 958 | + } | |
| 959 | + } | |
| 960 | + Py_XDECREF(func); | |
| 961 | + PyErr_SetString(PyExc_TypeError, "unhashable instance"); | |
| 962 | + return -1; | |
| 963 | + } | |
| 964 | + res = PyEval_CallObject(func, (PyObject *)NULL); | |
| 965 | + Py_DECREF(func); | |
| 966 | + if (res == NULL) | |
| 967 | + return -1; | |
| 968 | + if (PyInt_Check(res) || PyLong_Check(res)) | |
| 969 | + /* This already converts a -1 result to -2. */ | |
| 970 | + outcome = res->ob_type->tp_hash(res); | |
| 971 | + else { | |
| 972 | + PyErr_SetString(PyExc_TypeError, | |
| 973 | + "__hash__() should return an int"); | |
| 974 | + outcome = -1; | |
| 975 | + } | |
| 976 | + Py_DECREF(res); | |
| 977 | + return outcome; | |
| 978 | +} | |
| 979 | + | |
| 980 | +static int | |
| 981 | +instance_traverse(PyInstanceObject *o, visitproc visit, void *arg) | |
| 982 | +{ | |
| 983 | + Py_VISIT(o->in_class); | |
| 984 | + Py_VISIT(o->in_dict); | |
| 985 | + return 0; | |
| 986 | +} | |
| 987 | + | |
| 988 | +static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr; | |
| 989 | +static PyObject *iterstr, *nextstr; | |
| 990 | + | |
| 991 | +static Py_ssize_t | |
| 992 | +instance_length(PyInstanceObject *inst) | |
| 993 | +{ | |
| 994 | + PyObject *func; | |
| 995 | + PyObject *res; | |
| 996 | + Py_ssize_t outcome; | |
| 997 | + | |
| 998 | + if (lenstr == NULL) { | |
| 999 | + lenstr = PyString_InternFromString("__len__"); | |
| 1000 | + if (lenstr == NULL) | |
| 1001 | + return -1; | |
| 1002 | + } | |
| 1003 | + func = instance_getattr(inst, lenstr); | |
| 1004 | + if (func == NULL) | |
| 1005 | + return -1; | |
| 1006 | + res = PyEval_CallObject(func, (PyObject *)NULL); | |
| 1007 | + Py_DECREF(func); | |
| 1008 | + if (res == NULL) | |
| 1009 | + return -1; | |
| 1010 | + if (PyInt_Check(res)) { | |
| 1011 | + outcome = PyInt_AsSsize_t(res); | |
| 1012 | + if (outcome == -1 && PyErr_Occurred()) { | |
| 1013 | + Py_DECREF(res); | |
| 1014 | + return -1; | |
| 1015 | + } | |
| 1016 | +#if SIZEOF_SIZE_T < SIZEOF_INT | |
| 1017 | + /* Overflow check -- range of PyInt is more than C int */ | |
| 1018 | + if (outcome != (int)outcome) { | |
| 1019 | + PyErr_SetString(PyExc_OverflowError, | |
| 1020 | + "__len__() should return 0 <= outcome < 2**31"); | |
| 1021 | + outcome = -1; | |
| 1022 | + } | |
| 1023 | + else | |
| 1024 | +#endif | |
| 1025 | + if (outcome < 0) { | |
| 1026 | + PyErr_SetString(PyExc_ValueError, | |
| 1027 | + "__len__() should return >= 0"); | |
| 1028 | + outcome = -1; | |
| 1029 | + } | |
| 1030 | + } | |
| 1031 | + else { | |
| 1032 | + PyErr_SetString(PyExc_TypeError, | |
| 1033 | + "__len__() should return an int"); | |
| 1034 | + outcome = -1; | |
| 1035 | + } | |
| 1036 | + Py_DECREF(res); | |
| 1037 | + return outcome; | |
| 1038 | +} | |
| 1039 | + | |
| 1040 | +static PyObject * | |
| 1041 | +instance_subscript(PyInstanceObject *inst, PyObject *key) | |
| 1042 | +{ | |
| 1043 | + PyObject *func; | |
| 1044 | + PyObject *arg; | |
| 1045 | + PyObject *res; | |
| 1046 | + | |
| 1047 | + if (getitemstr == NULL) { | |
| 1048 | + getitemstr = PyString_InternFromString("__getitem__"); | |
| 1049 | + if (getitemstr == NULL) | |
| 1050 | + return NULL; | |
| 1051 | + } | |
| 1052 | + func = instance_getattr(inst, getitemstr); | |
| 1053 | + if (func == NULL) | |
| 1054 | + return NULL; | |
| 1055 | + arg = PyTuple_Pack(1, key); | |
| 1056 | + if (arg == NULL) { | |
| 1057 | + Py_DECREF(func); | |
| 1058 | + return NULL; | |
| 1059 | + } | |
| 1060 | + res = PyEval_CallObject(func, arg); | |
| 1061 | + Py_DECREF(func); | |
| 1062 | + Py_DECREF(arg); | |
| 1063 | + return res; | |
| 1064 | +} | |
| 1065 | + | |
| 1066 | +static int | |
| 1067 | +instance_ass_subscript(PyInstanceObject *inst, PyObject *key, PyObject *value) | |
| 1068 | +{ | |
| 1069 | + PyObject *func; | |
| 1070 | + PyObject *arg; | |
| 1071 | + PyObject *res; | |
| 1072 | + | |
| 1073 | + if (value == NULL) { | |
| 1074 | + if (delitemstr == NULL) { | |
| 1075 | + delitemstr = PyString_InternFromString("__delitem__"); | |
| 1076 | + if (delitemstr == NULL) | |
| 1077 | + return -1; | |
| 1078 | + } | |
| 1079 | + func = instance_getattr(inst, delitemstr); | |
| 1080 | + } | |
| 1081 | + else { | |
| 1082 | + if (setitemstr == NULL) { | |
| 1083 | + setitemstr = PyString_InternFromString("__setitem__"); | |
| 1084 | + if (setitemstr == NULL) | |
| 1085 | + return -1; | |
| 1086 | + } | |
| 1087 | + func = instance_getattr(inst, setitemstr); | |
| 1088 | + } | |
| 1089 | + if (func == NULL) | |
| 1090 | + return -1; | |
| 1091 | + if (value == NULL) | |
| 1092 | + arg = PyTuple_Pack(1, key); | |
| 1093 | + else | |
| 1094 | + arg = PyTuple_Pack(2, key, value); | |
| 1095 | + if (arg == NULL) { | |
| 1096 | + Py_DECREF(func); | |
| 1097 | + return -1; | |
| 1098 | + } | |
| 1099 | + res = PyEval_CallObject(func, arg); | |
| 1100 | + Py_DECREF(func); | |
| 1101 | + Py_DECREF(arg); | |
| 1102 | + if (res == NULL) | |
| 1103 | + return -1; | |
| 1104 | + Py_DECREF(res); | |
| 1105 | + return 0; | |
| 1106 | +} | |
| 1107 | + | |
| 1108 | +static PyMappingMethods instance_as_mapping = { | |
| 1109 | + (lenfunc)instance_length, /* mp_length */ | |
| 1110 | + (binaryfunc)instance_subscript, /* mp_subscript */ | |
| 1111 | + (objobjargproc)instance_ass_subscript, /* mp_ass_subscript */ | |
| 1112 | +}; | |
| 1113 | + | |
| 1114 | +static PyObject * | |
| 1115 | +instance_item(PyInstanceObject *inst, Py_ssize_t i) | |
| 1116 | +{ | |
| 1117 | + PyObject *func, *res; | |
| 1118 | + | |
| 1119 | + if (getitemstr == NULL) { | |
| 1120 | + getitemstr = PyString_InternFromString("__getitem__"); | |
| 1121 | + if (getitemstr == NULL) | |
| 1122 | + return NULL; | |
| 1123 | + } | |
| 1124 | + func = instance_getattr(inst, getitemstr); | |
| 1125 | + if (func == NULL) | |
| 1126 | + return NULL; | |
| 1127 | + res = PyObject_CallFunction(func, "n", i); | |
| 1128 | + Py_DECREF(func); | |
| 1129 | + return res; | |
| 1130 | +} | |
| 1131 | + | |
| 1132 | +static PyObject * | |
| 1133 | +instance_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j) | |
| 1134 | +{ | |
| 1135 | + PyObject *func, *arg, *res; | |
| 1136 | + static PyObject *getslicestr; | |
| 1137 | + | |
| 1138 | + if (getslicestr == NULL) { | |
| 1139 | + getslicestr = PyString_InternFromString("__getslice__"); | |
| 1140 | + if (getslicestr == NULL) | |
| 1141 | + return NULL; | |
| 1142 | + } | |
| 1143 | + func = instance_getattr(inst, getslicestr); | |
| 1144 | + | |
| 1145 | + if (func == NULL) { | |
| 1146 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1147 | + return NULL; | |
| 1148 | + PyErr_Clear(); | |
| 1149 | + | |
| 1150 | + if (getitemstr == NULL) { | |
| 1151 | + getitemstr = PyString_InternFromString("__getitem__"); | |
| 1152 | + if (getitemstr == NULL) | |
| 1153 | + return NULL; | |
| 1154 | + } | |
| 1155 | + func = instance_getattr(inst, getitemstr); | |
| 1156 | + if (func == NULL) | |
| 1157 | + return NULL; | |
| 1158 | + arg = Py_BuildValue("(N)", _PySlice_FromIndices(i, j)); | |
| 1159 | + } else | |
| 1160 | + arg = Py_BuildValue("(nn)", i, j); | |
| 1161 | + | |
| 1162 | + if (arg == NULL) { | |
| 1163 | + Py_DECREF(func); | |
| 1164 | + return NULL; | |
| 1165 | + } | |
| 1166 | + res = PyEval_CallObject(func, arg); | |
| 1167 | + Py_DECREF(func); | |
| 1168 | + Py_DECREF(arg); | |
| 1169 | + return res; | |
| 1170 | +} | |
| 1171 | + | |
| 1172 | +static int | |
| 1173 | +instance_ass_item(PyInstanceObject *inst, Py_ssize_t i, PyObject *item) | |
| 1174 | +{ | |
| 1175 | + PyObject *func, *arg, *res; | |
| 1176 | + | |
| 1177 | + if (item == NULL) { | |
| 1178 | + if (delitemstr == NULL) { | |
| 1179 | + delitemstr = PyString_InternFromString("__delitem__"); | |
| 1180 | + if (delitemstr == NULL) | |
| 1181 | + return -1; | |
| 1182 | + } | |
| 1183 | + func = instance_getattr(inst, delitemstr); | |
| 1184 | + } | |
| 1185 | + else { | |
| 1186 | + if (setitemstr == NULL) { | |
| 1187 | + setitemstr = PyString_InternFromString("__setitem__"); | |
| 1188 | + if (setitemstr == NULL) | |
| 1189 | + return -1; | |
| 1190 | + } | |
| 1191 | + func = instance_getattr(inst, setitemstr); | |
| 1192 | + } | |
| 1193 | + if (func == NULL) | |
| 1194 | + return -1; | |
| 1195 | + if (item == NULL) | |
| 1196 | + arg = PyInt_FromSsize_t(i); | |
| 1197 | + else | |
| 1198 | + arg = Py_BuildValue("(nO)", i, item); | |
| 1199 | + if (arg == NULL) { | |
| 1200 | + Py_DECREF(func); | |
| 1201 | + return -1; | |
| 1202 | + } | |
| 1203 | + res = PyEval_CallObject(func, arg); | |
| 1204 | + Py_DECREF(func); | |
| 1205 | + Py_DECREF(arg); | |
| 1206 | + if (res == NULL) | |
| 1207 | + return -1; | |
| 1208 | + Py_DECREF(res); | |
| 1209 | + return 0; | |
| 1210 | +} | |
| 1211 | + | |
| 1212 | +static int | |
| 1213 | +instance_ass_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j, PyObject *value) | |
| 1214 | +{ | |
| 1215 | + PyObject *func, *arg, *res; | |
| 1216 | + static PyObject *setslicestr, *delslicestr; | |
| 1217 | + | |
| 1218 | + if (value == NULL) { | |
| 1219 | + if (delslicestr == NULL) { | |
| 1220 | + delslicestr = | |
| 1221 | + PyString_InternFromString("__delslice__"); | |
| 1222 | + if (delslicestr == NULL) | |
| 1223 | + return -1; | |
| 1224 | + } | |
| 1225 | + func = instance_getattr(inst, delslicestr); | |
| 1226 | + if (func == NULL) { | |
| 1227 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1228 | + return -1; | |
| 1229 | + PyErr_Clear(); | |
| 1230 | + if (delitemstr == NULL) { | |
| 1231 | + delitemstr = | |
| 1232 | + PyString_InternFromString("__delitem__"); | |
| 1233 | + if (delitemstr == NULL) | |
| 1234 | + return -1; | |
| 1235 | + } | |
| 1236 | + func = instance_getattr(inst, delitemstr); | |
| 1237 | + if (func == NULL) | |
| 1238 | + return -1; | |
| 1239 | + | |
| 1240 | + arg = Py_BuildValue("(N)", | |
| 1241 | + _PySlice_FromIndices(i, j)); | |
| 1242 | + } else | |
| 1243 | + arg = Py_BuildValue("(nn)", i, j); | |
| 1244 | + } | |
| 1245 | + else { | |
| 1246 | + if (setslicestr == NULL) { | |
| 1247 | + setslicestr = | |
| 1248 | + PyString_InternFromString("__setslice__"); | |
| 1249 | + if (setslicestr == NULL) | |
| 1250 | + return -1; | |
| 1251 | + } | |
| 1252 | + func = instance_getattr(inst, setslicestr); | |
| 1253 | + if (func == NULL) { | |
| 1254 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1255 | + return -1; | |
| 1256 | + PyErr_Clear(); | |
| 1257 | + if (setitemstr == NULL) { | |
| 1258 | + setitemstr = | |
| 1259 | + PyString_InternFromString("__setitem__"); | |
| 1260 | + if (setitemstr == NULL) | |
| 1261 | + return -1; | |
| 1262 | + } | |
| 1263 | + func = instance_getattr(inst, setitemstr); | |
| 1264 | + if (func == NULL) | |
| 1265 | + return -1; | |
| 1266 | + | |
| 1267 | + arg = Py_BuildValue("(NO)", | |
| 1268 | + _PySlice_FromIndices(i, j), value); | |
| 1269 | + } else | |
| 1270 | + arg = Py_BuildValue("(nnO)", i, j, value); | |
| 1271 | + } | |
| 1272 | + if (arg == NULL) { | |
| 1273 | + Py_DECREF(func); | |
| 1274 | + return -1; | |
| 1275 | + } | |
| 1276 | + res = PyEval_CallObject(func, arg); | |
| 1277 | + Py_DECREF(func); | |
| 1278 | + Py_DECREF(arg); | |
| 1279 | + if (res == NULL) | |
| 1280 | + return -1; | |
| 1281 | + Py_DECREF(res); | |
| 1282 | + return 0; | |
| 1283 | +} | |
| 1284 | + | |
| 1285 | +static int | |
| 1286 | +instance_contains(PyInstanceObject *inst, PyObject *member) | |
| 1287 | +{ | |
| 1288 | + static PyObject *__contains__; | |
| 1289 | + PyObject *func; | |
| 1290 | + | |
| 1291 | + /* Try __contains__ first. | |
| 1292 | + * If that can't be done, try iterator-based searching. | |
| 1293 | + */ | |
| 1294 | + | |
| 1295 | + if(__contains__ == NULL) { | |
| 1296 | + __contains__ = PyString_InternFromString("__contains__"); | |
| 1297 | + if(__contains__ == NULL) | |
| 1298 | + return -1; | |
| 1299 | + } | |
| 1300 | + func = instance_getattr(inst, __contains__); | |
| 1301 | + if (func) { | |
| 1302 | + PyObject *res; | |
| 1303 | + int ret; | |
| 1304 | + PyObject *arg = PyTuple_Pack(1, member); | |
| 1305 | + if(arg == NULL) { | |
| 1306 | + Py_DECREF(func); | |
| 1307 | + return -1; | |
| 1308 | + } | |
| 1309 | + res = PyEval_CallObject(func, arg); | |
| 1310 | + Py_DECREF(func); | |
| 1311 | + Py_DECREF(arg); | |
| 1312 | + if(res == NULL) | |
| 1313 | + return -1; | |
| 1314 | + ret = PyObject_IsTrue(res); | |
| 1315 | + Py_DECREF(res); | |
| 1316 | + return ret; | |
| 1317 | + } | |
| 1318 | + | |
| 1319 | + /* Couldn't find __contains__. */ | |
| 1320 | + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { | |
| 1321 | + Py_ssize_t rc; | |
| 1322 | + /* Assume the failure was simply due to that there is no | |
| 1323 | + * __contains__ attribute, and try iterating instead. | |
| 1324 | + */ | |
| 1325 | + PyErr_Clear(); | |
| 1326 | + rc = _PySequence_IterSearch((PyObject *)inst, member, | |
| 1327 | + PY_ITERSEARCH_CONTAINS); | |
| 1328 | + if (rc >= 0) | |
| 1329 | + return rc > 0; | |
| 1330 | + } | |
| 1331 | + return -1; | |
| 1332 | +} | |
| 1333 | + | |
| 1334 | +static PySequenceMethods | |
| 1335 | +instance_as_sequence = { | |
| 1336 | + (lenfunc)instance_length, /* sq_length */ | |
| 1337 | + 0, /* sq_concat */ | |
| 1338 | + 0, /* sq_repeat */ | |
| 1339 | + (ssizeargfunc)instance_item, /* sq_item */ | |
| 1340 | + (ssizessizeargfunc)instance_slice, /* sq_slice */ | |
| 1341 | + (ssizeobjargproc)instance_ass_item, /* sq_ass_item */ | |
| 1342 | + (ssizessizeobjargproc)instance_ass_slice,/* sq_ass_slice */ | |
| 1343 | + (objobjproc)instance_contains, /* sq_contains */ | |
| 1344 | +}; | |
| 1345 | + | |
| 1346 | +static PyObject * | |
| 1347 | +generic_unary_op(PyInstanceObject *self, PyObject *methodname) | |
| 1348 | +{ | |
| 1349 | + PyObject *func, *res; | |
| 1350 | + | |
| 1351 | + if ((func = instance_getattr(self, methodname)) == NULL) | |
| 1352 | + return NULL; | |
| 1353 | + res = PyEval_CallObject(func, (PyObject *)NULL); | |
| 1354 | + Py_DECREF(func); | |
| 1355 | + return res; | |
| 1356 | +} | |
| 1357 | + | |
| 1358 | +static PyObject * | |
| 1359 | +generic_binary_op(PyObject *v, PyObject *w, char *opname) | |
| 1360 | +{ | |
| 1361 | + PyObject *result; | |
| 1362 | + PyObject *args; | |
| 1363 | + PyObject *func = PyObject_GetAttrString(v, opname); | |
| 1364 | + if (func == NULL) { | |
| 1365 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1366 | + return NULL; | |
| 1367 | + PyErr_Clear(); | |
| 1368 | + Py_INCREF(Py_NotImplemented); | |
| 1369 | + return Py_NotImplemented; | |
| 1370 | + } | |
| 1371 | + args = PyTuple_Pack(1, w); | |
| 1372 | + if (args == NULL) { | |
| 1373 | + Py_DECREF(func); | |
| 1374 | + return NULL; | |
| 1375 | + } | |
| 1376 | + result = PyEval_CallObject(func, args); | |
| 1377 | + Py_DECREF(args); | |
| 1378 | + Py_DECREF(func); | |
| 1379 | + return result; | |
| 1380 | +} | |
| 1381 | + | |
| 1382 | + | |
| 1383 | +static PyObject *coerce_obj; | |
| 1384 | + | |
| 1385 | +/* Try one half of a binary operator involving a class instance. */ | |
| 1386 | +static PyObject * | |
| 1387 | +half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc, | |
| 1388 | + int swapped) | |
| 1389 | +{ | |
| 1390 | + PyObject *args; | |
| 1391 | + PyObject *coercefunc; | |
| 1392 | + PyObject *coerced = NULL; | |
| 1393 | + PyObject *v1; | |
| 1394 | + PyObject *result; | |
| 1395 | + | |
| 1396 | + if (!PyInstance_Check(v)) { | |
| 1397 | + Py_INCREF(Py_NotImplemented); | |
| 1398 | + return Py_NotImplemented; | |
| 1399 | + } | |
| 1400 | + | |
| 1401 | + if (coerce_obj == NULL) { | |
| 1402 | + coerce_obj = PyString_InternFromString("__coerce__"); | |
| 1403 | + if (coerce_obj == NULL) | |
| 1404 | + return NULL; | |
| 1405 | + } | |
| 1406 | + coercefunc = PyObject_GetAttr(v, coerce_obj); | |
| 1407 | + if (coercefunc == NULL) { | |
| 1408 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1409 | + return NULL; | |
| 1410 | + PyErr_Clear(); | |
| 1411 | + return generic_binary_op(v, w, opname); | |
| 1412 | + } | |
| 1413 | + | |
| 1414 | + args = PyTuple_Pack(1, w); | |
| 1415 | + if (args == NULL) { | |
| 1416 | + Py_DECREF(coercefunc); | |
| 1417 | + return NULL; | |
| 1418 | + } | |
| 1419 | + coerced = PyEval_CallObject(coercefunc, args); | |
| 1420 | + Py_DECREF(args); | |
| 1421 | + Py_DECREF(coercefunc); | |
| 1422 | + if (coerced == NULL) { | |
| 1423 | + return NULL; | |
| 1424 | + } | |
| 1425 | + if (coerced == Py_None || coerced == Py_NotImplemented) { | |
| 1426 | + Py_DECREF(coerced); | |
| 1427 | + return generic_binary_op(v, w, opname); | |
| 1428 | + } | |
| 1429 | + if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) { | |
| 1430 | + Py_DECREF(coerced); | |
| 1431 | + PyErr_SetString(PyExc_TypeError, | |
| 1432 | + "coercion should return None or 2-tuple"); | |
| 1433 | + return NULL; | |
| 1434 | + } | |
| 1435 | + v1 = PyTuple_GetItem(coerced, 0); | |
| 1436 | + w = PyTuple_GetItem(coerced, 1); | |
| 1437 | + if (v1->ob_type == v->ob_type && PyInstance_Check(v)) { | |
| 1438 | + /* prevent recursion if __coerce__ returns self as the first | |
| 1439 | + * argument */ | |
| 1440 | + result = generic_binary_op(v1, w, opname); | |
| 1441 | + } else { | |
| 1442 | + if (Py_EnterRecursiveCall(" after coercion")) | |
| 1443 | + return NULL; | |
| 1444 | + if (swapped) | |
| 1445 | + result = (thisfunc)(w, v1); | |
| 1446 | + else | |
| 1447 | + result = (thisfunc)(v1, w); | |
| 1448 | + Py_LeaveRecursiveCall(); | |
| 1449 | + } | |
| 1450 | + Py_DECREF(coerced); | |
| 1451 | + return result; | |
| 1452 | +} | |
| 1453 | + | |
| 1454 | +/* Implement a binary operator involving at least one class instance. */ | |
| 1455 | +static PyObject * | |
| 1456 | +do_binop(PyObject *v, PyObject *w, char *opname, char *ropname, | |
| 1457 | + binaryfunc thisfunc) | |
| 1458 | +{ | |
| 1459 | + PyObject *result = half_binop(v, w, opname, thisfunc, 0); | |
| 1460 | + if (result == Py_NotImplemented) { | |
| 1461 | + Py_DECREF(result); | |
| 1462 | + result = half_binop(w, v, ropname, thisfunc, 1); | |
| 1463 | + } | |
| 1464 | + return result; | |
| 1465 | +} | |
| 1466 | + | |
| 1467 | +static PyObject * | |
| 1468 | +do_binop_inplace(PyObject *v, PyObject *w, char *iopname, char *opname, | |
| 1469 | + char *ropname, binaryfunc thisfunc) | |
| 1470 | +{ | |
| 1471 | + PyObject *result = half_binop(v, w, iopname, thisfunc, 0); | |
| 1472 | + if (result == Py_NotImplemented) { | |
| 1473 | + Py_DECREF(result); | |
| 1474 | + result = do_binop(v, w, opname, ropname, thisfunc); | |
| 1475 | + } | |
| 1476 | + return result; | |
| 1477 | +} | |
| 1478 | + | |
| 1479 | +static int | |
| 1480 | +instance_coerce(PyObject **pv, PyObject **pw) | |
| 1481 | +{ | |
| 1482 | + PyObject *v = *pv; | |
| 1483 | + PyObject *w = *pw; | |
| 1484 | + PyObject *coercefunc; | |
| 1485 | + PyObject *args; | |
| 1486 | + PyObject *coerced; | |
| 1487 | + | |
| 1488 | + if (coerce_obj == NULL) { | |
| 1489 | + coerce_obj = PyString_InternFromString("__coerce__"); | |
| 1490 | + if (coerce_obj == NULL) | |
| 1491 | + return -1; | |
| 1492 | + } | |
| 1493 | + coercefunc = PyObject_GetAttr(v, coerce_obj); | |
| 1494 | + if (coercefunc == NULL) { | |
| 1495 | + /* No __coerce__ method */ | |
| 1496 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1497 | + return -1; | |
| 1498 | + PyErr_Clear(); | |
| 1499 | + return 1; | |
| 1500 | + } | |
| 1501 | + /* Has __coerce__ method: call it */ | |
| 1502 | + args = PyTuple_Pack(1, w); | |
| 1503 | + if (args == NULL) { | |
| 1504 | + return -1; | |
| 1505 | + } | |
| 1506 | + coerced = PyEval_CallObject(coercefunc, args); | |
| 1507 | + Py_DECREF(args); | |
| 1508 | + Py_DECREF(coercefunc); | |
| 1509 | + if (coerced == NULL) { | |
| 1510 | + /* __coerce__ call raised an exception */ | |
| 1511 | + return -1; | |
| 1512 | + } | |
| 1513 | + if (coerced == Py_None || coerced == Py_NotImplemented) { | |
| 1514 | + /* __coerce__ says "I can't do it" */ | |
| 1515 | + Py_DECREF(coerced); | |
| 1516 | + return 1; | |
| 1517 | + } | |
| 1518 | + if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) { | |
| 1519 | + /* __coerce__ return value is malformed */ | |
| 1520 | + Py_DECREF(coerced); | |
| 1521 | + PyErr_SetString(PyExc_TypeError, | |
| 1522 | + "coercion should return None or 2-tuple"); | |
| 1523 | + return -1; | |
| 1524 | + } | |
| 1525 | + /* __coerce__ returned two new values */ | |
| 1526 | + *pv = PyTuple_GetItem(coerced, 0); | |
| 1527 | + *pw = PyTuple_GetItem(coerced, 1); | |
| 1528 | + Py_INCREF(*pv); | |
| 1529 | + Py_INCREF(*pw); | |
| 1530 | + Py_DECREF(coerced); | |
| 1531 | + return 0; | |
| 1532 | +} | |
| 1533 | + | |
| 1534 | +#define UNARY(funcname, methodname) \ | |
| 1535 | +static PyObject *funcname(PyInstanceObject *self) { \ | |
| 1536 | + static PyObject *o; \ | |
| 1537 | + if (o == NULL) { o = PyString_InternFromString(methodname); \ | |
| 1538 | + if (o == NULL) return NULL; } \ | |
| 1539 | + return generic_unary_op(self, o); \ | |
| 1540 | +} | |
| 1541 | + | |
| 1542 | +#define BINARY(f, m, n) \ | |
| 1543 | +static PyObject *f(PyObject *v, PyObject *w) { \ | |
| 1544 | + return do_binop(v, w, "__" m "__", "__r" m "__", n); \ | |
| 1545 | +} | |
| 1546 | + | |
| 1547 | +#define BINARY_INPLACE(f, m, n) \ | |
| 1548 | +static PyObject *f(PyObject *v, PyObject *w) { \ | |
| 1549 | + return do_binop_inplace(v, w, "__i" m "__", "__" m "__", \ | |
| 1550 | + "__r" m "__", n); \ | |
| 1551 | +} | |
| 1552 | + | |
| 1553 | +UNARY(instance_neg, "__neg__") | |
| 1554 | +UNARY(instance_pos, "__pos__") | |
| 1555 | +UNARY(instance_abs, "__abs__") | |
| 1556 | + | |
| 1557 | +BINARY(instance_or, "or", PyNumber_Or) | |
| 1558 | +BINARY(instance_and, "and", PyNumber_And) | |
| 1559 | +BINARY(instance_xor, "xor", PyNumber_Xor) | |
| 1560 | +BINARY(instance_lshift, "lshift", PyNumber_Lshift) | |
| 1561 | +BINARY(instance_rshift, "rshift", PyNumber_Rshift) | |
| 1562 | +BINARY(instance_add, "add", PyNumber_Add) | |
| 1563 | +BINARY(instance_sub, "sub", PyNumber_Subtract) | |
| 1564 | +BINARY(instance_mul, "mul", PyNumber_Multiply) | |
| 1565 | +BINARY(instance_div, "div", PyNumber_Divide) | |
| 1566 | +BINARY(instance_mod, "mod", PyNumber_Remainder) | |
| 1567 | +BINARY(instance_divmod, "divmod", PyNumber_Divmod) | |
| 1568 | +BINARY(instance_floordiv, "floordiv", PyNumber_FloorDivide) | |
| 1569 | +BINARY(instance_truediv, "truediv", PyNumber_TrueDivide) | |
| 1570 | + | |
| 1571 | +BINARY_INPLACE(instance_ior, "or", PyNumber_InPlaceOr) | |
| 1572 | +BINARY_INPLACE(instance_ixor, "xor", PyNumber_InPlaceXor) | |
| 1573 | +BINARY_INPLACE(instance_iand, "and", PyNumber_InPlaceAnd) | |
| 1574 | +BINARY_INPLACE(instance_ilshift, "lshift", PyNumber_InPlaceLshift) | |
| 1575 | +BINARY_INPLACE(instance_irshift, "rshift", PyNumber_InPlaceRshift) | |
| 1576 | +BINARY_INPLACE(instance_iadd, "add", PyNumber_InPlaceAdd) | |
| 1577 | +BINARY_INPLACE(instance_isub, "sub", PyNumber_InPlaceSubtract) | |
| 1578 | +BINARY_INPLACE(instance_imul, "mul", PyNumber_InPlaceMultiply) | |
| 1579 | +BINARY_INPLACE(instance_idiv, "div", PyNumber_InPlaceDivide) | |
| 1580 | +BINARY_INPLACE(instance_imod, "mod", PyNumber_InPlaceRemainder) | |
| 1581 | +BINARY_INPLACE(instance_ifloordiv, "floordiv", PyNumber_InPlaceFloorDivide) | |
| 1582 | +BINARY_INPLACE(instance_itruediv, "truediv", PyNumber_InPlaceTrueDivide) | |
| 1583 | + | |
| 1584 | +/* Try a 3-way comparison, returning an int; v is an instance. Return: | |
| 1585 | + -2 for an exception; | |
| 1586 | + -1 if v < w; | |
| 1587 | + 0 if v == w; | |
| 1588 | + 1 if v > w; | |
| 1589 | + 2 if this particular 3-way comparison is not implemented or undefined. | |
| 1590 | +*/ | |
| 1591 | +static int | |
| 1592 | +half_cmp(PyObject *v, PyObject *w) | |
| 1593 | +{ | |
| 1594 | + static PyObject *cmp_obj; | |
| 1595 | + PyObject *args; | |
| 1596 | + PyObject *cmp_func; | |
| 1597 | + PyObject *result; | |
| 1598 | + long l; | |
| 1599 | + | |
| 1600 | + assert(PyInstance_Check(v)); | |
| 1601 | + | |
| 1602 | + if (cmp_obj == NULL) { | |
| 1603 | + cmp_obj = PyString_InternFromString("__cmp__"); | |
| 1604 | + if (cmp_obj == NULL) | |
| 1605 | + return -2; | |
| 1606 | + } | |
| 1607 | + | |
| 1608 | + cmp_func = PyObject_GetAttr(v, cmp_obj); | |
| 1609 | + if (cmp_func == NULL) { | |
| 1610 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1611 | + return -2; | |
| 1612 | + PyErr_Clear(); | |
| 1613 | + return 2; | |
| 1614 | + } | |
| 1615 | + | |
| 1616 | + args = PyTuple_Pack(1, w); | |
| 1617 | + if (args == NULL) { | |
| 1618 | + Py_DECREF(cmp_func); | |
| 1619 | + return -2; | |
| 1620 | + } | |
| 1621 | + | |
| 1622 | + result = PyEval_CallObject(cmp_func, args); | |
| 1623 | + Py_DECREF(args); | |
| 1624 | + Py_DECREF(cmp_func); | |
| 1625 | + | |
| 1626 | + if (result == NULL) | |
| 1627 | + return -2; | |
| 1628 | + | |
| 1629 | + if (result == Py_NotImplemented) { | |
| 1630 | + Py_DECREF(result); | |
| 1631 | + return 2; | |
| 1632 | + } | |
| 1633 | + | |
| 1634 | + l = PyInt_AsLong(result); | |
| 1635 | + Py_DECREF(result); | |
| 1636 | + if (l == -1 && PyErr_Occurred()) { | |
| 1637 | + PyErr_SetString(PyExc_TypeError, | |
| 1638 | + "comparison did not return an int"); | |
| 1639 | + return -2; | |
| 1640 | + } | |
| 1641 | + | |
| 1642 | + return l < 0 ? -1 : l > 0 ? 1 : 0; | |
| 1643 | +} | |
| 1644 | + | |
| 1645 | +/* Try a 3-way comparison, returning an int; either v or w is an instance. | |
| 1646 | + We first try a coercion. Return: | |
| 1647 | + -2 for an exception; | |
| 1648 | + -1 if v < w; | |
| 1649 | + 0 if v == w; | |
| 1650 | + 1 if v > w; | |
| 1651 | + 2 if this particular 3-way comparison is not implemented or undefined. | |
| 1652 | + THIS IS ONLY CALLED FROM object.c! | |
| 1653 | +*/ | |
| 1654 | +static int | |
| 1655 | +instance_compare(PyObject *v, PyObject *w) | |
| 1656 | +{ | |
| 1657 | + int c; | |
| 1658 | + | |
| 1659 | + c = PyNumber_CoerceEx(&v, &w); | |
| 1660 | + if (c < 0) | |
| 1661 | + return -2; | |
| 1662 | + if (c == 0) { | |
| 1663 | + /* If neither is now an instance, use regular comparison */ | |
| 1664 | + if (!PyInstance_Check(v) && !PyInstance_Check(w)) { | |
| 1665 | + c = PyObject_Compare(v, w); | |
| 1666 | + Py_DECREF(v); | |
| 1667 | + Py_DECREF(w); | |
| 1668 | + if (PyErr_Occurred()) | |
| 1669 | + return -2; | |
| 1670 | + return c < 0 ? -1 : c > 0 ? 1 : 0; | |
| 1671 | + } | |
| 1672 | + } | |
| 1673 | + else { | |
| 1674 | + /* The coercion didn't do anything. | |
| 1675 | + Treat this the same as returning v and w unchanged. */ | |
| 1676 | + Py_INCREF(v); | |
| 1677 | + Py_INCREF(w); | |
| 1678 | + } | |
| 1679 | + | |
| 1680 | + if (PyInstance_Check(v)) { | |
| 1681 | + c = half_cmp(v, w); | |
| 1682 | + if (c <= 1) { | |
| 1683 | + Py_DECREF(v); | |
| 1684 | + Py_DECREF(w); | |
| 1685 | + return c; | |
| 1686 | + } | |
| 1687 | + } | |
| 1688 | + if (PyInstance_Check(w)) { | |
| 1689 | + c = half_cmp(w, v); | |
| 1690 | + if (c <= 1) { | |
| 1691 | + Py_DECREF(v); | |
| 1692 | + Py_DECREF(w); | |
| 1693 | + if (c >= -1) | |
| 1694 | + c = -c; | |
| 1695 | + return c; | |
| 1696 | + } | |
| 1697 | + } | |
| 1698 | + Py_DECREF(v); | |
| 1699 | + Py_DECREF(w); | |
| 1700 | + return 2; | |
| 1701 | +} | |
| 1702 | + | |
| 1703 | +static int | |
| 1704 | +instance_nonzero(PyInstanceObject *self) | |
| 1705 | +{ | |
| 1706 | + PyObject *func, *res; | |
| 1707 | + long outcome; | |
| 1708 | + static PyObject *nonzerostr; | |
| 1709 | + | |
| 1710 | + if (nonzerostr == NULL) { | |
| 1711 | + nonzerostr = PyString_InternFromString("__nonzero__"); | |
| 1712 | + if (nonzerostr == NULL) | |
| 1713 | + return -1; | |
| 1714 | + } | |
| 1715 | + if ((func = instance_getattr(self, nonzerostr)) == NULL) { | |
| 1716 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1717 | + return -1; | |
| 1718 | + PyErr_Clear(); | |
| 1719 | + if (lenstr == NULL) { | |
| 1720 | + lenstr = PyString_InternFromString("__len__"); | |
| 1721 | + if (lenstr == NULL) | |
| 1722 | + return -1; | |
| 1723 | + } | |
| 1724 | + if ((func = instance_getattr(self, lenstr)) == NULL) { | |
| 1725 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1726 | + return -1; | |
| 1727 | + PyErr_Clear(); | |
| 1728 | + /* Fall back to the default behavior: | |
| 1729 | + all instances are nonzero */ | |
| 1730 | + return 1; | |
| 1731 | + } | |
| 1732 | + } | |
| 1733 | + res = PyEval_CallObject(func, (PyObject *)NULL); | |
| 1734 | + Py_DECREF(func); | |
| 1735 | + if (res == NULL) | |
| 1736 | + return -1; | |
| 1737 | + if (!PyInt_Check(res)) { | |
| 1738 | + Py_DECREF(res); | |
| 1739 | + PyErr_SetString(PyExc_TypeError, | |
| 1740 | + "__nonzero__ should return an int"); | |
| 1741 | + return -1; | |
| 1742 | + } | |
| 1743 | + outcome = PyInt_AsLong(res); | |
| 1744 | + Py_DECREF(res); | |
| 1745 | + if (outcome < 0) { | |
| 1746 | + PyErr_SetString(PyExc_ValueError, | |
| 1747 | + "__nonzero__ should return >= 0"); | |
| 1748 | + return -1; | |
| 1749 | + } | |
| 1750 | + return outcome > 0; | |
| 1751 | +} | |
| 1752 | + | |
| 1753 | +static PyObject * | |
| 1754 | +instance_index(PyInstanceObject *self) | |
| 1755 | +{ | |
| 1756 | + PyObject *func, *res; | |
| 1757 | + static PyObject *indexstr = NULL; | |
| 1758 | + | |
| 1759 | + if (indexstr == NULL) { | |
| 1760 | + indexstr = PyString_InternFromString("__index__"); | |
| 1761 | + if (indexstr == NULL) | |
| 1762 | + return NULL; | |
| 1763 | + } | |
| 1764 | + if ((func = instance_getattr(self, indexstr)) == NULL) { | |
| 1765 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1766 | + return NULL; | |
| 1767 | + PyErr_Clear(); | |
| 1768 | + PyErr_SetString(PyExc_TypeError, | |
| 1769 | + "object cannot be interpreted as an index"); | |
| 1770 | + return NULL; | |
| 1771 | + } | |
| 1772 | + res = PyEval_CallObject(func, (PyObject *)NULL); | |
| 1773 | + Py_DECREF(func); | |
| 1774 | + return res; | |
| 1775 | +} | |
| 1776 | + | |
| 1777 | + | |
| 1778 | +UNARY(instance_invert, "__invert__") | |
| 1779 | +UNARY(instance_int, "__int__") | |
| 1780 | +UNARY(instance_long, "__long__") | |
| 1781 | +UNARY(instance_float, "__float__") | |
| 1782 | +UNARY(instance_oct, "__oct__") | |
| 1783 | +UNARY(instance_hex, "__hex__") | |
| 1784 | + | |
| 1785 | +static PyObject * | |
| 1786 | +bin_power(PyObject *v, PyObject *w) | |
| 1787 | +{ | |
| 1788 | + return PyNumber_Power(v, w, Py_None); | |
| 1789 | +} | |
| 1790 | + | |
| 1791 | +/* This version is for ternary calls only (z != None) */ | |
| 1792 | +static PyObject * | |
| 1793 | +instance_pow(PyObject *v, PyObject *w, PyObject *z) | |
| 1794 | +{ | |
| 1795 | + if (z == Py_None) { | |
| 1796 | + return do_binop(v, w, "__pow__", "__rpow__", bin_power); | |
| 1797 | + } | |
| 1798 | + else { | |
| 1799 | + PyObject *func; | |
| 1800 | + PyObject *args; | |
| 1801 | + PyObject *result; | |
| 1802 | + | |
| 1803 | + /* XXX Doesn't do coercions... */ | |
| 1804 | + func = PyObject_GetAttrString(v, "__pow__"); | |
| 1805 | + if (func == NULL) | |
| 1806 | + return NULL; | |
| 1807 | + args = PyTuple_Pack(2, w, z); | |
| 1808 | + if (args == NULL) { | |
| 1809 | + Py_DECREF(func); | |
| 1810 | + return NULL; | |
| 1811 | + } | |
| 1812 | + result = PyEval_CallObject(func, args); | |
| 1813 | + Py_DECREF(func); | |
| 1814 | + Py_DECREF(args); | |
| 1815 | + return result; | |
| 1816 | + } | |
| 1817 | +} | |
| 1818 | + | |
| 1819 | +static PyObject * | |
| 1820 | +bin_inplace_power(PyObject *v, PyObject *w) | |
| 1821 | +{ | |
| 1822 | + return PyNumber_InPlacePower(v, w, Py_None); | |
| 1823 | +} | |
| 1824 | + | |
| 1825 | + | |
| 1826 | +static PyObject * | |
| 1827 | +instance_ipow(PyObject *v, PyObject *w, PyObject *z) | |
| 1828 | +{ | |
| 1829 | + if (z == Py_None) { | |
| 1830 | + return do_binop_inplace(v, w, "__ipow__", "__pow__", | |
| 1831 | + "__rpow__", bin_inplace_power); | |
| 1832 | + } | |
| 1833 | + else { | |
| 1834 | + /* XXX Doesn't do coercions... */ | |
| 1835 | + PyObject *func; | |
| 1836 | + PyObject *args; | |
| 1837 | + PyObject *result; | |
| 1838 | + | |
| 1839 | + func = PyObject_GetAttrString(v, "__ipow__"); | |
| 1840 | + if (func == NULL) { | |
| 1841 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1842 | + return NULL; | |
| 1843 | + PyErr_Clear(); | |
| 1844 | + return instance_pow(v, w, z); | |
| 1845 | + } | |
| 1846 | + args = PyTuple_Pack(2, w, z); | |
| 1847 | + if (args == NULL) { | |
| 1848 | + Py_DECREF(func); | |
| 1849 | + return NULL; | |
| 1850 | + } | |
| 1851 | + result = PyEval_CallObject(func, args); | |
| 1852 | + Py_DECREF(func); | |
| 1853 | + Py_DECREF(args); | |
| 1854 | + return result; | |
| 1855 | + } | |
| 1856 | +} | |
| 1857 | + | |
| 1858 | + | |
| 1859 | +/* Map rich comparison operators to their __xx__ namesakes */ | |
| 1860 | +#define NAME_OPS 6 | |
| 1861 | +static PyObject **name_op = NULL; | |
| 1862 | + | |
| 1863 | +static int | |
| 1864 | +init_name_op(void) | |
| 1865 | +{ | |
| 1866 | + int i; | |
| 1867 | + char *_name_op[] = { | |
| 1868 | + "__lt__", | |
| 1869 | + "__le__", | |
| 1870 | + "__eq__", | |
| 1871 | + "__ne__", | |
| 1872 | + "__gt__", | |
| 1873 | + "__ge__", | |
| 1874 | + }; | |
| 1875 | + | |
| 1876 | + name_op = (PyObject **)malloc(sizeof(PyObject *) * NAME_OPS); | |
| 1877 | + if (name_op == NULL) | |
| 1878 | + return -1; | |
| 1879 | + for (i = 0; i < NAME_OPS; ++i) { | |
| 1880 | + name_op[i] = PyString_InternFromString(_name_op[i]); | |
| 1881 | + if (name_op[i] == NULL) | |
| 1882 | + return -1; | |
| 1883 | + } | |
| 1884 | + return 0; | |
| 1885 | +} | |
| 1886 | + | |
| 1887 | +static PyObject * | |
| 1888 | +half_richcompare(PyObject *v, PyObject *w, int op) | |
| 1889 | +{ | |
| 1890 | + PyObject *method; | |
| 1891 | + PyObject *args; | |
| 1892 | + PyObject *res; | |
| 1893 | + | |
| 1894 | + assert(PyInstance_Check(v)); | |
| 1895 | + | |
| 1896 | + if (name_op == NULL) { | |
| 1897 | + if (init_name_op() < 0) | |
| 1898 | + return NULL; | |
| 1899 | + } | |
| 1900 | + /* If the instance doesn't define an __getattr__ method, use | |
| 1901 | + instance_getattr2 directly because it will not set an | |
| 1902 | + exception on failure. */ | |
| 1903 | + if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL) | |
| 1904 | + method = instance_getattr2((PyInstanceObject *)v, | |
| 1905 | + name_op[op]); | |
| 1906 | + else | |
| 1907 | + method = PyObject_GetAttr(v, name_op[op]); | |
| 1908 | + if (method == NULL) { | |
| 1909 | + if (PyErr_Occurred()) { | |
| 1910 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1911 | + return NULL; | |
| 1912 | + PyErr_Clear(); | |
| 1913 | + } | |
| 1914 | + res = Py_NotImplemented; | |
| 1915 | + Py_INCREF(res); | |
| 1916 | + return res; | |
| 1917 | + } | |
| 1918 | + | |
| 1919 | + args = PyTuple_Pack(1, w); | |
| 1920 | + if (args == NULL) { | |
| 1921 | + Py_DECREF(method); | |
| 1922 | + return NULL; | |
| 1923 | + } | |
| 1924 | + | |
| 1925 | + res = PyEval_CallObject(method, args); | |
| 1926 | + Py_DECREF(args); | |
| 1927 | + Py_DECREF(method); | |
| 1928 | + | |
| 1929 | + return res; | |
| 1930 | +} | |
| 1931 | + | |
| 1932 | +static PyObject * | |
| 1933 | +instance_richcompare(PyObject *v, PyObject *w, int op) | |
| 1934 | +{ | |
| 1935 | + PyObject *res; | |
| 1936 | + | |
| 1937 | + if (PyInstance_Check(v)) { | |
| 1938 | + res = half_richcompare(v, w, op); | |
| 1939 | + if (res != Py_NotImplemented) | |
| 1940 | + return res; | |
| 1941 | + Py_DECREF(res); | |
| 1942 | + } | |
| 1943 | + | |
| 1944 | + if (PyInstance_Check(w)) { | |
| 1945 | + res = half_richcompare(w, v, _Py_SwappedOp[op]); | |
| 1946 | + if (res != Py_NotImplemented) | |
| 1947 | + return res; | |
| 1948 | + Py_DECREF(res); | |
| 1949 | + } | |
| 1950 | + | |
| 1951 | + Py_INCREF(Py_NotImplemented); | |
| 1952 | + return Py_NotImplemented; | |
| 1953 | +} | |
| 1954 | + | |
| 1955 | + | |
| 1956 | +/* Get the iterator */ | |
| 1957 | +static PyObject * | |
| 1958 | +instance_getiter(PyInstanceObject *self) | |
| 1959 | +{ | |
| 1960 | + PyObject *func; | |
| 1961 | + | |
| 1962 | + if (iterstr == NULL) { | |
| 1963 | + iterstr = PyString_InternFromString("__iter__"); | |
| 1964 | + if (iterstr == NULL) | |
| 1965 | + return NULL; | |
| 1966 | + } | |
| 1967 | + if (getitemstr == NULL) { | |
| 1968 | + getitemstr = PyString_InternFromString("__getitem__"); | |
| 1969 | + if (getitemstr == NULL) | |
| 1970 | + return NULL; | |
| 1971 | + } | |
| 1972 | + | |
| 1973 | + if ((func = instance_getattr(self, iterstr)) != NULL) { | |
| 1974 | + PyObject *res = PyEval_CallObject(func, (PyObject *)NULL); | |
| 1975 | + Py_DECREF(func); | |
| 1976 | + if (res != NULL && !PyIter_Check(res)) { | |
| 1977 | + PyErr_Format(PyExc_TypeError, | |
| 1978 | + "__iter__ returned non-iterator " | |
| 1979 | + "of type '%.100s'", | |
| 1980 | + res->ob_type->tp_name); | |
| 1981 | + Py_DECREF(res); | |
| 1982 | + res = NULL; | |
| 1983 | + } | |
| 1984 | + return res; | |
| 1985 | + } | |
| 1986 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1987 | + return NULL; | |
| 1988 | + PyErr_Clear(); | |
| 1989 | + if ((func = instance_getattr(self, getitemstr)) == NULL) { | |
| 1990 | + PyErr_SetString(PyExc_TypeError, | |
| 1991 | + "iteration over non-sequence"); | |
| 1992 | + return NULL; | |
| 1993 | + } | |
| 1994 | + Py_DECREF(func); | |
| 1995 | + return PySeqIter_New((PyObject *)self); | |
| 1996 | +} | |
| 1997 | + | |
| 1998 | + | |
| 1999 | +/* Call the iterator's next */ | |
| 2000 | +static PyObject * | |
| 2001 | +instance_iternext(PyInstanceObject *self) | |
| 2002 | +{ | |
| 2003 | + PyObject *func; | |
| 2004 | + | |
| 2005 | + if (nextstr == NULL) { | |
| 2006 | + nextstr = PyString_InternFromString("next"); | |
| 2007 | + if (nextstr == NULL) | |
| 2008 | + return NULL; | |
| 2009 | + } | |
| 2010 | + | |
| 2011 | + if ((func = instance_getattr(self, nextstr)) != NULL) { | |
| 2012 | + PyObject *res = PyEval_CallObject(func, (PyObject *)NULL); | |
| 2013 | + Py_DECREF(func); | |
| 2014 | + if (res != NULL) { | |
| 2015 | + return res; | |
| 2016 | + } | |
| 2017 | + if (PyErr_ExceptionMatches(PyExc_StopIteration)) { | |
| 2018 | + PyErr_Clear(); | |
| 2019 | + return NULL; | |
| 2020 | + } | |
| 2021 | + return NULL; | |
| 2022 | + } | |
| 2023 | + PyErr_SetString(PyExc_TypeError, "instance has no next() method"); | |
| 2024 | + return NULL; | |
| 2025 | +} | |
| 2026 | + | |
| 2027 | +static PyObject * | |
| 2028 | +instance_call(PyObject *func, PyObject *arg, PyObject *kw) | |
| 2029 | +{ | |
| 2030 | + PyObject *res, *call = PyObject_GetAttrString(func, "__call__"); | |
| 2031 | + if (call == NULL) { | |
| 2032 | + PyInstanceObject *inst = (PyInstanceObject*) func; | |
| 2033 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 2034 | + return NULL; | |
| 2035 | + PyErr_Clear(); | |
| 2036 | + PyErr_Format(PyExc_AttributeError, | |
| 2037 | + "%.200s instance has no __call__ method", | |
| 2038 | + PyString_AsString(inst->in_class->cl_name)); | |
| 2039 | + return NULL; | |
| 2040 | + } | |
| 2041 | + /* We must check and increment the recursion depth here. Scenario: | |
| 2042 | + class A: | |
| 2043 | + pass | |
| 2044 | + A.__call__ = A() # that's right | |
| 2045 | + a = A() # ok | |
| 2046 | + a() # infinite recursion | |
| 2047 | + This bounces between instance_call() and PyObject_Call() without | |
| 2048 | + ever hitting eval_frame() (which has the main recursion check). */ | |
| 2049 | + if (Py_EnterRecursiveCall(" in __call__")) { | |
| 2050 | + res = NULL; | |
| 2051 | + } | |
| 2052 | + else { | |
| 2053 | + res = PyObject_Call(call, arg, kw); | |
| 2054 | + Py_LeaveRecursiveCall(); | |
| 2055 | + } | |
| 2056 | + Py_DECREF(call); | |
| 2057 | + return res; | |
| 2058 | +} | |
| 2059 | + | |
| 2060 | + | |
| 2061 | +static PyNumberMethods instance_as_number = { | |
| 2062 | + instance_add, /* nb_add */ | |
| 2063 | + instance_sub, /* nb_subtract */ | |
| 2064 | + instance_mul, /* nb_multiply */ | |
| 2065 | + instance_div, /* nb_divide */ | |
| 2066 | + instance_mod, /* nb_remainder */ | |
| 2067 | + instance_divmod, /* nb_divmod */ | |
| 2068 | + instance_pow, /* nb_power */ | |
| 2069 | + (unaryfunc)instance_neg, /* nb_negative */ | |
| 2070 | + (unaryfunc)instance_pos, /* nb_positive */ | |
| 2071 | + (unaryfunc)instance_abs, /* nb_absolute */ | |
| 2072 | + (inquiry)instance_nonzero, /* nb_nonzero */ | |
| 2073 | + (unaryfunc)instance_invert, /* nb_invert */ | |
| 2074 | + instance_lshift, /* nb_lshift */ | |
| 2075 | + instance_rshift, /* nb_rshift */ | |
| 2076 | + instance_and, /* nb_and */ | |
| 2077 | + instance_xor, /* nb_xor */ | |
| 2078 | + instance_or, /* nb_or */ | |
| 2079 | + instance_coerce, /* nb_coerce */ | |
| 2080 | + (unaryfunc)instance_int, /* nb_int */ | |
| 2081 | + (unaryfunc)instance_long, /* nb_long */ | |
| 2082 | + (unaryfunc)instance_float, /* nb_float */ | |
| 2083 | + (unaryfunc)instance_oct, /* nb_oct */ | |
| 2084 | + (unaryfunc)instance_hex, /* nb_hex */ | |
| 2085 | + instance_iadd, /* nb_inplace_add */ | |
| 2086 | + instance_isub, /* nb_inplace_subtract */ | |
| 2087 | + instance_imul, /* nb_inplace_multiply */ | |
| 2088 | + instance_idiv, /* nb_inplace_divide */ | |
| 2089 | + instance_imod, /* nb_inplace_remainder */ | |
| 2090 | + instance_ipow, /* nb_inplace_power */ | |
| 2091 | + instance_ilshift, /* nb_inplace_lshift */ | |
| 2092 | + instance_irshift, /* nb_inplace_rshift */ | |
| 2093 | + instance_iand, /* nb_inplace_and */ | |
| 2094 | + instance_ixor, /* nb_inplace_xor */ | |
| 2095 | + instance_ior, /* nb_inplace_or */ | |
| 2096 | + instance_floordiv, /* nb_floor_divide */ | |
| 2097 | + instance_truediv, /* nb_true_divide */ | |
| 2098 | + instance_ifloordiv, /* nb_inplace_floor_divide */ | |
| 2099 | + instance_itruediv, /* nb_inplace_true_divide */ | |
| 2100 | + (unaryfunc)instance_index, /* nb_index */ | |
| 2101 | +}; | |
| 2102 | + | |
| 2103 | +PyTypeObject PyInstance_Type = { | |
| 2104 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 2105 | + 0, | |
| 2106 | + "instance", | |
| 2107 | + sizeof(PyInstanceObject), | |
| 2108 | + 0, | |
| 2109 | + (destructor)instance_dealloc, /* tp_dealloc */ | |
| 2110 | + 0, /* tp_print */ | |
| 2111 | + 0, /* tp_getattr */ | |
| 2112 | + 0, /* tp_setattr */ | |
| 2113 | + instance_compare, /* tp_compare */ | |
| 2114 | + (reprfunc)instance_repr, /* tp_repr */ | |
| 2115 | + &instance_as_number, /* tp_as_number */ | |
| 2116 | + &instance_as_sequence, /* tp_as_sequence */ | |
| 2117 | + &instance_as_mapping, /* tp_as_mapping */ | |
| 2118 | + (hashfunc)instance_hash, /* tp_hash */ | |
| 2119 | + instance_call, /* tp_call */ | |
| 2120 | + (reprfunc)instance_str, /* tp_str */ | |
| 2121 | + (getattrofunc)instance_getattr, /* tp_getattro */ | |
| 2122 | + (setattrofunc)instance_setattr, /* tp_setattro */ | |
| 2123 | + 0, /* tp_as_buffer */ | |
| 2124 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES,/*tp_flags*/ | |
| 2125 | + instance_doc, /* tp_doc */ | |
| 2126 | + (traverseproc)instance_traverse, /* tp_traverse */ | |
| 2127 | + 0, /* tp_clear */ | |
| 2128 | + instance_richcompare, /* tp_richcompare */ | |
| 2129 | + offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */ | |
| 2130 | + (getiterfunc)instance_getiter, /* tp_iter */ | |
| 2131 | + (iternextfunc)instance_iternext, /* tp_iternext */ | |
| 2132 | + 0, /* tp_methods */ | |
| 2133 | + 0, /* tp_members */ | |
| 2134 | + 0, /* tp_getset */ | |
| 2135 | + 0, /* tp_base */ | |
| 2136 | + 0, /* tp_dict */ | |
| 2137 | + 0, /* tp_descr_get */ | |
| 2138 | + 0, /* tp_descr_set */ | |
| 2139 | + 0, /* tp_dictoffset */ | |
| 2140 | + 0, /* tp_init */ | |
| 2141 | + 0, /* tp_alloc */ | |
| 2142 | + instance_new, /* tp_new */ | |
| 2143 | +}; | |
| 2144 | + | |
| 2145 | + | |
| 2146 | +/* Instance method objects are used for two purposes: | |
| 2147 | + (a) as bound instance methods (returned by instancename.methodname) | |
| 2148 | + (b) as unbound methods (returned by ClassName.methodname) | |
| 2149 | + In case (b), im_self is NULL | |
| 2150 | +*/ | |
| 2151 | + | |
| 2152 | +static PyMethodObject *free_list; | |
| 2153 | + | |
| 2154 | +PyObject * | |
| 2155 | +PyMethod_New(PyObject *func, PyObject *self, PyObject *klass) | |
| 2156 | +{ | |
| 2157 | + register PyMethodObject *im; | |
| 2158 | + if (!PyCallable_Check(func)) { | |
| 2159 | + PyErr_BadInternalCall(); | |
| 2160 | + return NULL; | |
| 2161 | + } | |
| 2162 | + im = free_list; | |
| 2163 | + if (im != NULL) { | |
| 2164 | + free_list = (PyMethodObject *)(im->im_self); | |
| 2165 | + PyObject_INIT(im, &PyMethod_Type); | |
| 2166 | + } | |
| 2167 | + else { | |
| 2168 | + im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); | |
| 2169 | + if (im == NULL) | |
| 2170 | + return NULL; | |
| 2171 | + } | |
| 2172 | + im->im_weakreflist = NULL; | |
| 2173 | + Py_INCREF(func); | |
| 2174 | + im->im_func = func; | |
| 2175 | + Py_XINCREF(self); | |
| 2176 | + im->im_self = self; | |
| 2177 | + Py_XINCREF(klass); | |
| 2178 | + im->im_class = klass; | |
| 2179 | + _PyObject_GC_TRACK(im); | |
| 2180 | + return (PyObject *)im; | |
| 2181 | +} | |
| 2182 | + | |
| 2183 | +/* Descriptors for PyMethod attributes */ | |
| 2184 | + | |
| 2185 | +/* im_class, im_func and im_self are stored in the PyMethod object */ | |
| 2186 | + | |
| 2187 | +#define OFF(x) offsetof(PyMethodObject, x) | |
| 2188 | + | |
| 2189 | +static PyMemberDef instancemethod_memberlist[] = { | |
| 2190 | + {"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED, | |
| 2191 | + "the class associated with a method"}, | |
| 2192 | + {"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED, | |
| 2193 | + "the function (or other callable) implementing a method"}, | |
| 2194 | + {"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED, | |
| 2195 | + "the instance to which a method is bound; None for unbound methods"}, | |
| 2196 | + {NULL} /* Sentinel */ | |
| 2197 | +}; | |
| 2198 | + | |
| 2199 | +/* Christian Tismer argued convincingly that method attributes should | |
| 2200 | + (nearly) always override function attributes. | |
| 2201 | + The one exception is __doc__; there's a default __doc__ which | |
| 2202 | + should only be used for the class, not for instances */ | |
| 2203 | + | |
| 2204 | +static PyObject * | |
| 2205 | +instancemethod_get_doc(PyMethodObject *im, void *context) | |
| 2206 | +{ | |
| 2207 | + static PyObject *docstr; | |
| 2208 | + if (docstr == NULL) { | |
| 2209 | + docstr= PyString_InternFromString("__doc__"); | |
| 2210 | + if (docstr == NULL) | |
| 2211 | + return NULL; | |
| 2212 | + } | |
| 2213 | + return PyObject_GetAttr(im->im_func, docstr); | |
| 2214 | +} | |
| 2215 | + | |
| 2216 | +static PyGetSetDef instancemethod_getset[] = { | |
| 2217 | + {"__doc__", (getter)instancemethod_get_doc, NULL, NULL}, | |
| 2218 | + {0} | |
| 2219 | +}; | |
| 2220 | + | |
| 2221 | +static PyObject * | |
| 2222 | +instancemethod_getattro(PyObject *obj, PyObject *name) | |
| 2223 | +{ | |
| 2224 | + PyMethodObject *im = (PyMethodObject *)obj; | |
| 2225 | + PyTypeObject *tp = obj->ob_type; | |
| 2226 | + PyObject *descr = NULL; | |
| 2227 | + | |
| 2228 | + if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) { | |
| 2229 | + if (tp->tp_dict == NULL) { | |
| 2230 | + if (PyType_Ready(tp) < 0) | |
| 2231 | + return NULL; | |
| 2232 | + } | |
| 2233 | + descr = _PyType_Lookup(tp, name); | |
| 2234 | + } | |
| 2235 | + | |
| 2236 | + if (descr != NULL) { | |
| 2237 | + descrgetfunc f = TP_DESCR_GET(descr->ob_type); | |
| 2238 | + if (f != NULL) | |
| 2239 | + return f(descr, obj, (PyObject *)obj->ob_type); | |
| 2240 | + else { | |
| 2241 | + Py_INCREF(descr); | |
| 2242 | + return descr; | |
| 2243 | + } | |
| 2244 | + } | |
| 2245 | + | |
| 2246 | + return PyObject_GetAttr(im->im_func, name); | |
| 2247 | +} | |
| 2248 | + | |
| 2249 | +PyDoc_STRVAR(instancemethod_doc, | |
| 2250 | +"instancemethod(function, instance, class)\n\ | |
| 2251 | +\n\ | |
| 2252 | +Create an instance method object."); | |
| 2253 | + | |
| 2254 | +static PyObject * | |
| 2255 | +instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw) | |
| 2256 | +{ | |
| 2257 | + PyObject *func; | |
| 2258 | + PyObject *self; | |
| 2259 | + PyObject *classObj = NULL; | |
| 2260 | + | |
| 2261 | + if (!_PyArg_NoKeywords("instancemethod", kw)) | |
| 2262 | + return NULL; | |
| 2263 | + if (!PyArg_UnpackTuple(args, "instancemethod", 2, 3, | |
| 2264 | + &func, &self, &classObj)) | |
| 2265 | + return NULL; | |
| 2266 | + if (!PyCallable_Check(func)) { | |
| 2267 | + PyErr_SetString(PyExc_TypeError, | |
| 2268 | + "first argument must be callable"); | |
| 2269 | + return NULL; | |
| 2270 | + } | |
| 2271 | + if (self == Py_None) | |
| 2272 | + self = NULL; | |
| 2273 | + if (self == NULL && classObj == NULL) { | |
| 2274 | + PyErr_SetString(PyExc_TypeError, | |
| 2275 | + "unbound methods must have non-NULL im_class"); | |
| 2276 | + return NULL; | |
| 2277 | + } | |
| 2278 | + | |
| 2279 | + return PyMethod_New(func, self, classObj); | |
| 2280 | +} | |
| 2281 | + | |
| 2282 | +static void | |
| 2283 | +instancemethod_dealloc(register PyMethodObject *im) | |
| 2284 | +{ | |
| 2285 | + _PyObject_GC_UNTRACK(im); | |
| 2286 | + if (im->im_weakreflist != NULL) | |
| 2287 | + PyObject_ClearWeakRefs((PyObject *)im); | |
| 2288 | + Py_DECREF(im->im_func); | |
| 2289 | + Py_XDECREF(im->im_self); | |
| 2290 | + Py_XDECREF(im->im_class); | |
| 2291 | + im->im_self = (PyObject *)free_list; | |
| 2292 | + free_list = im; | |
| 2293 | +} | |
| 2294 | + | |
| 2295 | +static int | |
| 2296 | +instancemethod_compare(PyMethodObject *a, PyMethodObject *b) | |
| 2297 | +{ | |
| 2298 | + int cmp; | |
| 2299 | + cmp = PyObject_Compare(a->im_func, b->im_func); | |
| 2300 | + if (cmp) | |
| 2301 | + return cmp; | |
| 2302 | + | |
| 2303 | + if (a->im_self == b->im_self) | |
| 2304 | + return 0; | |
| 2305 | + if (a->im_self == NULL || b->im_self == NULL) | |
| 2306 | + return (a->im_self < b->im_self) ? -1 : 1; | |
| 2307 | + else | |
| 2308 | + return PyObject_Compare(a->im_self, b->im_self); | |
| 2309 | +} | |
| 2310 | + | |
| 2311 | +static PyObject * | |
| 2312 | +instancemethod_repr(PyMethodObject *a) | |
| 2313 | +{ | |
| 2314 | + PyObject *self = a->im_self; | |
| 2315 | + PyObject *func = a->im_func; | |
| 2316 | + PyObject *klass = a->im_class; | |
| 2317 | + PyObject *funcname = NULL, *klassname = NULL, *result = NULL; | |
| 2318 | + char *sfuncname = "?", *sklassname = "?"; | |
| 2319 | + | |
| 2320 | + funcname = PyObject_GetAttrString(func, "__name__"); | |
| 2321 | + if (funcname == NULL) { | |
| 2322 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 2323 | + return NULL; | |
| 2324 | + PyErr_Clear(); | |
| 2325 | + } | |
| 2326 | + else if (!PyString_Check(funcname)) { | |
| 2327 | + Py_DECREF(funcname); | |
| 2328 | + funcname = NULL; | |
| 2329 | + } | |
| 2330 | + else | |
| 2331 | + sfuncname = PyString_AS_STRING(funcname); | |
| 2332 | + if (klass == NULL) | |
| 2333 | + klassname = NULL; | |
| 2334 | + else { | |
| 2335 | + klassname = PyObject_GetAttrString(klass, "__name__"); | |
| 2336 | + if (klassname == NULL) { | |
| 2337 | + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 2338 | + return NULL; | |
| 2339 | + PyErr_Clear(); | |
| 2340 | + } | |
| 2341 | + else if (!PyString_Check(klassname)) { | |
| 2342 | + Py_DECREF(klassname); | |
| 2343 | + klassname = NULL; | |
| 2344 | + } | |
| 2345 | + else | |
| 2346 | + sklassname = PyString_AS_STRING(klassname); | |
| 2347 | + } | |
| 2348 | + if (self == NULL) | |
| 2349 | + result = PyString_FromFormat("<unbound method %s.%s>", | |
| 2350 | + sklassname, sfuncname); | |
| 2351 | + else { | |
| 2352 | + /* XXX Shouldn't use repr() here! */ | |
| 2353 | + PyObject *selfrepr = PyObject_Repr(self); | |
| 2354 | + if (selfrepr == NULL) | |
| 2355 | + goto fail; | |
| 2356 | + if (!PyString_Check(selfrepr)) { | |
| 2357 | + Py_DECREF(selfrepr); | |
| 2358 | + goto fail; | |
| 2359 | + } | |
| 2360 | + result = PyString_FromFormat("<bound method %s.%s of %s>", | |
| 2361 | + sklassname, sfuncname, | |
| 2362 | + PyString_AS_STRING(selfrepr)); | |
| 2363 | + Py_DECREF(selfrepr); | |
| 2364 | + } | |
| 2365 | + fail: | |
| 2366 | + Py_XDECREF(funcname); | |
| 2367 | + Py_XDECREF(klassname); | |
| 2368 | + return result; | |
| 2369 | +} | |
| 2370 | + | |
| 2371 | +static long | |
| 2372 | +instancemethod_hash(PyMethodObject *a) | |
| 2373 | +{ | |
| 2374 | + long x, y; | |
| 2375 | + if (a->im_self == NULL) | |
| 2376 | + x = PyObject_Hash(Py_None); | |
| 2377 | + else | |
| 2378 | + x = PyObject_Hash(a->im_self); | |
| 2379 | + if (x == -1) | |
| 2380 | + return -1; | |
| 2381 | + y = PyObject_Hash(a->im_func); | |
| 2382 | + if (y == -1) | |
| 2383 | + return -1; | |
| 2384 | + x = x ^ y; | |
| 2385 | + if (x == -1) | |
| 2386 | + x = -2; | |
| 2387 | + return x; | |
| 2388 | +} | |
| 2389 | + | |
| 2390 | +static int | |
| 2391 | +instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg) | |
| 2392 | +{ | |
| 2393 | + Py_VISIT(im->im_func); | |
| 2394 | + Py_VISIT(im->im_self); | |
| 2395 | + Py_VISIT(im->im_class); | |
| 2396 | + return 0; | |
| 2397 | +} | |
| 2398 | + | |
| 2399 | +static void | |
| 2400 | +getclassname(PyObject *klass, char *buf, int bufsize) | |
| 2401 | +{ | |
| 2402 | + PyObject *name; | |
| 2403 | + | |
| 2404 | + assert(bufsize > 1); | |
| 2405 | + strcpy(buf, "?"); /* Default outcome */ | |
| 2406 | + if (klass == NULL) | |
| 2407 | + return; | |
| 2408 | + name = PyObject_GetAttrString(klass, "__name__"); | |
| 2409 | + if (name == NULL) { | |
| 2410 | + /* This function cannot return an exception */ | |
| 2411 | + PyErr_Clear(); | |
| 2412 | + return; | |
| 2413 | + } | |
| 2414 | + if (PyString_Check(name)) { | |
| 2415 | + strncpy(buf, PyString_AS_STRING(name), bufsize); | |
| 2416 | + buf[bufsize-1] = '\0'; | |
| 2417 | + } | |
| 2418 | + Py_DECREF(name); | |
| 2419 | +} | |
| 2420 | + | |
| 2421 | +static void | |
| 2422 | +getinstclassname(PyObject *inst, char *buf, int bufsize) | |
| 2423 | +{ | |
| 2424 | + PyObject *klass; | |
| 2425 | + | |
| 2426 | + if (inst == NULL) { | |
| 2427 | + assert(bufsize > 0 && (size_t)bufsize > strlen("nothing")); | |
| 2428 | + strcpy(buf, "nothing"); | |
| 2429 | + return; | |
| 2430 | + } | |
| 2431 | + | |
| 2432 | + klass = PyObject_GetAttrString(inst, "__class__"); | |
| 2433 | + if (klass == NULL) { | |
| 2434 | + /* This function cannot return an exception */ | |
| 2435 | + PyErr_Clear(); | |
| 2436 | + klass = (PyObject *)(inst->ob_type); | |
| 2437 | + Py_INCREF(klass); | |
| 2438 | + } | |
| 2439 | + getclassname(klass, buf, bufsize); | |
| 2440 | + Py_XDECREF(klass); | |
| 2441 | +} | |
| 2442 | + | |
| 2443 | +static PyObject * | |
| 2444 | +instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw) | |
| 2445 | +{ | |
| 2446 | + PyObject *self = PyMethod_GET_SELF(func); | |
| 2447 | + PyObject *klass = PyMethod_GET_CLASS(func); | |
| 2448 | + PyObject *result; | |
| 2449 | + | |
| 2450 | + func = PyMethod_GET_FUNCTION(func); | |
| 2451 | + if (self == NULL) { | |
| 2452 | + /* Unbound methods must be called with an instance of | |
| 2453 | + the class (or a derived class) as first argument */ | |
| 2454 | + int ok; | |
| 2455 | + if (PyTuple_Size(arg) >= 1) | |
| 2456 | + self = PyTuple_GET_ITEM(arg, 0); | |
| 2457 | + if (self == NULL) | |
| 2458 | + ok = 0; | |
| 2459 | + else { | |
| 2460 | + ok = PyObject_IsInstance(self, klass); | |
| 2461 | + if (ok < 0) | |
| 2462 | + return NULL; | |
| 2463 | + } | |
| 2464 | + if (!ok) { | |
| 2465 | + char clsbuf[256]; | |
| 2466 | + char instbuf[256]; | |
| 2467 | + getclassname(klass, clsbuf, sizeof(clsbuf)); | |
| 2468 | + getinstclassname(self, instbuf, sizeof(instbuf)); | |
| 2469 | + PyErr_Format(PyExc_TypeError, | |
| 2470 | + "unbound method %s%s must be called with " | |
| 2471 | + "%s instance as first argument " | |
| 2472 | + "(got %s%s instead)", | |
| 2473 | + PyEval_GetFuncName(func), | |
| 2474 | + PyEval_GetFuncDesc(func), | |
| 2475 | + clsbuf, | |
| 2476 | + instbuf, | |
| 2477 | + self == NULL ? "" : " instance"); | |
| 2478 | + return NULL; | |
| 2479 | + } | |
| 2480 | + Py_INCREF(arg); | |
| 2481 | + } | |
| 2482 | + else { | |
| 2483 | + Py_ssize_t argcount = PyTuple_Size(arg); | |
| 2484 | + PyObject *newarg = PyTuple_New(argcount + 1); | |
| 2485 | + int i; | |
| 2486 | + if (newarg == NULL) | |
| 2487 | + return NULL; | |
| 2488 | + Py_INCREF(self); | |
| 2489 | + PyTuple_SET_ITEM(newarg, 0, self); | |
| 2490 | + for (i = 0; i < argcount; i++) { | |
| 2491 | + PyObject *v = PyTuple_GET_ITEM(arg, i); | |
| 2492 | + Py_XINCREF(v); | |
| 2493 | + PyTuple_SET_ITEM(newarg, i+1, v); | |
| 2494 | + } | |
| 2495 | + arg = newarg; | |
| 2496 | + } | |
| 2497 | + result = PyObject_Call((PyObject *)func, arg, kw); | |
| 2498 | + Py_DECREF(arg); | |
| 2499 | + return result; | |
| 2500 | +} | |
| 2501 | + | |
| 2502 | +static PyObject * | |
| 2503 | +instancemethod_descr_get(PyObject *meth, PyObject *obj, PyObject *cls) | |
| 2504 | +{ | |
| 2505 | + /* Don't rebind an already bound method, or an unbound method | |
| 2506 | + of a class that's not a base class of cls. */ | |
| 2507 | + | |
| 2508 | + if (PyMethod_GET_SELF(meth) != NULL) { | |
| 2509 | + /* Already bound */ | |
| 2510 | + Py_INCREF(meth); | |
| 2511 | + return meth; | |
| 2512 | + } | |
| 2513 | + /* No, it is an unbound method */ | |
| 2514 | + if (PyMethod_GET_CLASS(meth) != NULL && cls != NULL) { | |
| 2515 | + /* Do subclass test. If it fails, return meth unchanged. */ | |
| 2516 | + int ok = PyObject_IsSubclass(cls, PyMethod_GET_CLASS(meth)); | |
| 2517 | + if (ok < 0) | |
| 2518 | + return NULL; | |
| 2519 | + if (!ok) { | |
| 2520 | + Py_INCREF(meth); | |
| 2521 | + return meth; | |
| 2522 | + } | |
| 2523 | + } | |
| 2524 | + /* Bind it to obj */ | |
| 2525 | + return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, cls); | |
| 2526 | +} | |
| 2527 | + | |
| 2528 | +PyTypeObject PyMethod_Type = { | |
| 2529 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 2530 | + 0, | |
| 2531 | + "instancemethod", | |
| 2532 | + sizeof(PyMethodObject), | |
| 2533 | + 0, | |
| 2534 | + (destructor)instancemethod_dealloc, /* tp_dealloc */ | |
| 2535 | + 0, /* tp_print */ | |
| 2536 | + 0, /* tp_getattr */ | |
| 2537 | + 0, /* tp_setattr */ | |
| 2538 | + (cmpfunc)instancemethod_compare, /* tp_compare */ | |
| 2539 | + (reprfunc)instancemethod_repr, /* tp_repr */ | |
| 2540 | + 0, /* tp_as_number */ | |
| 2541 | + 0, /* tp_as_sequence */ | |
| 2542 | + 0, /* tp_as_mapping */ | |
| 2543 | + (hashfunc)instancemethod_hash, /* tp_hash */ | |
| 2544 | + instancemethod_call, /* tp_call */ | |
| 2545 | + 0, /* tp_str */ | |
| 2546 | + instancemethod_getattro, /* tp_getattro */ | |
| 2547 | + PyObject_GenericSetAttr, /* tp_setattro */ | |
| 2548 | + 0, /* tp_as_buffer */ | |
| 2549 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */ | |
| 2550 | + instancemethod_doc, /* tp_doc */ | |
| 2551 | + (traverseproc)instancemethod_traverse, /* tp_traverse */ | |
| 2552 | + 0, /* tp_clear */ | |
| 2553 | + 0, /* tp_richcompare */ | |
| 2554 | + offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */ | |
| 2555 | + 0, /* tp_iter */ | |
| 2556 | + 0, /* tp_iternext */ | |
| 2557 | + 0, /* tp_methods */ | |
| 2558 | + instancemethod_memberlist, /* tp_members */ | |
| 2559 | + instancemethod_getset, /* tp_getset */ | |
| 2560 | + 0, /* tp_base */ | |
| 2561 | + 0, /* tp_dict */ | |
| 2562 | + instancemethod_descr_get, /* tp_descr_get */ | |
| 2563 | + 0, /* tp_descr_set */ | |
| 2564 | + 0, /* tp_dictoffset */ | |
| 2565 | + 0, /* tp_init */ | |
| 2566 | + 0, /* tp_alloc */ | |
| 2567 | + instancemethod_new, /* tp_new */ | |
| 2568 | +}; | |
| 2569 | + | |
| 2570 | +/* Clear out the free list */ | |
| 2571 | + | |
| 2572 | +void | |
| 2573 | +PyMethod_Fini(void) | |
| 2574 | +{ | |
| 2575 | + while (free_list) { | |
| 2576 | + PyMethodObject *im = free_list; | |
| 2577 | + free_list = (PyMethodObject *)(im->im_self); | |
| 2578 | + PyObject_GC_Del(im); | |
| 2579 | + } | |
| 2580 | +} | |
| @@ -0,0 +1,161 @@ | ||
| 1 | + | |
| 2 | +/* Wrap void* pointers to be passed between C modules */ | |
| 3 | + | |
| 4 | +#include "Python.h" | |
| 5 | + | |
| 6 | + | |
| 7 | +/* Declarations for objects of type PyCObject */ | |
| 8 | + | |
| 9 | +typedef void (*destructor1)(void *); | |
| 10 | +typedef void (*destructor2)(void *, void*); | |
| 11 | + | |
| 12 | +typedef struct { | |
| 13 | + PyObject_HEAD | |
| 14 | + void *cobject; | |
| 15 | + void *desc; | |
| 16 | + void (*destructor)(void *); | |
| 17 | +} PyCObject; | |
| 18 | + | |
| 19 | +PyObject * | |
| 20 | +PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *)) | |
| 21 | +{ | |
| 22 | + PyCObject *self; | |
| 23 | + | |
| 24 | + self = PyObject_NEW(PyCObject, &PyCObject_Type); | |
| 25 | + if (self == NULL) | |
| 26 | + return NULL; | |
| 27 | + self->cobject=cobj; | |
| 28 | + self->destructor=destr; | |
| 29 | + self->desc=NULL; | |
| 30 | + | |
| 31 | + return (PyObject *)self; | |
| 32 | +} | |
| 33 | + | |
| 34 | +PyObject * | |
| 35 | +PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc, | |
| 36 | + void (*destr)(void *, void *)) | |
| 37 | +{ | |
| 38 | + PyCObject *self; | |
| 39 | + | |
| 40 | + if (!desc) { | |
| 41 | + PyErr_SetString(PyExc_TypeError, | |
| 42 | + "PyCObject_FromVoidPtrAndDesc called with null" | |
| 43 | + " description"); | |
| 44 | + return NULL; | |
| 45 | + } | |
| 46 | + self = PyObject_NEW(PyCObject, &PyCObject_Type); | |
| 47 | + if (self == NULL) | |
| 48 | + return NULL; | |
| 49 | + self->cobject = cobj; | |
| 50 | + self->destructor = (destructor1)destr; | |
| 51 | + self->desc = desc; | |
| 52 | + | |
| 53 | + return (PyObject *)self; | |
| 54 | +} | |
| 55 | + | |
| 56 | +void * | |
| 57 | +PyCObject_AsVoidPtr(PyObject *self) | |
| 58 | +{ | |
| 59 | + if (self) { | |
| 60 | + if (self->ob_type == &PyCObject_Type) | |
| 61 | + return ((PyCObject *)self)->cobject; | |
| 62 | + PyErr_SetString(PyExc_TypeError, | |
| 63 | + "PyCObject_AsVoidPtr with non-C-object"); | |
| 64 | + } | |
| 65 | + if (!PyErr_Occurred()) | |
| 66 | + PyErr_SetString(PyExc_TypeError, | |
| 67 | + "PyCObject_AsVoidPtr called with null pointer"); | |
| 68 | + return NULL; | |
| 69 | +} | |
| 70 | + | |
| 71 | +void * | |
| 72 | +PyCObject_GetDesc(PyObject *self) | |
| 73 | +{ | |
| 74 | + if (self) { | |
| 75 | + if (self->ob_type == &PyCObject_Type) | |
| 76 | + return ((PyCObject *)self)->desc; | |
| 77 | + PyErr_SetString(PyExc_TypeError, | |
| 78 | + "PyCObject_GetDesc with non-C-object"); | |
| 79 | + } | |
| 80 | + if (!PyErr_Occurred()) | |
| 81 | + PyErr_SetString(PyExc_TypeError, | |
| 82 | + "PyCObject_GetDesc called with null pointer"); | |
| 83 | + return NULL; | |
| 84 | +} | |
| 85 | + | |
| 86 | +void * | |
| 87 | +PyCObject_Import(char *module_name, char *name) | |
| 88 | +{ | |
| 89 | + PyObject *m, *c; | |
| 90 | + void *r = NULL; | |
| 91 | + | |
| 92 | + if ((m = PyImport_ImportModule(module_name))) { | |
| 93 | + if ((c = PyObject_GetAttrString(m,name))) { | |
| 94 | + r = PyCObject_AsVoidPtr(c); | |
| 95 | + Py_DECREF(c); | |
| 96 | + } | |
| 97 | + Py_DECREF(m); | |
| 98 | + } | |
| 99 | + return r; | |
| 100 | +} | |
| 101 | + | |
| 102 | +int | |
| 103 | +PyCObject_SetVoidPtr(PyObject *self, void *cobj) | |
| 104 | +{ | |
| 105 | + PyCObject* cself = (PyCObject*)self; | |
| 106 | + if (cself == NULL || !PyCObject_Check(cself) || | |
| 107 | + cself->destructor != NULL) { | |
| 108 | + PyErr_SetString(PyExc_TypeError, | |
| 109 | + "Invalid call to PyCObject_SetVoidPtr"); | |
| 110 | + return 0; | |
| 111 | + } | |
| 112 | + cself->cobject = cobj; | |
| 113 | + return 1; | |
| 114 | +} | |
| 115 | + | |
| 116 | +static void | |
| 117 | +PyCObject_dealloc(PyCObject *self) | |
| 118 | +{ | |
| 119 | + if (self->destructor) { | |
| 120 | + if(self->desc) | |
| 121 | + ((destructor2)(self->destructor))(self->cobject, self->desc); | |
| 122 | + else | |
| 123 | + (self->destructor)(self->cobject); | |
| 124 | + } | |
| 125 | + PyObject_DEL(self); | |
| 126 | +} | |
| 127 | + | |
| 128 | + | |
| 129 | +PyDoc_STRVAR(PyCObject_Type__doc__, | |
| 130 | +"C objects to be exported from one extension module to another\n\ | |
| 131 | +\n\ | |
| 132 | +C objects are used for communication between extension modules. They\n\ | |
| 133 | +provide a way for an extension module to export a C interface to other\n\ | |
| 134 | +extension modules, so that extension modules can use the Python import\n\ | |
| 135 | +mechanism to link to one another."); | |
| 136 | + | |
| 137 | +PyTypeObject PyCObject_Type = { | |
| 138 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 139 | + 0, /*ob_size*/ | |
| 140 | + "PyCObject", /*tp_name*/ | |
| 141 | + sizeof(PyCObject), /*tp_basicsize*/ | |
| 142 | + 0, /*tp_itemsize*/ | |
| 143 | + /* methods */ | |
| 144 | + (destructor)PyCObject_dealloc, /*tp_dealloc*/ | |
| 145 | + 0, /*tp_print*/ | |
| 146 | + 0, /*tp_getattr*/ | |
| 147 | + 0, /*tp_setattr*/ | |
| 148 | + 0, /*tp_compare*/ | |
| 149 | + 0, /*tp_repr*/ | |
| 150 | + 0, /*tp_as_number*/ | |
| 151 | + 0, /*tp_as_sequence*/ | |
| 152 | + 0, /*tp_as_mapping*/ | |
| 153 | + 0, /*tp_hash*/ | |
| 154 | + 0, /*tp_call*/ | |
| 155 | + 0, /*tp_str*/ | |
| 156 | + 0, /*tp_getattro*/ | |
| 157 | + 0, /*tp_setattro*/ | |
| 158 | + 0, /*tp_as_buffer*/ | |
| 159 | + 0, /*tp_flags*/ | |
| 160 | + PyCObject_Type__doc__ /*tp_doc*/ | |
| 161 | +}; | |
| @@ -0,0 +1,590 @@ | ||
| 1 | +#include "Python.h" | |
| 2 | +#include "code.h" | |
| 3 | +#include "structmember.h" | |
| 4 | + | |
| 5 | +#define NAME_CHARS \ | |
| 6 | + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" | |
| 7 | + | |
| 8 | +/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */ | |
| 9 | + | |
| 10 | +static int | |
| 11 | +all_name_chars(unsigned char *s) | |
| 12 | +{ | |
| 13 | + static char ok_name_char[256]; | |
| 14 | + static unsigned char *name_chars = (unsigned char *)NAME_CHARS; | |
| 15 | + | |
| 16 | + if (ok_name_char[*name_chars] == 0) { | |
| 17 | + unsigned char *p; | |
| 18 | + for (p = name_chars; *p; p++) | |
| 19 | + ok_name_char[*p] = 1; | |
| 20 | + } | |
| 21 | + while (*s) { | |
| 22 | + if (ok_name_char[*s++] == 0) | |
| 23 | + return 0; | |
| 24 | + } | |
| 25 | + return 1; | |
| 26 | +} | |
| 27 | + | |
| 28 | +static void | |
| 29 | +intern_strings(PyObject *tuple) | |
| 30 | +{ | |
| 31 | + Py_ssize_t i; | |
| 32 | + | |
| 33 | + for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { | |
| 34 | + PyObject *v = PyTuple_GET_ITEM(tuple, i); | |
| 35 | + if (v == NULL || !PyString_CheckExact(v)) { | |
| 36 | + Py_FatalError("non-string found in code slot"); | |
| 37 | + } | |
| 38 | + PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i)); | |
| 39 | + } | |
| 40 | +} | |
| 41 | + | |
| 42 | + | |
| 43 | +PyCodeObject * | |
| 44 | +PyCode_New(int argcount, int nlocals, int stacksize, int flags, | |
| 45 | + PyObject *code, PyObject *consts, PyObject *names, | |
| 46 | + PyObject *varnames, PyObject *freevars, PyObject *cellvars, | |
| 47 | + PyObject *filename, PyObject *name, int firstlineno, | |
| 48 | + PyObject *lnotab) | |
| 49 | +{ | |
| 50 | + PyCodeObject *co; | |
| 51 | + Py_ssize_t i; | |
| 52 | + /* Check argument types */ | |
| 53 | + if (argcount < 0 || nlocals < 0 || | |
| 54 | + code == NULL || | |
| 55 | + consts == NULL || !PyTuple_Check(consts) || | |
| 56 | + names == NULL || !PyTuple_Check(names) || | |
| 57 | + varnames == NULL || !PyTuple_Check(varnames) || | |
| 58 | + freevars == NULL || !PyTuple_Check(freevars) || | |
| 59 | + cellvars == NULL || !PyTuple_Check(cellvars) || | |
| 60 | + name == NULL || !PyString_Check(name) || | |
| 61 | + filename == NULL || !PyString_Check(filename) || | |
| 62 | + lnotab == NULL || !PyString_Check(lnotab) || | |
| 63 | + !PyObject_CheckReadBuffer(code)) { | |
| 64 | + PyErr_BadInternalCall(); | |
| 65 | + return NULL; | |
| 66 | + } | |
| 67 | + intern_strings(names); | |
| 68 | + intern_strings(varnames); | |
| 69 | + intern_strings(freevars); | |
| 70 | + intern_strings(cellvars); | |
| 71 | + /* Intern selected string constants */ | |
| 72 | + for (i = PyTuple_Size(consts); --i >= 0; ) { | |
| 73 | + PyObject *v = PyTuple_GetItem(consts, i); | |
| 74 | + if (!PyString_Check(v)) | |
| 75 | + continue; | |
| 76 | + if (!all_name_chars((unsigned char *)PyString_AS_STRING(v))) | |
| 77 | + continue; | |
| 78 | + PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i)); | |
| 79 | + } | |
| 80 | + co = PyObject_NEW(PyCodeObject, &PyCode_Type); | |
| 81 | + if (co != NULL) { | |
| 82 | + co->co_argcount = argcount; | |
| 83 | + co->co_nlocals = nlocals; | |
| 84 | + co->co_stacksize = stacksize; | |
| 85 | + co->co_flags = flags; | |
| 86 | + Py_INCREF(code); | |
| 87 | + co->co_code = code; | |
| 88 | + Py_INCREF(consts); | |
| 89 | + co->co_consts = consts; | |
| 90 | + Py_INCREF(names); | |
| 91 | + co->co_names = names; | |
| 92 | + Py_INCREF(varnames); | |
| 93 | + co->co_varnames = varnames; | |
| 94 | + Py_INCREF(freevars); | |
| 95 | + co->co_freevars = freevars; | |
| 96 | + Py_INCREF(cellvars); | |
| 97 | + co->co_cellvars = cellvars; | |
| 98 | + Py_INCREF(filename); | |
| 99 | + co->co_filename = filename; | |
| 100 | + Py_INCREF(name); | |
| 101 | + co->co_name = name; | |
| 102 | + co->co_firstlineno = firstlineno; | |
| 103 | + Py_INCREF(lnotab); | |
| 104 | + co->co_lnotab = lnotab; | |
| 105 | + co->co_zombieframe = NULL; | |
| 106 | + } | |
| 107 | + return co; | |
| 108 | +} | |
| 109 | + | |
| 110 | + | |
| 111 | +#define OFF(x) offsetof(PyCodeObject, x) | |
| 112 | + | |
| 113 | +static PyMemberDef code_memberlist[] = { | |
| 114 | + {"co_argcount", T_INT, OFF(co_argcount), READONLY}, | |
| 115 | + {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, | |
| 116 | + {"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, | |
| 117 | + {"co_flags", T_INT, OFF(co_flags), READONLY}, | |
| 118 | + {"co_code", T_OBJECT, OFF(co_code), READONLY}, | |
| 119 | + {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, | |
| 120 | + {"co_names", T_OBJECT, OFF(co_names), READONLY}, | |
| 121 | + {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY}, | |
| 122 | + {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY}, | |
| 123 | + {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY}, | |
| 124 | + {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, | |
| 125 | + {"co_name", T_OBJECT, OFF(co_name), READONLY}, | |
| 126 | + {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, | |
| 127 | + {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY}, | |
| 128 | + {NULL} /* Sentinel */ | |
| 129 | +}; | |
| 130 | + | |
| 131 | +/* Helper for code_new: return a shallow copy of a tuple that is | |
| 132 | + guaranteed to contain exact strings, by converting string subclasses | |
| 133 | + to exact strings and complaining if a non-string is found. */ | |
| 134 | +static PyObject* | |
| 135 | +validate_and_copy_tuple(PyObject *tup) | |
| 136 | +{ | |
| 137 | + PyObject *newtuple; | |
| 138 | + PyObject *item; | |
| 139 | + Py_ssize_t i, len; | |
| 140 | + | |
| 141 | + len = PyTuple_GET_SIZE(tup); | |
| 142 | + newtuple = PyTuple_New(len); | |
| 143 | + if (newtuple == NULL) | |
| 144 | + return NULL; | |
| 145 | + | |
| 146 | + for (i = 0; i < len; i++) { | |
| 147 | + item = PyTuple_GET_ITEM(tup, i); | |
| 148 | + if (PyString_CheckExact(item)) { | |
| 149 | + Py_INCREF(item); | |
| 150 | + } | |
| 151 | + else if (!PyString_Check(item)) { | |
| 152 | + PyErr_Format( | |
| 153 | + PyExc_TypeError, | |
| 154 | + "name tuples must contain only " | |
| 155 | + "strings, not '%.500s'", | |
| 156 | + item->ob_type->tp_name); | |
| 157 | + Py_DECREF(newtuple); | |
| 158 | + return NULL; | |
| 159 | + } | |
| 160 | + else { | |
| 161 | + item = PyString_FromStringAndSize( | |
| 162 | + PyString_AS_STRING(item), | |
| 163 | + PyString_GET_SIZE(item)); | |
| 164 | + if (item == NULL) { | |
| 165 | + Py_DECREF(newtuple); | |
| 166 | + return NULL; | |
| 167 | + } | |
| 168 | + } | |
| 169 | + PyTuple_SET_ITEM(newtuple, i, item); | |
| 170 | + } | |
| 171 | + | |
| 172 | + return newtuple; | |
| 173 | +} | |
| 174 | + | |
| 175 | +PyDoc_STRVAR(code_doc, | |
| 176 | +"code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\ | |
| 177 | + varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\ | |
| 178 | +\n\ | |
| 179 | +Create a code object. Not for the faint of heart."); | |
| 180 | + | |
| 181 | +static PyObject * | |
| 182 | +code_new(PyTypeObject *type, PyObject *args, PyObject *kw) | |
| 183 | +{ | |
| 184 | + int argcount; | |
| 185 | + int nlocals; | |
| 186 | + int stacksize; | |
| 187 | + int flags; | |
| 188 | + PyObject *co = NULL; | |
| 189 | + PyObject *code; | |
| 190 | + PyObject *consts; | |
| 191 | + PyObject *names, *ournames = NULL; | |
| 192 | + PyObject *varnames, *ourvarnames = NULL; | |
| 193 | + PyObject *freevars = NULL, *ourfreevars = NULL; | |
| 194 | + PyObject *cellvars = NULL, *ourcellvars = NULL; | |
| 195 | + PyObject *filename; | |
| 196 | + PyObject *name; | |
| 197 | + int firstlineno; | |
| 198 | + PyObject *lnotab; | |
| 199 | + | |
| 200 | + if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code", | |
| 201 | + &argcount, &nlocals, &stacksize, &flags, | |
| 202 | + &code, | |
| 203 | + &PyTuple_Type, &consts, | |
| 204 | + &PyTuple_Type, &names, | |
| 205 | + &PyTuple_Type, &varnames, | |
| 206 | + &filename, &name, | |
| 207 | + &firstlineno, &lnotab, | |
| 208 | + &PyTuple_Type, &freevars, | |
| 209 | + &PyTuple_Type, &cellvars)) | |
| 210 | + return NULL; | |
| 211 | + | |
| 212 | + if (argcount < 0) { | |
| 213 | + PyErr_SetString( | |
| 214 | + PyExc_ValueError, | |
| 215 | + "code: argcount must not be negative"); | |
| 216 | + goto cleanup; | |
| 217 | + } | |
| 218 | + | |
| 219 | + if (nlocals < 0) { | |
| 220 | + PyErr_SetString( | |
| 221 | + PyExc_ValueError, | |
| 222 | + "code: nlocals must not be negative"); | |
| 223 | + goto cleanup; | |
| 224 | + } | |
| 225 | + | |
| 226 | + ournames = validate_and_copy_tuple(names); | |
| 227 | + if (ournames == NULL) | |
| 228 | + goto cleanup; | |
| 229 | + ourvarnames = validate_and_copy_tuple(varnames); | |
| 230 | + if (ourvarnames == NULL) | |
| 231 | + goto cleanup; | |
| 232 | + if (freevars) | |
| 233 | + ourfreevars = validate_and_copy_tuple(freevars); | |
| 234 | + else | |
| 235 | + ourfreevars = PyTuple_New(0); | |
| 236 | + if (ourfreevars == NULL) | |
| 237 | + goto cleanup; | |
| 238 | + if (cellvars) | |
| 239 | + ourcellvars = validate_and_copy_tuple(cellvars); | |
| 240 | + else | |
| 241 | + ourcellvars = PyTuple_New(0); | |
| 242 | + if (ourcellvars == NULL) | |
| 243 | + goto cleanup; | |
| 244 | + | |
| 245 | + co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags, | |
| 246 | + code, consts, ournames, ourvarnames, | |
| 247 | + ourfreevars, ourcellvars, filename, | |
| 248 | + name, firstlineno, lnotab); | |
| 249 | + cleanup: | |
| 250 | + Py_XDECREF(ournames); | |
| 251 | + Py_XDECREF(ourvarnames); | |
| 252 | + Py_XDECREF(ourfreevars); | |
| 253 | + Py_XDECREF(ourcellvars); | |
| 254 | + return co; | |
| 255 | +} | |
| 256 | + | |
| 257 | +static void | |
| 258 | +code_dealloc(PyCodeObject *co) | |
| 259 | +{ | |
| 260 | + Py_XDECREF(co->co_code); | |
| 261 | + Py_XDECREF(co->co_consts); | |
| 262 | + Py_XDECREF(co->co_names); | |
| 263 | + Py_XDECREF(co->co_varnames); | |
| 264 | + Py_XDECREF(co->co_freevars); | |
| 265 | + Py_XDECREF(co->co_cellvars); | |
| 266 | + Py_XDECREF(co->co_filename); | |
| 267 | + Py_XDECREF(co->co_name); | |
| 268 | + Py_XDECREF(co->co_lnotab); | |
| 269 | + if (co->co_zombieframe != NULL) | |
| 270 | + PyObject_GC_Del(co->co_zombieframe); | |
| 271 | + PyObject_DEL(co); | |
| 272 | +} | |
| 273 | + | |
| 274 | +static PyObject * | |
| 275 | +code_repr(PyCodeObject *co) | |
| 276 | +{ | |
| 277 | + char buf[500]; | |
| 278 | + int lineno = -1; | |
| 279 | + char *filename = "???"; | |
| 280 | + char *name = "???"; | |
| 281 | + | |
| 282 | + if (co->co_firstlineno != 0) | |
| 283 | + lineno = co->co_firstlineno; | |
| 284 | + if (co->co_filename && PyString_Check(co->co_filename)) | |
| 285 | + filename = PyString_AS_STRING(co->co_filename); | |
| 286 | + if (co->co_name && PyString_Check(co->co_name)) | |
| 287 | + name = PyString_AS_STRING(co->co_name); | |
| 288 | + PyOS_snprintf(buf, sizeof(buf), | |
| 289 | + "<code object %.100s at %p, file \"%.300s\", line %d>", | |
| 290 | + name, co, filename, lineno); | |
| 291 | + return PyString_FromString(buf); | |
| 292 | +} | |
| 293 | + | |
| 294 | +static int | |
| 295 | +code_compare(PyCodeObject *co, PyCodeObject *cp) | |
| 296 | +{ | |
| 297 | + int cmp; | |
| 298 | + cmp = PyObject_Compare(co->co_name, cp->co_name); | |
| 299 | + if (cmp) return cmp; | |
| 300 | + cmp = co->co_argcount - cp->co_argcount; | |
| 301 | + if (cmp) goto normalize; | |
| 302 | + cmp = co->co_nlocals - cp->co_nlocals; | |
| 303 | + if (cmp) goto normalize; | |
| 304 | + cmp = co->co_flags - cp->co_flags; | |
| 305 | + if (cmp) goto normalize; | |
| 306 | + cmp = co->co_firstlineno - cp->co_firstlineno; | |
| 307 | + if (cmp) goto normalize; | |
| 308 | + cmp = PyObject_Compare(co->co_code, cp->co_code); | |
| 309 | + if (cmp) return cmp; | |
| 310 | + cmp = PyObject_Compare(co->co_consts, cp->co_consts); | |
| 311 | + if (cmp) return cmp; | |
| 312 | + cmp = PyObject_Compare(co->co_names, cp->co_names); | |
| 313 | + if (cmp) return cmp; | |
| 314 | + cmp = PyObject_Compare(co->co_varnames, cp->co_varnames); | |
| 315 | + if (cmp) return cmp; | |
| 316 | + cmp = PyObject_Compare(co->co_freevars, cp->co_freevars); | |
| 317 | + if (cmp) return cmp; | |
| 318 | + cmp = PyObject_Compare(co->co_cellvars, cp->co_cellvars); | |
| 319 | + return cmp; | |
| 320 | + | |
| 321 | + normalize: | |
| 322 | + if (cmp > 0) | |
| 323 | + return 1; | |
| 324 | + else if (cmp < 0) | |
| 325 | + return -1; | |
| 326 | + else | |
| 327 | + return 0; | |
| 328 | +} | |
| 329 | + | |
| 330 | +static long | |
| 331 | +code_hash(PyCodeObject *co) | |
| 332 | +{ | |
| 333 | + long h, h0, h1, h2, h3, h4, h5, h6; | |
| 334 | + h0 = PyObject_Hash(co->co_name); | |
| 335 | + if (h0 == -1) return -1; | |
| 336 | + h1 = PyObject_Hash(co->co_code); | |
| 337 | + if (h1 == -1) return -1; | |
| 338 | + h2 = PyObject_Hash(co->co_consts); | |
| 339 | + if (h2 == -1) return -1; | |
| 340 | + h3 = PyObject_Hash(co->co_names); | |
| 341 | + if (h3 == -1) return -1; | |
| 342 | + h4 = PyObject_Hash(co->co_varnames); | |
| 343 | + if (h4 == -1) return -1; | |
| 344 | + h5 = PyObject_Hash(co->co_freevars); | |
| 345 | + if (h5 == -1) return -1; | |
| 346 | + h6 = PyObject_Hash(co->co_cellvars); | |
| 347 | + if (h6 == -1) return -1; | |
| 348 | + h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^ | |
| 349 | + co->co_argcount ^ co->co_nlocals ^ co->co_flags; | |
| 350 | + if (h == -1) h = -2; | |
| 351 | + return h; | |
| 352 | +} | |
| 353 | + | |
| 354 | +/* XXX code objects need to participate in GC? */ | |
| 355 | + | |
| 356 | +PyTypeObject PyCode_Type = { | |
| 357 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 358 | + 0, | |
| 359 | + "code", | |
| 360 | + sizeof(PyCodeObject), | |
| 361 | + 0, | |
| 362 | + (destructor)code_dealloc, /* tp_dealloc */ | |
| 363 | + 0, /* tp_print */ | |
| 364 | + 0, /* tp_getattr */ | |
| 365 | + 0, /* tp_setattr */ | |
| 366 | + (cmpfunc)code_compare, /* tp_compare */ | |
| 367 | + (reprfunc)code_repr, /* tp_repr */ | |
| 368 | + 0, /* tp_as_number */ | |
| 369 | + 0, /* tp_as_sequence */ | |
| 370 | + 0, /* tp_as_mapping */ | |
| 371 | + (hashfunc)code_hash, /* tp_hash */ | |
| 372 | + 0, /* tp_call */ | |
| 373 | + 0, /* tp_str */ | |
| 374 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 375 | + 0, /* tp_setattro */ | |
| 376 | + 0, /* tp_as_buffer */ | |
| 377 | + Py_TPFLAGS_DEFAULT, /* tp_flags */ | |
| 378 | + code_doc, /* tp_doc */ | |
| 379 | + 0, /* tp_traverse */ | |
| 380 | + 0, /* tp_clear */ | |
| 381 | + 0, /* tp_richcompare */ | |
| 382 | + 0, /* tp_weaklistoffset */ | |
| 383 | + 0, /* tp_iter */ | |
| 384 | + 0, /* tp_iternext */ | |
| 385 | + 0, /* tp_methods */ | |
| 386 | + code_memberlist, /* tp_members */ | |
| 387 | + 0, /* tp_getset */ | |
| 388 | + 0, /* tp_base */ | |
| 389 | + 0, /* tp_dict */ | |
| 390 | + 0, /* tp_descr_get */ | |
| 391 | + 0, /* tp_descr_set */ | |
| 392 | + 0, /* tp_dictoffset */ | |
| 393 | + 0, /* tp_init */ | |
| 394 | + 0, /* tp_alloc */ | |
| 395 | + code_new, /* tp_new */ | |
| 396 | +}; | |
| 397 | + | |
| 398 | +/* All about c_lnotab. | |
| 399 | + | |
| 400 | +c_lnotab is an array of unsigned bytes disguised as a Python string. In -O | |
| 401 | +mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped | |
| 402 | +to source code line #s (when needed for tracebacks) via c_lnotab instead. | |
| 403 | +The array is conceptually a list of | |
| 404 | + (bytecode offset increment, line number increment) | |
| 405 | +pairs. The details are important and delicate, best illustrated by example: | |
| 406 | + | |
| 407 | + byte code offset source code line number | |
| 408 | + 0 1 | |
| 409 | + 6 2 | |
| 410 | + 50 7 | |
| 411 | + 350 307 | |
| 412 | + 361 308 | |
| 413 | + | |
| 414 | +The first trick is that these numbers aren't stored, only the increments | |
| 415 | +from one row to the next (this doesn't really work, but it's a start): | |
| 416 | + | |
| 417 | + 0, 1, 6, 1, 44, 5, 300, 300, 11, 1 | |
| 418 | + | |
| 419 | +The second trick is that an unsigned byte can't hold negative values, or | |
| 420 | +values larger than 255, so (a) there's a deep assumption that byte code | |
| 421 | +offsets and their corresponding line #s both increase monotonically, and (b) | |
| 422 | +if at least one column jumps by more than 255 from one row to the next, more | |
| 423 | +than one pair is written to the table. In case #b, there's no way to know | |
| 424 | +from looking at the table later how many were written. That's the delicate | |
| 425 | +part. A user of c_lnotab desiring to find the source line number | |
| 426 | +corresponding to a bytecode address A should do something like this | |
| 427 | + | |
| 428 | + lineno = addr = 0 | |
| 429 | + for addr_incr, line_incr in c_lnotab: | |
| 430 | + addr += addr_incr | |
| 431 | + if addr > A: | |
| 432 | + return lineno | |
| 433 | + lineno += line_incr | |
| 434 | + | |
| 435 | +In order for this to work, when the addr field increments by more than 255, | |
| 436 | +the line # increment in each pair generated must be 0 until the remaining addr | |
| 437 | +increment is < 256. So, in the example above, com_set_lineno should not (as | |
| 438 | +was actually done until 2.2) expand 300, 300 to 255, 255, 45, 45, but to | |
| 439 | +255, 0, 45, 255, 0, 45. | |
| 440 | +*/ | |
| 441 | + | |
| 442 | +int | |
| 443 | +PyCode_Addr2Line(PyCodeObject *co, int addrq) | |
| 444 | +{ | |
| 445 | + int size = PyString_Size(co->co_lnotab) / 2; | |
| 446 | + unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab); | |
| 447 | + int line = co->co_firstlineno; | |
| 448 | + int addr = 0; | |
| 449 | + while (--size >= 0) { | |
| 450 | + addr += *p++; | |
| 451 | + if (addr > addrq) | |
| 452 | + break; | |
| 453 | + line += *p++; | |
| 454 | + } | |
| 455 | + return line; | |
| 456 | +} | |
| 457 | + | |
| 458 | +/* | |
| 459 | + Check whether the current instruction is at the start of a line. | |
| 460 | + | |
| 461 | + */ | |
| 462 | + | |
| 463 | + /* The theory of SET_LINENO-less tracing. | |
| 464 | + | |
| 465 | + In a nutshell, we use the co_lnotab field of the code object | |
| 466 | + to tell when execution has moved onto a different line. | |
| 467 | + | |
| 468 | + As mentioned above, the basic idea is so set things up so | |
| 469 | + that | |
| 470 | + | |
| 471 | + *instr_lb <= frame->f_lasti < *instr_ub | |
| 472 | + | |
| 473 | + is true so long as execution does not change lines. | |
| 474 | + | |
| 475 | + This is all fairly simple. Digging the information out of | |
| 476 | + co_lnotab takes some work, but is conceptually clear. | |
| 477 | + | |
| 478 | + Somewhat harder to explain is why we don't *always* call the | |
| 479 | + line trace function when the above test fails. | |
| 480 | + | |
| 481 | + Consider this code: | |
| 482 | + | |
| 483 | + 1: def f(a): | |
| 484 | + 2: if a: | |
| 485 | + 3: print 1 | |
| 486 | + 4: else: | |
| 487 | + 5: print 2 | |
| 488 | + | |
| 489 | + which compiles to this: | |
| 490 | + | |
| 491 | + 2 0 LOAD_FAST 0 (a) | |
| 492 | + 3 JUMP_IF_FALSE 9 (to 15) | |
| 493 | + 6 POP_TOP | |
| 494 | + | |
| 495 | + 3 7 LOAD_CONST 1 (1) | |
| 496 | + 10 PRINT_ITEM | |
| 497 | + 11 PRINT_NEWLINE | |
| 498 | + 12 JUMP_FORWARD 6 (to 21) | |
| 499 | + >> 15 POP_TOP | |
| 500 | + | |
| 501 | + 5 16 LOAD_CONST 2 (2) | |
| 502 | + 19 PRINT_ITEM | |
| 503 | + 20 PRINT_NEWLINE | |
| 504 | + >> 21 LOAD_CONST 0 (None) | |
| 505 | + 24 RETURN_VALUE | |
| 506 | + | |
| 507 | + If 'a' is false, execution will jump to instruction at offset | |
| 508 | + 15 and the co_lnotab will claim that execution has moved to | |
| 509 | + line 3. This is at best misleading. In this case we could | |
| 510 | + associate the POP_TOP with line 4, but that doesn't make | |
| 511 | + sense in all cases (I think). | |
| 512 | + | |
| 513 | + What we do is only call the line trace function if the co_lnotab | |
| 514 | + indicates we have jumped to the *start* of a line, i.e. if the | |
| 515 | + current instruction offset matches the offset given for the | |
| 516 | + start of a line by the co_lnotab. | |
| 517 | + | |
| 518 | + This also takes care of the situation where 'a' is true. | |
| 519 | + Execution will jump from instruction offset 12 to offset 21. | |
| 520 | + Then the co_lnotab would imply that execution has moved to line | |
| 521 | + 5, which is again misleading. | |
| 522 | + | |
| 523 | + Why do we set f_lineno when tracing? Well, consider the code | |
| 524 | + above when 'a' is true. If stepping through this with 'n' in | |
| 525 | + pdb, you would stop at line 1 with a "call" type event, then | |
| 526 | + line events on lines 2 and 3, then a "return" type event -- but | |
| 527 | + you would be shown line 5 during this event. This is a change | |
| 528 | + from the behaviour in 2.2 and before, and I've found it | |
| 529 | + confusing in practice. By setting and using f_lineno when | |
| 530 | + tracing, one can report a line number different from that | |
| 531 | + suggested by f_lasti on this one occasion where it's desirable. | |
| 532 | + */ | |
| 533 | + | |
| 534 | + | |
| 535 | +int | |
| 536 | +PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) | |
| 537 | +{ | |
| 538 | + int size, addr, line; | |
| 539 | + unsigned char* p; | |
| 540 | + | |
| 541 | + p = (unsigned char*)PyString_AS_STRING(co->co_lnotab); | |
| 542 | + size = PyString_GET_SIZE(co->co_lnotab) / 2; | |
| 543 | + | |
| 544 | + addr = 0; | |
| 545 | + line = co->co_firstlineno; | |
| 546 | + assert(line > 0); | |
| 547 | + | |
| 548 | + /* possible optimization: if f->f_lasti == instr_ub | |
| 549 | + (likely to be a common case) then we already know | |
| 550 | + instr_lb -- if we stored the matching value of p | |
| 551 | + somwhere we could skip the first while loop. */ | |
| 552 | + | |
| 553 | + /* see comments in compile.c for the description of | |
| 554 | + co_lnotab. A point to remember: increments to p | |
| 555 | + should come in pairs -- although we don't care about | |
| 556 | + the line increments here, treating them as byte | |
| 557 | + increments gets confusing, to say the least. */ | |
| 558 | + | |
| 559 | + bounds->ap_lower = 0; | |
| 560 | + while (size > 0) { | |
| 561 | + if (addr + *p > lasti) | |
| 562 | + break; | |
| 563 | + addr += *p++; | |
| 564 | + if (*p) | |
| 565 | + bounds->ap_lower = addr; | |
| 566 | + line += *p++; | |
| 567 | + --size; | |
| 568 | + } | |
| 569 | + | |
| 570 | + /* If lasti and addr don't match exactly, we don't want to | |
| 571 | + change the lineno slot on the frame or execute a trace | |
| 572 | + function. Return -1 instead. | |
| 573 | + */ | |
| 574 | + if (addr != lasti) | |
| 575 | + line = -1; | |
| 576 | + | |
| 577 | + if (size > 0) { | |
| 578 | + while (--size >= 0) { | |
| 579 | + addr += *p++; | |
| 580 | + if (*p++) | |
| 581 | + break; | |
| 582 | + } | |
| 583 | + bounds->ap_upper = addr; | |
| 584 | + } | |
| 585 | + else { | |
| 586 | + bounds->ap_upper = INT_MAX; | |
| 587 | + } | |
| 588 | + | |
| 589 | + return line; | |
| 590 | +} | |
| @@ -0,0 +1,1031 @@ | ||
| 1 | + | |
| 2 | +/* Complex object implementation */ | |
| 3 | + | |
| 4 | +/* Borrows heavily from floatobject.c */ | |
| 5 | + | |
| 6 | +/* Submitted by Jim Hugunin */ | |
| 7 | + | |
| 8 | +#include "Python.h" | |
| 9 | +#include "structmember.h" | |
| 10 | + | |
| 11 | +#ifndef WITHOUT_COMPLEX | |
| 12 | + | |
| 13 | +/* Precisions used by repr() and str(), respectively. | |
| 14 | + | |
| 15 | + The repr() precision (17 significant decimal digits) is the minimal number | |
| 16 | + that is guaranteed to have enough precision so that if the number is read | |
| 17 | + back in the exact same binary value is recreated. This is true for IEEE | |
| 18 | + floating point by design, and also happens to work for all other modern | |
| 19 | + hardware. | |
| 20 | + | |
| 21 | + The str() precision is chosen so that in most cases, the rounding noise | |
| 22 | + created by various operations is suppressed, while giving plenty of | |
| 23 | + precision for practical use. | |
| 24 | +*/ | |
| 25 | + | |
| 26 | +#define PREC_REPR 17 | |
| 27 | +#define PREC_STR 12 | |
| 28 | + | |
| 29 | +/* elementary operations on complex numbers */ | |
| 30 | + | |
| 31 | +static Py_complex c_1 = {1., 0.}; | |
| 32 | + | |
| 33 | +Py_complex | |
| 34 | +c_sum(Py_complex a, Py_complex b) | |
| 35 | +{ | |
| 36 | + Py_complex r; | |
| 37 | + r.real = a.real + b.real; | |
| 38 | + r.imag = a.imag + b.imag; | |
| 39 | + return r; | |
| 40 | +} | |
| 41 | + | |
| 42 | +Py_complex | |
| 43 | +c_diff(Py_complex a, Py_complex b) | |
| 44 | +{ | |
| 45 | + Py_complex r; | |
| 46 | + r.real = a.real - b.real; | |
| 47 | + r.imag = a.imag - b.imag; | |
| 48 | + return r; | |
| 49 | +} | |
| 50 | + | |
| 51 | +Py_complex | |
| 52 | +c_neg(Py_complex a) | |
| 53 | +{ | |
| 54 | + Py_complex r; | |
| 55 | + r.real = -a.real; | |
| 56 | + r.imag = -a.imag; | |
| 57 | + return r; | |
| 58 | +} | |
| 59 | + | |
| 60 | +Py_complex | |
| 61 | +c_prod(Py_complex a, Py_complex b) | |
| 62 | +{ | |
| 63 | + Py_complex r; | |
| 64 | + r.real = a.real*b.real - a.imag*b.imag; | |
| 65 | + r.imag = a.real*b.imag + a.imag*b.real; | |
| 66 | + return r; | |
| 67 | +} | |
| 68 | + | |
| 69 | +Py_complex | |
| 70 | +c_quot(Py_complex a, Py_complex b) | |
| 71 | +{ | |
| 72 | + /****************************************************************** | |
| 73 | + This was the original algorithm. It's grossly prone to spurious | |
| 74 | + overflow and underflow errors. It also merrily divides by 0 despite | |
| 75 | + checking for that(!). The code still serves a doc purpose here, as | |
| 76 | + the algorithm following is a simple by-cases transformation of this | |
| 77 | + one: | |
| 78 | + | |
| 79 | + Py_complex r; | |
| 80 | + double d = b.real*b.real + b.imag*b.imag; | |
| 81 | + if (d == 0.) | |
| 82 | + errno = EDOM; | |
| 83 | + r.real = (a.real*b.real + a.imag*b.imag)/d; | |
| 84 | + r.imag = (a.imag*b.real - a.real*b.imag)/d; | |
| 85 | + return r; | |
| 86 | + ******************************************************************/ | |
| 87 | + | |
| 88 | + /* This algorithm is better, and is pretty obvious: first divide the | |
| 89 | + * numerators and denominator by whichever of {b.real, b.imag} has | |
| 90 | + * larger magnitude. The earliest reference I found was to CACM | |
| 91 | + * Algorithm 116 (Complex Division, Robert L. Smith, Stanford | |
| 92 | + * University). As usual, though, we're still ignoring all IEEE | |
| 93 | + * endcases. | |
| 94 | + */ | |
| 95 | + Py_complex r; /* the result */ | |
| 96 | + const double abs_breal = b.real < 0 ? -b.real : b.real; | |
| 97 | + const double abs_bimag = b.imag < 0 ? -b.imag : b.imag; | |
| 98 | + | |
| 99 | + if (abs_breal >= abs_bimag) { | |
| 100 | + /* divide tops and bottom by b.real */ | |
| 101 | + if (abs_breal == 0.0) { | |
| 102 | + errno = EDOM; | |
| 103 | + r.real = r.imag = 0.0; | |
| 104 | + } | |
| 105 | + else { | |
| 106 | + const double ratio = b.imag / b.real; | |
| 107 | + const double denom = b.real + b.imag * ratio; | |
| 108 | + r.real = (a.real + a.imag * ratio) / denom; | |
| 109 | + r.imag = (a.imag - a.real * ratio) / denom; | |
| 110 | + } | |
| 111 | + } | |
| 112 | + else { | |
| 113 | + /* divide tops and bottom by b.imag */ | |
| 114 | + const double ratio = b.real / b.imag; | |
| 115 | + const double denom = b.real * ratio + b.imag; | |
| 116 | + assert(b.imag != 0.0); | |
| 117 | + r.real = (a.real * ratio + a.imag) / denom; | |
| 118 | + r.imag = (a.imag * ratio - a.real) / denom; | |
| 119 | + } | |
| 120 | + return r; | |
| 121 | +} | |
| 122 | + | |
| 123 | +Py_complex | |
| 124 | +c_pow(Py_complex a, Py_complex b) | |
| 125 | +{ | |
| 126 | + Py_complex r; | |
| 127 | + double vabs,len,at,phase; | |
| 128 | + if (b.real == 0. && b.imag == 0.) { | |
| 129 | + r.real = 1.; | |
| 130 | + r.imag = 0.; | |
| 131 | + } | |
| 132 | + else if (a.real == 0. && a.imag == 0.) { | |
| 133 | + if (b.imag != 0. || b.real < 0.) | |
| 134 | + errno = EDOM; | |
| 135 | + r.real = 0.; | |
| 136 | + r.imag = 0.; | |
| 137 | + } | |
| 138 | + else { | |
| 139 | + vabs = hypot(a.real,a.imag); | |
| 140 | + len = pow(vabs,b.real); | |
| 141 | + at = atan2(a.imag, a.real); | |
| 142 | + phase = at*b.real; | |
| 143 | + if (b.imag != 0.0) { | |
| 144 | + len /= exp(at*b.imag); | |
| 145 | + phase += b.imag*log(vabs); | |
| 146 | + } | |
| 147 | + r.real = len*cos(phase); | |
| 148 | + r.imag = len*sin(phase); | |
| 149 | + } | |
| 150 | + return r; | |
| 151 | +} | |
| 152 | + | |
| 153 | +static Py_complex | |
| 154 | +c_powu(Py_complex x, long n) | |
| 155 | +{ | |
| 156 | + Py_complex r, p; | |
| 157 | + long mask = 1; | |
| 158 | + r = c_1; | |
| 159 | + p = x; | |
| 160 | + while (mask > 0 && n >= mask) { | |
| 161 | + if (n & mask) | |
| 162 | + r = c_prod(r,p); | |
| 163 | + mask <<= 1; | |
| 164 | + p = c_prod(p,p); | |
| 165 | + } | |
| 166 | + return r; | |
| 167 | +} | |
| 168 | + | |
| 169 | +static Py_complex | |
| 170 | +c_powi(Py_complex x, long n) | |
| 171 | +{ | |
| 172 | + Py_complex cn; | |
| 173 | + | |
| 174 | + if (n > 100 || n < -100) { | |
| 175 | + cn.real = (double) n; | |
| 176 | + cn.imag = 0.; | |
| 177 | + return c_pow(x,cn); | |
| 178 | + } | |
| 179 | + else if (n > 0) | |
| 180 | + return c_powu(x,n); | |
| 181 | + else | |
| 182 | + return c_quot(c_1,c_powu(x,-n)); | |
| 183 | + | |
| 184 | +} | |
| 185 | + | |
| 186 | +static PyObject * | |
| 187 | +complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval) | |
| 188 | +{ | |
| 189 | + PyObject *op; | |
| 190 | + | |
| 191 | + op = type->tp_alloc(type, 0); | |
| 192 | + if (op != NULL) | |
| 193 | + ((PyComplexObject *)op)->cval = cval; | |
| 194 | + return op; | |
| 195 | +} | |
| 196 | + | |
| 197 | +PyObject * | |
| 198 | +PyComplex_FromCComplex(Py_complex cval) | |
| 199 | +{ | |
| 200 | + register PyComplexObject *op; | |
| 201 | + | |
| 202 | + /* Inline PyObject_New */ | |
| 203 | + op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject)); | |
| 204 | + if (op == NULL) | |
| 205 | + return PyErr_NoMemory(); | |
| 206 | + PyObject_INIT(op, &PyComplex_Type); | |
| 207 | + op->cval = cval; | |
| 208 | + return (PyObject *) op; | |
| 209 | +} | |
| 210 | + | |
| 211 | +static PyObject * | |
| 212 | +complex_subtype_from_doubles(PyTypeObject *type, double real, double imag) | |
| 213 | +{ | |
| 214 | + Py_complex c; | |
| 215 | + c.real = real; | |
| 216 | + c.imag = imag; | |
| 217 | + return complex_subtype_from_c_complex(type, c); | |
| 218 | +} | |
| 219 | + | |
| 220 | +PyObject * | |
| 221 | +PyComplex_FromDoubles(double real, double imag) | |
| 222 | +{ | |
| 223 | + Py_complex c; | |
| 224 | + c.real = real; | |
| 225 | + c.imag = imag; | |
| 226 | + return PyComplex_FromCComplex(c); | |
| 227 | +} | |
| 228 | + | |
| 229 | +double | |
| 230 | +PyComplex_RealAsDouble(PyObject *op) | |
| 231 | +{ | |
| 232 | + if (PyComplex_Check(op)) { | |
| 233 | + return ((PyComplexObject *)op)->cval.real; | |
| 234 | + } | |
| 235 | + else { | |
| 236 | + return PyFloat_AsDouble(op); | |
| 237 | + } | |
| 238 | +} | |
| 239 | + | |
| 240 | +double | |
| 241 | +PyComplex_ImagAsDouble(PyObject *op) | |
| 242 | +{ | |
| 243 | + if (PyComplex_Check(op)) { | |
| 244 | + return ((PyComplexObject *)op)->cval.imag; | |
| 245 | + } | |
| 246 | + else { | |
| 247 | + return 0.0; | |
| 248 | + } | |
| 249 | +} | |
| 250 | + | |
| 251 | +Py_complex | |
| 252 | +PyComplex_AsCComplex(PyObject *op) | |
| 253 | +{ | |
| 254 | + Py_complex cv; | |
| 255 | + if (PyComplex_Check(op)) { | |
| 256 | + return ((PyComplexObject *)op)->cval; | |
| 257 | + } | |
| 258 | + else { | |
| 259 | + cv.real = PyFloat_AsDouble(op); | |
| 260 | + cv.imag = 0.; | |
| 261 | + return cv; | |
| 262 | + } | |
| 263 | +} | |
| 264 | + | |
| 265 | +static void | |
| 266 | +complex_dealloc(PyObject *op) | |
| 267 | +{ | |
| 268 | + op->ob_type->tp_free(op); | |
| 269 | +} | |
| 270 | + | |
| 271 | + | |
| 272 | +static void | |
| 273 | +complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision) | |
| 274 | +{ | |
| 275 | + char format[32]; | |
| 276 | + if (v->cval.real == 0.) { | |
| 277 | + PyOS_snprintf(format, sizeof(format), "%%.%ig", precision); | |
| 278 | + PyOS_ascii_formatd(buf, bufsz - 1, format, v->cval.imag); | |
| 279 | + strncat(buf, "j", 1); | |
| 280 | + } else { | |
| 281 | + char re[64], im[64]; | |
| 282 | + /* Format imaginary part with sign, real part without */ | |
| 283 | + PyOS_snprintf(format, sizeof(format), "%%.%ig", precision); | |
| 284 | + PyOS_ascii_formatd(re, sizeof(re), format, v->cval.real); | |
| 285 | + PyOS_snprintf(format, sizeof(format), "%%+.%ig", precision); | |
| 286 | + PyOS_ascii_formatd(im, sizeof(im), format, v->cval.imag); | |
| 287 | + PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im); | |
| 288 | + } | |
| 289 | +} | |
| 290 | + | |
| 291 | +static int | |
| 292 | +complex_print(PyComplexObject *v, FILE *fp, int flags) | |
| 293 | +{ | |
| 294 | + char buf[100]; | |
| 295 | + complex_to_buf(buf, sizeof(buf), v, | |
| 296 | + (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR); | |
| 297 | + fputs(buf, fp); | |
| 298 | + return 0; | |
| 299 | +} | |
| 300 | + | |
| 301 | +static PyObject * | |
| 302 | +complex_repr(PyComplexObject *v) | |
| 303 | +{ | |
| 304 | + char buf[100]; | |
| 305 | + complex_to_buf(buf, sizeof(buf), v, PREC_REPR); | |
| 306 | + return PyString_FromString(buf); | |
| 307 | +} | |
| 308 | + | |
| 309 | +static PyObject * | |
| 310 | +complex_str(PyComplexObject *v) | |
| 311 | +{ | |
| 312 | + char buf[100]; | |
| 313 | + complex_to_buf(buf, sizeof(buf), v, PREC_STR); | |
| 314 | + return PyString_FromString(buf); | |
| 315 | +} | |
| 316 | + | |
| 317 | +static long | |
| 318 | +complex_hash(PyComplexObject *v) | |
| 319 | +{ | |
| 320 | + long hashreal, hashimag, combined; | |
| 321 | + hashreal = _Py_HashDouble(v->cval.real); | |
| 322 | + if (hashreal == -1) | |
| 323 | + return -1; | |
| 324 | + hashimag = _Py_HashDouble(v->cval.imag); | |
| 325 | + if (hashimag == -1) | |
| 326 | + return -1; | |
| 327 | + /* Note: if the imaginary part is 0, hashimag is 0 now, | |
| 328 | + * so the following returns hashreal unchanged. This is | |
| 329 | + * important because numbers of different types that | |
| 330 | + * compare equal must have the same hash value, so that | |
| 331 | + * hash(x + 0*j) must equal hash(x). | |
| 332 | + */ | |
| 333 | + combined = hashreal + 1000003 * hashimag; | |
| 334 | + if (combined == -1) | |
| 335 | + combined = -2; | |
| 336 | + return combined; | |
| 337 | +} | |
| 338 | + | |
| 339 | +static PyObject * | |
| 340 | +complex_add(PyComplexObject *v, PyComplexObject *w) | |
| 341 | +{ | |
| 342 | + Py_complex result; | |
| 343 | + PyFPE_START_PROTECT("complex_add", return 0) | |
| 344 | + result = c_sum(v->cval,w->cval); | |
| 345 | + PyFPE_END_PROTECT(result) | |
| 346 | + return PyComplex_FromCComplex(result); | |
| 347 | +} | |
| 348 | + | |
| 349 | +static PyObject * | |
| 350 | +complex_sub(PyComplexObject *v, PyComplexObject *w) | |
| 351 | +{ | |
| 352 | + Py_complex result; | |
| 353 | + PyFPE_START_PROTECT("complex_sub", return 0) | |
| 354 | + result = c_diff(v->cval,w->cval); | |
| 355 | + PyFPE_END_PROTECT(result) | |
| 356 | + return PyComplex_FromCComplex(result); | |
| 357 | +} | |
| 358 | + | |
| 359 | +static PyObject * | |
| 360 | +complex_mul(PyComplexObject *v, PyComplexObject *w) | |
| 361 | +{ | |
| 362 | + Py_complex result; | |
| 363 | + PyFPE_START_PROTECT("complex_mul", return 0) | |
| 364 | + result = c_prod(v->cval,w->cval); | |
| 365 | + PyFPE_END_PROTECT(result) | |
| 366 | + return PyComplex_FromCComplex(result); | |
| 367 | +} | |
| 368 | + | |
| 369 | +static PyObject * | |
| 370 | +complex_div(PyComplexObject *v, PyComplexObject *w) | |
| 371 | +{ | |
| 372 | + Py_complex quot; | |
| 373 | + PyFPE_START_PROTECT("complex_div", return 0) | |
| 374 | + errno = 0; | |
| 375 | + quot = c_quot(v->cval,w->cval); | |
| 376 | + PyFPE_END_PROTECT(quot) | |
| 377 | + if (errno == EDOM) { | |
| 378 | + PyErr_SetString(PyExc_ZeroDivisionError, "complex division"); | |
| 379 | + return NULL; | |
| 380 | + } | |
| 381 | + return PyComplex_FromCComplex(quot); | |
| 382 | +} | |
| 383 | + | |
| 384 | +static PyObject * | |
| 385 | +complex_classic_div(PyComplexObject *v, PyComplexObject *w) | |
| 386 | +{ | |
| 387 | + Py_complex quot; | |
| 388 | + | |
| 389 | + if (Py_DivisionWarningFlag >= 2 && | |
| 390 | + PyErr_Warn(PyExc_DeprecationWarning, | |
| 391 | + "classic complex division") < 0) | |
| 392 | + return NULL; | |
| 393 | + | |
| 394 | + PyFPE_START_PROTECT("complex_classic_div", return 0) | |
| 395 | + errno = 0; | |
| 396 | + quot = c_quot(v->cval,w->cval); | |
| 397 | + PyFPE_END_PROTECT(quot) | |
| 398 | + if (errno == EDOM) { | |
| 399 | + PyErr_SetString(PyExc_ZeroDivisionError, "complex division"); | |
| 400 | + return NULL; | |
| 401 | + } | |
| 402 | + return PyComplex_FromCComplex(quot); | |
| 403 | +} | |
| 404 | + | |
| 405 | +static PyObject * | |
| 406 | +complex_remainder(PyComplexObject *v, PyComplexObject *w) | |
| 407 | +{ | |
| 408 | + Py_complex div, mod; | |
| 409 | + | |
| 410 | + if (PyErr_Warn(PyExc_DeprecationWarning, | |
| 411 | + "complex divmod(), // and % are deprecated") < 0) | |
| 412 | + return NULL; | |
| 413 | + | |
| 414 | + errno = 0; | |
| 415 | + div = c_quot(v->cval,w->cval); /* The raw divisor value. */ | |
| 416 | + if (errno == EDOM) { | |
| 417 | + PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder"); | |
| 418 | + return NULL; | |
| 419 | + } | |
| 420 | + div.real = floor(div.real); /* Use the floor of the real part. */ | |
| 421 | + div.imag = 0.0; | |
| 422 | + mod = c_diff(v->cval, c_prod(w->cval, div)); | |
| 423 | + | |
| 424 | + return PyComplex_FromCComplex(mod); | |
| 425 | +} | |
| 426 | + | |
| 427 | + | |
| 428 | +static PyObject * | |
| 429 | +complex_divmod(PyComplexObject *v, PyComplexObject *w) | |
| 430 | +{ | |
| 431 | + Py_complex div, mod; | |
| 432 | + PyObject *d, *m, *z; | |
| 433 | + | |
| 434 | + if (PyErr_Warn(PyExc_DeprecationWarning, | |
| 435 | + "complex divmod(), // and % are deprecated") < 0) | |
| 436 | + return NULL; | |
| 437 | + | |
| 438 | + errno = 0; | |
| 439 | + div = c_quot(v->cval,w->cval); /* The raw divisor value. */ | |
| 440 | + if (errno == EDOM) { | |
| 441 | + PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()"); | |
| 442 | + return NULL; | |
| 443 | + } | |
| 444 | + div.real = floor(div.real); /* Use the floor of the real part. */ | |
| 445 | + div.imag = 0.0; | |
| 446 | + mod = c_diff(v->cval, c_prod(w->cval, div)); | |
| 447 | + d = PyComplex_FromCComplex(div); | |
| 448 | + m = PyComplex_FromCComplex(mod); | |
| 449 | + z = PyTuple_Pack(2, d, m); | |
| 450 | + Py_XDECREF(d); | |
| 451 | + Py_XDECREF(m); | |
| 452 | + return z; | |
| 453 | +} | |
| 454 | + | |
| 455 | +static PyObject * | |
| 456 | +complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z) | |
| 457 | +{ | |
| 458 | + Py_complex p; | |
| 459 | + Py_complex exponent; | |
| 460 | + long int_exponent; | |
| 461 | + | |
| 462 | + if ((PyObject *)z!=Py_None) { | |
| 463 | + PyErr_SetString(PyExc_ValueError, "complex modulo"); | |
| 464 | + return NULL; | |
| 465 | + } | |
| 466 | + PyFPE_START_PROTECT("complex_pow", return 0) | |
| 467 | + errno = 0; | |
| 468 | + exponent = ((PyComplexObject*)w)->cval; | |
| 469 | + int_exponent = (long)exponent.real; | |
| 470 | + if (exponent.imag == 0. && exponent.real == int_exponent) | |
| 471 | + p = c_powi(v->cval,int_exponent); | |
| 472 | + else | |
| 473 | + p = c_pow(v->cval,exponent); | |
| 474 | + | |
| 475 | + PyFPE_END_PROTECT(p) | |
| 476 | + Py_ADJUST_ERANGE2(p.real, p.imag); | |
| 477 | + if (errno == EDOM) { | |
| 478 | + PyErr_SetString(PyExc_ZeroDivisionError, | |
| 479 | + "0.0 to a negative or complex power"); | |
| 480 | + return NULL; | |
| 481 | + } | |
| 482 | + else if (errno == ERANGE) { | |
| 483 | + PyErr_SetString(PyExc_OverflowError, | |
| 484 | + "complex exponentiation"); | |
| 485 | + return NULL; | |
| 486 | + } | |
| 487 | + return PyComplex_FromCComplex(p); | |
| 488 | +} | |
| 489 | + | |
| 490 | +static PyObject * | |
| 491 | +complex_int_div(PyComplexObject *v, PyComplexObject *w) | |
| 492 | +{ | |
| 493 | + PyObject *t, *r; | |
| 494 | + | |
| 495 | + t = complex_divmod(v, w); | |
| 496 | + if (t != NULL) { | |
| 497 | + r = PyTuple_GET_ITEM(t, 0); | |
| 498 | + Py_INCREF(r); | |
| 499 | + Py_DECREF(t); | |
| 500 | + return r; | |
| 501 | + } | |
| 502 | + return NULL; | |
| 503 | +} | |
| 504 | + | |
| 505 | +static PyObject * | |
| 506 | +complex_neg(PyComplexObject *v) | |
| 507 | +{ | |
| 508 | + Py_complex neg; | |
| 509 | + neg.real = -v->cval.real; | |
| 510 | + neg.imag = -v->cval.imag; | |
| 511 | + return PyComplex_FromCComplex(neg); | |
| 512 | +} | |
| 513 | + | |
| 514 | +static PyObject * | |
| 515 | +complex_pos(PyComplexObject *v) | |
| 516 | +{ | |
| 517 | + if (PyComplex_CheckExact(v)) { | |
| 518 | + Py_INCREF(v); | |
| 519 | + return (PyObject *)v; | |
| 520 | + } | |
| 521 | + else | |
| 522 | + return PyComplex_FromCComplex(v->cval); | |
| 523 | +} | |
| 524 | + | |
| 525 | +static PyObject * | |
| 526 | +complex_abs(PyComplexObject *v) | |
| 527 | +{ | |
| 528 | + double result; | |
| 529 | + PyFPE_START_PROTECT("complex_abs", return 0) | |
| 530 | + result = hypot(v->cval.real,v->cval.imag); | |
| 531 | + PyFPE_END_PROTECT(result) | |
| 532 | + return PyFloat_FromDouble(result); | |
| 533 | +} | |
| 534 | + | |
| 535 | +static int | |
| 536 | +complex_nonzero(PyComplexObject *v) | |
| 537 | +{ | |
| 538 | + return v->cval.real != 0.0 || v->cval.imag != 0.0; | |
| 539 | +} | |
| 540 | + | |
| 541 | +static int | |
| 542 | +complex_coerce(PyObject **pv, PyObject **pw) | |
| 543 | +{ | |
| 544 | + Py_complex cval; | |
| 545 | + cval.imag = 0.; | |
| 546 | + if (PyInt_Check(*pw)) { | |
| 547 | + cval.real = (double)PyInt_AsLong(*pw); | |
| 548 | + *pw = PyComplex_FromCComplex(cval); | |
| 549 | + Py_INCREF(*pv); | |
| 550 | + return 0; | |
| 551 | + } | |
| 552 | + else if (PyLong_Check(*pw)) { | |
| 553 | + cval.real = PyLong_AsDouble(*pw); | |
| 554 | + if (cval.real == -1.0 && PyErr_Occurred()) | |
| 555 | + return -1; | |
| 556 | + *pw = PyComplex_FromCComplex(cval); | |
| 557 | + Py_INCREF(*pv); | |
| 558 | + return 0; | |
| 559 | + } | |
| 560 | + else if (PyFloat_Check(*pw)) { | |
| 561 | + cval.real = PyFloat_AsDouble(*pw); | |
| 562 | + *pw = PyComplex_FromCComplex(cval); | |
| 563 | + Py_INCREF(*pv); | |
| 564 | + return 0; | |
| 565 | + } | |
| 566 | + else if (PyComplex_Check(*pw)) { | |
| 567 | + Py_INCREF(*pv); | |
| 568 | + Py_INCREF(*pw); | |
| 569 | + return 0; | |
| 570 | + } | |
| 571 | + return 1; /* Can't do it */ | |
| 572 | +} | |
| 573 | + | |
| 574 | +static PyObject * | |
| 575 | +complex_richcompare(PyObject *v, PyObject *w, int op) | |
| 576 | +{ | |
| 577 | + int c; | |
| 578 | + Py_complex i, j; | |
| 579 | + PyObject *res; | |
| 580 | + | |
| 581 | + c = PyNumber_CoerceEx(&v, &w); | |
| 582 | + if (c < 0) | |
| 583 | + return NULL; | |
| 584 | + if (c > 0) { | |
| 585 | + Py_INCREF(Py_NotImplemented); | |
| 586 | + return Py_NotImplemented; | |
| 587 | + } | |
| 588 | + /* Make sure both arguments are complex. */ | |
| 589 | + if (!(PyComplex_Check(v) && PyComplex_Check(w))) { | |
| 590 | + Py_DECREF(v); | |
| 591 | + Py_DECREF(w); | |
| 592 | + Py_INCREF(Py_NotImplemented); | |
| 593 | + return Py_NotImplemented; | |
| 594 | + } | |
| 595 | + | |
| 596 | + i = ((PyComplexObject *)v)->cval; | |
| 597 | + j = ((PyComplexObject *)w)->cval; | |
| 598 | + Py_DECREF(v); | |
| 599 | + Py_DECREF(w); | |
| 600 | + | |
| 601 | + if (op != Py_EQ && op != Py_NE) { | |
| 602 | + PyErr_SetString(PyExc_TypeError, | |
| 603 | + "no ordering relation is defined for complex numbers"); | |
| 604 | + return NULL; | |
| 605 | + } | |
| 606 | + | |
| 607 | + if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ)) | |
| 608 | + res = Py_True; | |
| 609 | + else | |
| 610 | + res = Py_False; | |
| 611 | + | |
| 612 | + Py_INCREF(res); | |
| 613 | + return res; | |
| 614 | +} | |
| 615 | + | |
| 616 | +static PyObject * | |
| 617 | +complex_int(PyObject *v) | |
| 618 | +{ | |
| 619 | + PyErr_SetString(PyExc_TypeError, | |
| 620 | + "can't convert complex to int; use int(abs(z))"); | |
| 621 | + return NULL; | |
| 622 | +} | |
| 623 | + | |
| 624 | +static PyObject * | |
| 625 | +complex_long(PyObject *v) | |
| 626 | +{ | |
| 627 | + PyErr_SetString(PyExc_TypeError, | |
| 628 | + "can't convert complex to long; use long(abs(z))"); | |
| 629 | + return NULL; | |
| 630 | +} | |
| 631 | + | |
| 632 | +static PyObject * | |
| 633 | +complex_float(PyObject *v) | |
| 634 | +{ | |
| 635 | + PyErr_SetString(PyExc_TypeError, | |
| 636 | + "can't convert complex to float; use abs(z)"); | |
| 637 | + return NULL; | |
| 638 | +} | |
| 639 | + | |
| 640 | +static PyObject * | |
| 641 | +complex_conjugate(PyObject *self) | |
| 642 | +{ | |
| 643 | + Py_complex c; | |
| 644 | + c = ((PyComplexObject *)self)->cval; | |
| 645 | + c.imag = -c.imag; | |
| 646 | + return PyComplex_FromCComplex(c); | |
| 647 | +} | |
| 648 | + | |
| 649 | +static PyObject * | |
| 650 | +complex_getnewargs(PyComplexObject *v) | |
| 651 | +{ | |
| 652 | + return Py_BuildValue("(D)", &v->cval); | |
| 653 | +} | |
| 654 | + | |
| 655 | +static PyMethodDef complex_methods[] = { | |
| 656 | + {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS}, | |
| 657 | + {"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS}, | |
| 658 | + {NULL, NULL} /* sentinel */ | |
| 659 | +}; | |
| 660 | + | |
| 661 | +static PyMemberDef complex_members[] = { | |
| 662 | + {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), READONLY, | |
| 663 | + "the real part of a complex number"}, | |
| 664 | + {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), READONLY, | |
| 665 | + "the imaginary part of a complex number"}, | |
| 666 | + {0}, | |
| 667 | +}; | |
| 668 | + | |
| 669 | +static PyObject * | |
| 670 | +complex_subtype_from_string(PyTypeObject *type, PyObject *v) | |
| 671 | +{ | |
| 672 | + const char *s, *start; | |
| 673 | + char *end; | |
| 674 | + double x=0.0, y=0.0, z; | |
| 675 | + int got_re=0, got_im=0, done=0; | |
| 676 | + int digit_or_dot; | |
| 677 | + int sw_error=0; | |
| 678 | + int sign; | |
| 679 | + char buffer[256]; /* For errors */ | |
| 680 | +#ifdef Py_USING_UNICODE | |
| 681 | + char s_buffer[256]; | |
| 682 | +#endif | |
| 683 | + Py_ssize_t len; | |
| 684 | + | |
| 685 | + if (PyString_Check(v)) { | |
| 686 | + s = PyString_AS_STRING(v); | |
| 687 | + len = PyString_GET_SIZE(v); | |
| 688 | + } | |
| 689 | +#ifdef Py_USING_UNICODE | |
| 690 | + else if (PyUnicode_Check(v)) { | |
| 691 | + if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) { | |
| 692 | + PyErr_SetString(PyExc_ValueError, | |
| 693 | + "complex() literal too large to convert"); | |
| 694 | + return NULL; | |
| 695 | + } | |
| 696 | + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), | |
| 697 | + PyUnicode_GET_SIZE(v), | |
| 698 | + s_buffer, | |
| 699 | + NULL)) | |
| 700 | + return NULL; | |
| 701 | + s = s_buffer; | |
| 702 | + len = strlen(s); | |
| 703 | + } | |
| 704 | +#endif | |
| 705 | + else if (PyObject_AsCharBuffer(v, &s, &len)) { | |
| 706 | + PyErr_SetString(PyExc_TypeError, | |
| 707 | + "complex() arg is not a string"); | |
| 708 | + return NULL; | |
| 709 | + } | |
| 710 | + | |
| 711 | + /* position on first nonblank */ | |
| 712 | + start = s; | |
| 713 | + while (*s && isspace(Py_CHARMASK(*s))) | |
| 714 | + s++; | |
| 715 | + if (s[0] == '\0') { | |
| 716 | + PyErr_SetString(PyExc_ValueError, | |
| 717 | + "complex() arg is an empty string"); | |
| 718 | + return NULL; | |
| 719 | + } | |
| 720 | + | |
| 721 | + z = -1.0; | |
| 722 | + sign = 1; | |
| 723 | + do { | |
| 724 | + | |
| 725 | + switch (*s) { | |
| 726 | + | |
| 727 | + case '\0': | |
| 728 | + if (s-start != len) { | |
| 729 | + PyErr_SetString( | |
| 730 | + PyExc_ValueError, | |
| 731 | + "complex() arg contains a null byte"); | |
| 732 | + return NULL; | |
| 733 | + } | |
| 734 | + if(!done) sw_error=1; | |
| 735 | + break; | |
| 736 | + | |
| 737 | + case '-': | |
| 738 | + sign = -1; | |
| 739 | + /* Fallthrough */ | |
| 740 | + case '+': | |
| 741 | + if (done) sw_error=1; | |
| 742 | + s++; | |
| 743 | + if ( *s=='\0'||*s=='+'||*s=='-' || | |
| 744 | + isspace(Py_CHARMASK(*s)) ) sw_error=1; | |
| 745 | + break; | |
| 746 | + | |
| 747 | + case 'J': | |
| 748 | + case 'j': | |
| 749 | + if (got_im || done) { | |
| 750 | + sw_error = 1; | |
| 751 | + break; | |
| 752 | + } | |
| 753 | + if (z<0.0) { | |
| 754 | + y=sign; | |
| 755 | + } | |
| 756 | + else{ | |
| 757 | + y=sign*z; | |
| 758 | + } | |
| 759 | + got_im=1; | |
| 760 | + s++; | |
| 761 | + if (*s!='+' && *s!='-' ) | |
| 762 | + done=1; | |
| 763 | + break; | |
| 764 | + | |
| 765 | + default: | |
| 766 | + if (isspace(Py_CHARMASK(*s))) { | |
| 767 | + while (*s && isspace(Py_CHARMASK(*s))) | |
| 768 | + s++; | |
| 769 | + if (s[0] != '\0') | |
| 770 | + sw_error=1; | |
| 771 | + else | |
| 772 | + done = 1; | |
| 773 | + break; | |
| 774 | + } | |
| 775 | + digit_or_dot = | |
| 776 | + (*s=='.' || isdigit(Py_CHARMASK(*s))); | |
| 777 | + if (done||!digit_or_dot) { | |
| 778 | + sw_error=1; | |
| 779 | + break; | |
| 780 | + } | |
| 781 | + errno = 0; | |
| 782 | + PyFPE_START_PROTECT("strtod", return 0) | |
| 783 | + z = PyOS_ascii_strtod(s, &end) ; | |
| 784 | + PyFPE_END_PROTECT(z) | |
| 785 | + if (errno != 0) { | |
| 786 | + PyOS_snprintf(buffer, sizeof(buffer), | |
| 787 | + "float() out of range: %.150s", s); | |
| 788 | + PyErr_SetString( | |
| 789 | + PyExc_ValueError, | |
| 790 | + buffer); | |
| 791 | + return NULL; | |
| 792 | + } | |
| 793 | + s=end; | |
| 794 | + if (*s=='J' || *s=='j') { | |
| 795 | + | |
| 796 | + break; | |
| 797 | + } | |
| 798 | + if (got_re) { | |
| 799 | + sw_error=1; | |
| 800 | + break; | |
| 801 | + } | |
| 802 | + | |
| 803 | + /* accept a real part */ | |
| 804 | + x=sign*z; | |
| 805 | + got_re=1; | |
| 806 | + if (got_im) done=1; | |
| 807 | + z = -1.0; | |
| 808 | + sign = 1; | |
| 809 | + break; | |
| 810 | + | |
| 811 | + } /* end of switch */ | |
| 812 | + | |
| 813 | + } while (s - start < len && !sw_error); | |
| 814 | + | |
| 815 | + if (sw_error) { | |
| 816 | + PyErr_SetString(PyExc_ValueError, | |
| 817 | + "complex() arg is a malformed string"); | |
| 818 | + return NULL; | |
| 819 | + } | |
| 820 | + | |
| 821 | + return complex_subtype_from_doubles(type, x, y); | |
| 822 | +} | |
| 823 | + | |
| 824 | +static PyObject * | |
| 825 | +complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 826 | +{ | |
| 827 | + PyObject *r, *i, *tmp, *f; | |
| 828 | + PyNumberMethods *nbr, *nbi = NULL; | |
| 829 | + Py_complex cr, ci; | |
| 830 | + int own_r = 0; | |
| 831 | + static PyObject *complexstr; | |
| 832 | + static char *kwlist[] = {"real", "imag", 0}; | |
| 833 | + | |
| 834 | + r = Py_False; | |
| 835 | + i = NULL; | |
| 836 | + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist, | |
| 837 | + &r, &i)) | |
| 838 | + return NULL; | |
| 839 | + | |
| 840 | + /* Special-case for single argument that is already complex */ | |
| 841 | + if (PyComplex_CheckExact(r) && i == NULL && | |
| 842 | + type == &PyComplex_Type) { | |
| 843 | + /* Note that we can't know whether it's safe to return | |
| 844 | + a complex *subclass* instance as-is, hence the restriction | |
| 845 | + to exact complexes here. */ | |
| 846 | + Py_INCREF(r); | |
| 847 | + return r; | |
| 848 | + } | |
| 849 | + if (PyString_Check(r) || PyUnicode_Check(r)) { | |
| 850 | + if (i != NULL) { | |
| 851 | + PyErr_SetString(PyExc_TypeError, | |
| 852 | + "complex() can't take second arg" | |
| 853 | + " if first is a string"); | |
| 854 | + return NULL; | |
| 855 | + } | |
| 856 | + return complex_subtype_from_string(type, r); | |
| 857 | + } | |
| 858 | + if (i != NULL && (PyString_Check(i) || PyUnicode_Check(i))) { | |
| 859 | + PyErr_SetString(PyExc_TypeError, | |
| 860 | + "complex() second arg can't be a string"); | |
| 861 | + return NULL; | |
| 862 | + } | |
| 863 | + | |
| 864 | + /* XXX Hack to support classes with __complex__ method */ | |
| 865 | + if (complexstr == NULL) { | |
| 866 | + complexstr = PyString_InternFromString("__complex__"); | |
| 867 | + if (complexstr == NULL) | |
| 868 | + return NULL; | |
| 869 | + } | |
| 870 | + f = PyObject_GetAttr(r, complexstr); | |
| 871 | + if (f == NULL) | |
| 872 | + PyErr_Clear(); | |
| 873 | + else { | |
| 874 | + PyObject *args = PyTuple_New(0); | |
| 875 | + if (args == NULL) | |
| 876 | + return NULL; | |
| 877 | + r = PyEval_CallObject(f, args); | |
| 878 | + Py_DECREF(args); | |
| 879 | + Py_DECREF(f); | |
| 880 | + if (r == NULL) | |
| 881 | + return NULL; | |
| 882 | + own_r = 1; | |
| 883 | + } | |
| 884 | + nbr = r->ob_type->tp_as_number; | |
| 885 | + if (i != NULL) | |
| 886 | + nbi = i->ob_type->tp_as_number; | |
| 887 | + if (nbr == NULL || nbr->nb_float == NULL || | |
| 888 | + ((i != NULL) && (nbi == NULL || nbi->nb_float == NULL))) { | |
| 889 | + PyErr_SetString(PyExc_TypeError, | |
| 890 | + "complex() argument must be a string or a number"); | |
| 891 | + if (own_r) { | |
| 892 | + Py_DECREF(r); | |
| 893 | + } | |
| 894 | + return NULL; | |
| 895 | + } | |
| 896 | + if (PyComplex_Check(r)) { | |
| 897 | + /* Note that if r is of a complex subtype, we're only | |
| 898 | + retaining its real & imag parts here, and the return | |
| 899 | + value is (properly) of the builtin complex type. */ | |
| 900 | + cr = ((PyComplexObject*)r)->cval; | |
| 901 | + if (own_r) { | |
| 902 | + Py_DECREF(r); | |
| 903 | + } | |
| 904 | + } | |
| 905 | + else { | |
| 906 | + tmp = PyNumber_Float(r); | |
| 907 | + if (own_r) { | |
| 908 | + Py_DECREF(r); | |
| 909 | + } | |
| 910 | + if (tmp == NULL) | |
| 911 | + return NULL; | |
| 912 | + if (!PyFloat_Check(tmp)) { | |
| 913 | + PyErr_SetString(PyExc_TypeError, | |
| 914 | + "float(r) didn't return a float"); | |
| 915 | + Py_DECREF(tmp); | |
| 916 | + return NULL; | |
| 917 | + } | |
| 918 | + cr.real = PyFloat_AsDouble(tmp); | |
| 919 | + Py_DECREF(tmp); | |
| 920 | + cr.imag = 0.0; | |
| 921 | + } | |
| 922 | + if (i == NULL) { | |
| 923 | + ci.real = 0.0; | |
| 924 | + ci.imag = 0.0; | |
| 925 | + } | |
| 926 | + else if (PyComplex_Check(i)) | |
| 927 | + ci = ((PyComplexObject*)i)->cval; | |
| 928 | + else { | |
| 929 | + tmp = (*nbi->nb_float)(i); | |
| 930 | + if (tmp == NULL) | |
| 931 | + return NULL; | |
| 932 | + ci.real = PyFloat_AsDouble(tmp); | |
| 933 | + Py_DECREF(tmp); | |
| 934 | + ci.imag = 0.; | |
| 935 | + } | |
| 936 | + cr.real -= ci.imag; | |
| 937 | + cr.imag += ci.real; | |
| 938 | + return complex_subtype_from_c_complex(type, cr); | |
| 939 | +} | |
| 940 | + | |
| 941 | +PyDoc_STRVAR(complex_doc, | |
| 942 | +"complex(real[, imag]) -> complex number\n" | |
| 943 | +"\n" | |
| 944 | +"Create a complex number from a real part and an optional imaginary part.\n" | |
| 945 | +"This is equivalent to (real + imag*1j) where imag defaults to 0."); | |
| 946 | + | |
| 947 | +static PyNumberMethods complex_as_number = { | |
| 948 | + (binaryfunc)complex_add, /* nb_add */ | |
| 949 | + (binaryfunc)complex_sub, /* nb_subtract */ | |
| 950 | + (binaryfunc)complex_mul, /* nb_multiply */ | |
| 951 | + (binaryfunc)complex_classic_div, /* nb_divide */ | |
| 952 | + (binaryfunc)complex_remainder, /* nb_remainder */ | |
| 953 | + (binaryfunc)complex_divmod, /* nb_divmod */ | |
| 954 | + (ternaryfunc)complex_pow, /* nb_power */ | |
| 955 | + (unaryfunc)complex_neg, /* nb_negative */ | |
| 956 | + (unaryfunc)complex_pos, /* nb_positive */ | |
| 957 | + (unaryfunc)complex_abs, /* nb_absolute */ | |
| 958 | + (inquiry)complex_nonzero, /* nb_nonzero */ | |
| 959 | + 0, /* nb_invert */ | |
| 960 | + 0, /* nb_lshift */ | |
| 961 | + 0, /* nb_rshift */ | |
| 962 | + 0, /* nb_and */ | |
| 963 | + 0, /* nb_xor */ | |
| 964 | + 0, /* nb_or */ | |
| 965 | + complex_coerce, /* nb_coerce */ | |
| 966 | + complex_int, /* nb_int */ | |
| 967 | + complex_long, /* nb_long */ | |
| 968 | + complex_float, /* nb_float */ | |
| 969 | + 0, /* nb_oct */ | |
| 970 | + 0, /* nb_hex */ | |
| 971 | + 0, /* nb_inplace_add */ | |
| 972 | + 0, /* nb_inplace_subtract */ | |
| 973 | + 0, /* nb_inplace_multiply*/ | |
| 974 | + 0, /* nb_inplace_divide */ | |
| 975 | + 0, /* nb_inplace_remainder */ | |
| 976 | + 0, /* nb_inplace_power */ | |
| 977 | + 0, /* nb_inplace_lshift */ | |
| 978 | + 0, /* nb_inplace_rshift */ | |
| 979 | + 0, /* nb_inplace_and */ | |
| 980 | + 0, /* nb_inplace_xor */ | |
| 981 | + 0, /* nb_inplace_or */ | |
| 982 | + (binaryfunc)complex_int_div, /* nb_floor_divide */ | |
| 983 | + (binaryfunc)complex_div, /* nb_true_divide */ | |
| 984 | + 0, /* nb_inplace_floor_divide */ | |
| 985 | + 0, /* nb_inplace_true_divide */ | |
| 986 | +}; | |
| 987 | + | |
| 988 | +PyTypeObject PyComplex_Type = { | |
| 989 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 990 | + 0, | |
| 991 | + "complex", | |
| 992 | + sizeof(PyComplexObject), | |
| 993 | + 0, | |
| 994 | + complex_dealloc, /* tp_dealloc */ | |
| 995 | + (printfunc)complex_print, /* tp_print */ | |
| 996 | + 0, /* tp_getattr */ | |
| 997 | + 0, /* tp_setattr */ | |
| 998 | + 0, /* tp_compare */ | |
| 999 | + (reprfunc)complex_repr, /* tp_repr */ | |
| 1000 | + &complex_as_number, /* tp_as_number */ | |
| 1001 | + 0, /* tp_as_sequence */ | |
| 1002 | + 0, /* tp_as_mapping */ | |
| 1003 | + (hashfunc)complex_hash, /* tp_hash */ | |
| 1004 | + 0, /* tp_call */ | |
| 1005 | + (reprfunc)complex_str, /* tp_str */ | |
| 1006 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 1007 | + 0, /* tp_setattro */ | |
| 1008 | + 0, /* tp_as_buffer */ | |
| 1009 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ | |
| 1010 | + complex_doc, /* tp_doc */ | |
| 1011 | + 0, /* tp_traverse */ | |
| 1012 | + 0, /* tp_clear */ | |
| 1013 | + complex_richcompare, /* tp_richcompare */ | |
| 1014 | + 0, /* tp_weaklistoffset */ | |
| 1015 | + 0, /* tp_iter */ | |
| 1016 | + 0, /* tp_iternext */ | |
| 1017 | + complex_methods, /* tp_methods */ | |
| 1018 | + complex_members, /* tp_members */ | |
| 1019 | + 0, /* tp_getset */ | |
| 1020 | + 0, /* tp_base */ | |
| 1021 | + 0, /* tp_dict */ | |
| 1022 | + 0, /* tp_descr_get */ | |
| 1023 | + 0, /* tp_descr_set */ | |
| 1024 | + 0, /* tp_dictoffset */ | |
| 1025 | + 0, /* tp_init */ | |
| 1026 | + PyType_GenericAlloc, /* tp_alloc */ | |
| 1027 | + complex_new, /* tp_new */ | |
| 1028 | + PyObject_Del, /* tp_free */ | |
| 1029 | +}; | |
| 1030 | + | |
| 1031 | +#endif | |
| @@ -0,0 +1,1283 @@ | ||
| 1 | +/* Descriptors -- a new, flexible way to describe attributes */ | |
| 2 | + | |
| 3 | +#include "Python.h" | |
| 4 | +#include "structmember.h" /* Why is this not included in Python.h? */ | |
| 5 | + | |
| 6 | +static void | |
| 7 | +descr_dealloc(PyDescrObject *descr) | |
| 8 | +{ | |
| 9 | + _PyObject_GC_UNTRACK(descr); | |
| 10 | + Py_XDECREF(descr->d_type); | |
| 11 | + Py_XDECREF(descr->d_name); | |
| 12 | + PyObject_GC_Del(descr); | |
| 13 | +} | |
| 14 | + | |
| 15 | +static char * | |
| 16 | +descr_name(PyDescrObject *descr) | |
| 17 | +{ | |
| 18 | + if (descr->d_name != NULL && PyString_Check(descr->d_name)) | |
| 19 | + return PyString_AS_STRING(descr->d_name); | |
| 20 | + else | |
| 21 | + return "?"; | |
| 22 | +} | |
| 23 | + | |
| 24 | +static PyObject * | |
| 25 | +descr_repr(PyDescrObject *descr, char *format) | |
| 26 | +{ | |
| 27 | + return PyString_FromFormat(format, descr_name(descr), | |
| 28 | + descr->d_type->tp_name); | |
| 29 | +} | |
| 30 | + | |
| 31 | +static PyObject * | |
| 32 | +method_repr(PyMethodDescrObject *descr) | |
| 33 | +{ | |
| 34 | + return descr_repr((PyDescrObject *)descr, | |
| 35 | + "<method '%s' of '%s' objects>"); | |
| 36 | +} | |
| 37 | + | |
| 38 | +static PyObject * | |
| 39 | +member_repr(PyMemberDescrObject *descr) | |
| 40 | +{ | |
| 41 | + return descr_repr((PyDescrObject *)descr, | |
| 42 | + "<member '%s' of '%s' objects>"); | |
| 43 | +} | |
| 44 | + | |
| 45 | +static PyObject * | |
| 46 | +getset_repr(PyGetSetDescrObject *descr) | |
| 47 | +{ | |
| 48 | + return descr_repr((PyDescrObject *)descr, | |
| 49 | + "<attribute '%s' of '%s' objects>"); | |
| 50 | +} | |
| 51 | + | |
| 52 | +static PyObject * | |
| 53 | +wrapperdescr_repr(PyWrapperDescrObject *descr) | |
| 54 | +{ | |
| 55 | + return descr_repr((PyDescrObject *)descr, | |
| 56 | + "<slot wrapper '%s' of '%s' objects>"); | |
| 57 | +} | |
| 58 | + | |
| 59 | +static int | |
| 60 | +descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) | |
| 61 | +{ | |
| 62 | + if (obj == NULL) { | |
| 63 | + Py_INCREF(descr); | |
| 64 | + *pres = (PyObject *)descr; | |
| 65 | + return 1; | |
| 66 | + } | |
| 67 | + if (!PyObject_TypeCheck(obj, descr->d_type)) { | |
| 68 | + PyErr_Format(PyExc_TypeError, | |
| 69 | + "descriptor '%s' for '%s' objects " | |
| 70 | + "doesn't apply to '%s' object", | |
| 71 | + descr_name((PyDescrObject *)descr), | |
| 72 | + descr->d_type->tp_name, | |
| 73 | + obj->ob_type->tp_name); | |
| 74 | + *pres = NULL; | |
| 75 | + return 1; | |
| 76 | + } | |
| 77 | + return 0; | |
| 78 | +} | |
| 79 | + | |
| 80 | +static PyObject * | |
| 81 | +classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) | |
| 82 | +{ | |
| 83 | + /* Ensure a valid type. Class methods ignore obj. */ | |
| 84 | + if (type == NULL) { | |
| 85 | + if (obj != NULL) | |
| 86 | + type = (PyObject *)obj->ob_type; | |
| 87 | + else { | |
| 88 | + /* Wot - no type?! */ | |
| 89 | + PyErr_Format(PyExc_TypeError, | |
| 90 | + "descriptor '%s' for type '%s' " | |
| 91 | + "needs either an object or a type", | |
| 92 | + descr_name((PyDescrObject *)descr), | |
| 93 | + descr->d_type->tp_name); | |
| 94 | + return NULL; | |
| 95 | + } | |
| 96 | + } | |
| 97 | + if (!PyType_Check(type)) { | |
| 98 | + PyErr_Format(PyExc_TypeError, | |
| 99 | + "descriptor '%s' for type '%s' " | |
| 100 | + "needs a type, not a '%s' as arg 2", | |
| 101 | + descr_name((PyDescrObject *)descr), | |
| 102 | + descr->d_type->tp_name, | |
| 103 | + type->ob_type->tp_name); | |
| 104 | + return NULL; | |
| 105 | + } | |
| 106 | + if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) { | |
| 107 | + PyErr_Format(PyExc_TypeError, | |
| 108 | + "descriptor '%s' for type '%s' " | |
| 109 | + "doesn't apply to type '%s'", | |
| 110 | + descr_name((PyDescrObject *)descr), | |
| 111 | + descr->d_type->tp_name, | |
| 112 | + ((PyTypeObject *)type)->tp_name); | |
| 113 | + return NULL; | |
| 114 | + } | |
| 115 | + return PyCFunction_New(descr->d_method, type); | |
| 116 | +} | |
| 117 | + | |
| 118 | +static PyObject * | |
| 119 | +method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) | |
| 120 | +{ | |
| 121 | + PyObject *res; | |
| 122 | + | |
| 123 | + if (descr_check((PyDescrObject *)descr, obj, &res)) | |
| 124 | + return res; | |
| 125 | + return PyCFunction_New(descr->d_method, obj); | |
| 126 | +} | |
| 127 | + | |
| 128 | +static PyObject * | |
| 129 | +member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) | |
| 130 | +{ | |
| 131 | + PyObject *res; | |
| 132 | + | |
| 133 | + if (descr_check((PyDescrObject *)descr, obj, &res)) | |
| 134 | + return res; | |
| 135 | + return PyMember_GetOne((char *)obj, descr->d_member); | |
| 136 | +} | |
| 137 | + | |
| 138 | +static PyObject * | |
| 139 | +getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) | |
| 140 | +{ | |
| 141 | + PyObject *res; | |
| 142 | + | |
| 143 | + if (descr_check((PyDescrObject *)descr, obj, &res)) | |
| 144 | + return res; | |
| 145 | + if (descr->d_getset->get != NULL) | |
| 146 | + return descr->d_getset->get(obj, descr->d_getset->closure); | |
| 147 | + PyErr_Format(PyExc_AttributeError, | |
| 148 | + "attribute '%.300s' of '%.100s' objects is not readable", | |
| 149 | + descr_name((PyDescrObject *)descr), | |
| 150 | + descr->d_type->tp_name); | |
| 151 | + return NULL; | |
| 152 | +} | |
| 153 | + | |
| 154 | +static PyObject * | |
| 155 | +wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type) | |
| 156 | +{ | |
| 157 | + PyObject *res; | |
| 158 | + | |
| 159 | + if (descr_check((PyDescrObject *)descr, obj, &res)) | |
| 160 | + return res; | |
| 161 | + return PyWrapper_New((PyObject *)descr, obj); | |
| 162 | +} | |
| 163 | + | |
| 164 | +static int | |
| 165 | +descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, | |
| 166 | + int *pres) | |
| 167 | +{ | |
| 168 | + assert(obj != NULL); | |
| 169 | + if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) { | |
| 170 | + PyErr_Format(PyExc_TypeError, | |
| 171 | + "descriptor '%.200s' for '%.100s' objects " | |
| 172 | + "doesn't apply to '%.100s' object", | |
| 173 | + descr_name(descr), | |
| 174 | + descr->d_type->tp_name, | |
| 175 | + obj->ob_type->tp_name); | |
| 176 | + *pres = -1; | |
| 177 | + return 1; | |
| 178 | + } | |
| 179 | + return 0; | |
| 180 | +} | |
| 181 | + | |
| 182 | +static int | |
| 183 | +member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value) | |
| 184 | +{ | |
| 185 | + int res; | |
| 186 | + | |
| 187 | + if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) | |
| 188 | + return res; | |
| 189 | + return PyMember_SetOne((char *)obj, descr->d_member, value); | |
| 190 | +} | |
| 191 | + | |
| 192 | +static int | |
| 193 | +getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) | |
| 194 | +{ | |
| 195 | + int res; | |
| 196 | + | |
| 197 | + if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) | |
| 198 | + return res; | |
| 199 | + if (descr->d_getset->set != NULL) | |
| 200 | + return descr->d_getset->set(obj, value, | |
| 201 | + descr->d_getset->closure); | |
| 202 | + PyErr_Format(PyExc_AttributeError, | |
| 203 | + "attribute '%.300s' of '%.100s' objects is not writable", | |
| 204 | + descr_name((PyDescrObject *)descr), | |
| 205 | + descr->d_type->tp_name); | |
| 206 | + return -1; | |
| 207 | +} | |
| 208 | + | |
| 209 | +static PyObject * | |
| 210 | +methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) | |
| 211 | +{ | |
| 212 | + Py_ssize_t argc; | |
| 213 | + PyObject *self, *func, *result; | |
| 214 | + | |
| 215 | + /* Make sure that the first argument is acceptable as 'self' */ | |
| 216 | + assert(PyTuple_Check(args)); | |
| 217 | + argc = PyTuple_GET_SIZE(args); | |
| 218 | + if (argc < 1) { | |
| 219 | + PyErr_Format(PyExc_TypeError, | |
| 220 | + "descriptor '%.300s' of '%.100s' " | |
| 221 | + "object needs an argument", | |
| 222 | + descr_name((PyDescrObject *)descr), | |
| 223 | + descr->d_type->tp_name); | |
| 224 | + return NULL; | |
| 225 | + } | |
| 226 | + self = PyTuple_GET_ITEM(args, 0); | |
| 227 | + if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { | |
| 228 | + PyErr_Format(PyExc_TypeError, | |
| 229 | + "descriptor '%.200s' " | |
| 230 | + "requires a '%.100s' object " | |
| 231 | + "but received a '%.100s'", | |
| 232 | + descr_name((PyDescrObject *)descr), | |
| 233 | + descr->d_type->tp_name, | |
| 234 | + self->ob_type->tp_name); | |
| 235 | + return NULL; | |
| 236 | + } | |
| 237 | + | |
| 238 | + func = PyCFunction_New(descr->d_method, self); | |
| 239 | + if (func == NULL) | |
| 240 | + return NULL; | |
| 241 | + args = PyTuple_GetSlice(args, 1, argc); | |
| 242 | + if (args == NULL) { | |
| 243 | + Py_DECREF(func); | |
| 244 | + return NULL; | |
| 245 | + } | |
| 246 | + result = PyEval_CallObjectWithKeywords(func, args, kwds); | |
| 247 | + Py_DECREF(args); | |
| 248 | + Py_DECREF(func); | |
| 249 | + return result; | |
| 250 | +} | |
| 251 | + | |
| 252 | +static PyObject * | |
| 253 | +classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, | |
| 254 | + PyObject *kwds) | |
| 255 | +{ | |
| 256 | + PyObject *func, *result; | |
| 257 | + | |
| 258 | + func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type); | |
| 259 | + if (func == NULL) | |
| 260 | + return NULL; | |
| 261 | + | |
| 262 | + result = PyEval_CallObjectWithKeywords(func, args, kwds); | |
| 263 | + Py_DECREF(func); | |
| 264 | + return result; | |
| 265 | +} | |
| 266 | + | |
| 267 | +static PyObject * | |
| 268 | +wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) | |
| 269 | +{ | |
| 270 | + Py_ssize_t argc; | |
| 271 | + PyObject *self, *func, *result; | |
| 272 | + | |
| 273 | + /* Make sure that the first argument is acceptable as 'self' */ | |
| 274 | + assert(PyTuple_Check(args)); | |
| 275 | + argc = PyTuple_GET_SIZE(args); | |
| 276 | + if (argc < 1) { | |
| 277 | + PyErr_Format(PyExc_TypeError, | |
| 278 | + "descriptor '%.300s' of '%.100s' " | |
| 279 | + "object needs an argument", | |
| 280 | + descr_name((PyDescrObject *)descr), | |
| 281 | + descr->d_type->tp_name); | |
| 282 | + return NULL; | |
| 283 | + } | |
| 284 | + self = PyTuple_GET_ITEM(args, 0); | |
| 285 | + if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { | |
| 286 | + PyErr_Format(PyExc_TypeError, | |
| 287 | + "descriptor '%.200s' " | |
| 288 | + "requires a '%.100s' object " | |
| 289 | + "but received a '%.100s'", | |
| 290 | + descr_name((PyDescrObject *)descr), | |
| 291 | + descr->d_type->tp_name, | |
| 292 | + self->ob_type->tp_name); | |
| 293 | + return NULL; | |
| 294 | + } | |
| 295 | + | |
| 296 | + func = PyWrapper_New((PyObject *)descr, self); | |
| 297 | + if (func == NULL) | |
| 298 | + return NULL; | |
| 299 | + args = PyTuple_GetSlice(args, 1, argc); | |
| 300 | + if (args == NULL) { | |
| 301 | + Py_DECREF(func); | |
| 302 | + return NULL; | |
| 303 | + } | |
| 304 | + result = PyEval_CallObjectWithKeywords(func, args, kwds); | |
| 305 | + Py_DECREF(args); | |
| 306 | + Py_DECREF(func); | |
| 307 | + return result; | |
| 308 | +} | |
| 309 | + | |
| 310 | +static PyObject * | |
| 311 | +method_get_doc(PyMethodDescrObject *descr, void *closure) | |
| 312 | +{ | |
| 313 | + if (descr->d_method->ml_doc == NULL) { | |
| 314 | + Py_INCREF(Py_None); | |
| 315 | + return Py_None; | |
| 316 | + } | |
| 317 | + return PyString_FromString(descr->d_method->ml_doc); | |
| 318 | +} | |
| 319 | + | |
| 320 | +static PyMemberDef descr_members[] = { | |
| 321 | + {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, | |
| 322 | + {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, | |
| 323 | + {0} | |
| 324 | +}; | |
| 325 | + | |
| 326 | +static PyGetSetDef method_getset[] = { | |
| 327 | + {"__doc__", (getter)method_get_doc}, | |
| 328 | + {0} | |
| 329 | +}; | |
| 330 | + | |
| 331 | +static PyObject * | |
| 332 | +member_get_doc(PyMemberDescrObject *descr, void *closure) | |
| 333 | +{ | |
| 334 | + if (descr->d_member->doc == NULL) { | |
| 335 | + Py_INCREF(Py_None); | |
| 336 | + return Py_None; | |
| 337 | + } | |
| 338 | + return PyString_FromString(descr->d_member->doc); | |
| 339 | +} | |
| 340 | + | |
| 341 | +static PyGetSetDef member_getset[] = { | |
| 342 | + {"__doc__", (getter)member_get_doc}, | |
| 343 | + {0} | |
| 344 | +}; | |
| 345 | + | |
| 346 | +static PyObject * | |
| 347 | +getset_get_doc(PyGetSetDescrObject *descr, void *closure) | |
| 348 | +{ | |
| 349 | + if (descr->d_getset->doc == NULL) { | |
| 350 | + Py_INCREF(Py_None); | |
| 351 | + return Py_None; | |
| 352 | + } | |
| 353 | + return PyString_FromString(descr->d_getset->doc); | |
| 354 | +} | |
| 355 | + | |
| 356 | +static PyGetSetDef getset_getset[] = { | |
| 357 | + {"__doc__", (getter)getset_get_doc}, | |
| 358 | + {0} | |
| 359 | +}; | |
| 360 | + | |
| 361 | +static PyObject * | |
| 362 | +wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure) | |
| 363 | +{ | |
| 364 | + if (descr->d_base->doc == NULL) { | |
| 365 | + Py_INCREF(Py_None); | |
| 366 | + return Py_None; | |
| 367 | + } | |
| 368 | + return PyString_FromString(descr->d_base->doc); | |
| 369 | +} | |
| 370 | + | |
| 371 | +static PyGetSetDef wrapperdescr_getset[] = { | |
| 372 | + {"__doc__", (getter)wrapperdescr_get_doc}, | |
| 373 | + {0} | |
| 374 | +}; | |
| 375 | + | |
| 376 | +static int | |
| 377 | +descr_traverse(PyObject *self, visitproc visit, void *arg) | |
| 378 | +{ | |
| 379 | + PyDescrObject *descr = (PyDescrObject *)self; | |
| 380 | + Py_VISIT(descr->d_type); | |
| 381 | + return 0; | |
| 382 | +} | |
| 383 | + | |
| 384 | +static PyTypeObject PyMethodDescr_Type = { | |
| 385 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 386 | + 0, | |
| 387 | + "method_descriptor", | |
| 388 | + sizeof(PyMethodDescrObject), | |
| 389 | + 0, | |
| 390 | + (destructor)descr_dealloc, /* tp_dealloc */ | |
| 391 | + 0, /* tp_print */ | |
| 392 | + 0, /* tp_getattr */ | |
| 393 | + 0, /* tp_setattr */ | |
| 394 | + 0, /* tp_compare */ | |
| 395 | + (reprfunc)method_repr, /* tp_repr */ | |
| 396 | + 0, /* tp_as_number */ | |
| 397 | + 0, /* tp_as_sequence */ | |
| 398 | + 0, /* tp_as_mapping */ | |
| 399 | + 0, /* tp_hash */ | |
| 400 | + (ternaryfunc)methoddescr_call, /* tp_call */ | |
| 401 | + 0, /* tp_str */ | |
| 402 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 403 | + 0, /* tp_setattro */ | |
| 404 | + 0, /* tp_as_buffer */ | |
| 405 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ | |
| 406 | + 0, /* tp_doc */ | |
| 407 | + descr_traverse, /* tp_traverse */ | |
| 408 | + 0, /* tp_clear */ | |
| 409 | + 0, /* tp_richcompare */ | |
| 410 | + 0, /* tp_weaklistoffset */ | |
| 411 | + 0, /* tp_iter */ | |
| 412 | + 0, /* tp_iternext */ | |
| 413 | + 0, /* tp_methods */ | |
| 414 | + descr_members, /* tp_members */ | |
| 415 | + method_getset, /* tp_getset */ | |
| 416 | + 0, /* tp_base */ | |
| 417 | + 0, /* tp_dict */ | |
| 418 | + (descrgetfunc)method_get, /* tp_descr_get */ | |
| 419 | + 0, /* tp_descr_set */ | |
| 420 | +}; | |
| 421 | + | |
| 422 | +/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */ | |
| 423 | +static PyTypeObject PyClassMethodDescr_Type = { | |
| 424 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 425 | + 0, | |
| 426 | + "classmethod_descriptor", | |
| 427 | + sizeof(PyMethodDescrObject), | |
| 428 | + 0, | |
| 429 | + (destructor)descr_dealloc, /* tp_dealloc */ | |
| 430 | + 0, /* tp_print */ | |
| 431 | + 0, /* tp_getattr */ | |
| 432 | + 0, /* tp_setattr */ | |
| 433 | + 0, /* tp_compare */ | |
| 434 | + (reprfunc)method_repr, /* tp_repr */ | |
| 435 | + 0, /* tp_as_number */ | |
| 436 | + 0, /* tp_as_sequence */ | |
| 437 | + 0, /* tp_as_mapping */ | |
| 438 | + 0, /* tp_hash */ | |
| 439 | + (ternaryfunc)classmethoddescr_call, /* tp_call */ | |
| 440 | + 0, /* tp_str */ | |
| 441 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 442 | + 0, /* tp_setattro */ | |
| 443 | + 0, /* tp_as_buffer */ | |
| 444 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ | |
| 445 | + 0, /* tp_doc */ | |
| 446 | + descr_traverse, /* tp_traverse */ | |
| 447 | + 0, /* tp_clear */ | |
| 448 | + 0, /* tp_richcompare */ | |
| 449 | + 0, /* tp_weaklistoffset */ | |
| 450 | + 0, /* tp_iter */ | |
| 451 | + 0, /* tp_iternext */ | |
| 452 | + 0, /* tp_methods */ | |
| 453 | + descr_members, /* tp_members */ | |
| 454 | + method_getset, /* tp_getset */ | |
| 455 | + 0, /* tp_base */ | |
| 456 | + 0, /* tp_dict */ | |
| 457 | + (descrgetfunc)classmethod_get, /* tp_descr_get */ | |
| 458 | + 0, /* tp_descr_set */ | |
| 459 | +}; | |
| 460 | + | |
| 461 | +static PyTypeObject PyMemberDescr_Type = { | |
| 462 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 463 | + 0, | |
| 464 | + "member_descriptor", | |
| 465 | + sizeof(PyMemberDescrObject), | |
| 466 | + 0, | |
| 467 | + (destructor)descr_dealloc, /* tp_dealloc */ | |
| 468 | + 0, /* tp_print */ | |
| 469 | + 0, /* tp_getattr */ | |
| 470 | + 0, /* tp_setattr */ | |
| 471 | + 0, /* tp_compare */ | |
| 472 | + (reprfunc)member_repr, /* tp_repr */ | |
| 473 | + 0, /* tp_as_number */ | |
| 474 | + 0, /* tp_as_sequence */ | |
| 475 | + 0, /* tp_as_mapping */ | |
| 476 | + 0, /* tp_hash */ | |
| 477 | + 0, /* tp_call */ | |
| 478 | + 0, /* tp_str */ | |
| 479 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 480 | + 0, /* tp_setattro */ | |
| 481 | + 0, /* tp_as_buffer */ | |
| 482 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ | |
| 483 | + 0, /* tp_doc */ | |
| 484 | + descr_traverse, /* tp_traverse */ | |
| 485 | + 0, /* tp_clear */ | |
| 486 | + 0, /* tp_richcompare */ | |
| 487 | + 0, /* tp_weaklistoffset */ | |
| 488 | + 0, /* tp_iter */ | |
| 489 | + 0, /* tp_iternext */ | |
| 490 | + 0, /* tp_methods */ | |
| 491 | + descr_members, /* tp_members */ | |
| 492 | + member_getset, /* tp_getset */ | |
| 493 | + 0, /* tp_base */ | |
| 494 | + 0, /* tp_dict */ | |
| 495 | + (descrgetfunc)member_get, /* tp_descr_get */ | |
| 496 | + (descrsetfunc)member_set, /* tp_descr_set */ | |
| 497 | +}; | |
| 498 | + | |
| 499 | +static PyTypeObject PyGetSetDescr_Type = { | |
| 500 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 501 | + 0, | |
| 502 | + "getset_descriptor", | |
| 503 | + sizeof(PyGetSetDescrObject), | |
| 504 | + 0, | |
| 505 | + (destructor)descr_dealloc, /* tp_dealloc */ | |
| 506 | + 0, /* tp_print */ | |
| 507 | + 0, /* tp_getattr */ | |
| 508 | + 0, /* tp_setattr */ | |
| 509 | + 0, /* tp_compare */ | |
| 510 | + (reprfunc)getset_repr, /* tp_repr */ | |
| 511 | + 0, /* tp_as_number */ | |
| 512 | + 0, /* tp_as_sequence */ | |
| 513 | + 0, /* tp_as_mapping */ | |
| 514 | + 0, /* tp_hash */ | |
| 515 | + 0, /* tp_call */ | |
| 516 | + 0, /* tp_str */ | |
| 517 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 518 | + 0, /* tp_setattro */ | |
| 519 | + 0, /* tp_as_buffer */ | |
| 520 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ | |
| 521 | + 0, /* tp_doc */ | |
| 522 | + descr_traverse, /* tp_traverse */ | |
| 523 | + 0, /* tp_clear */ | |
| 524 | + 0, /* tp_richcompare */ | |
| 525 | + 0, /* tp_weaklistoffset */ | |
| 526 | + 0, /* tp_iter */ | |
| 527 | + 0, /* tp_iternext */ | |
| 528 | + 0, /* tp_methods */ | |
| 529 | + descr_members, /* tp_members */ | |
| 530 | + getset_getset, /* tp_getset */ | |
| 531 | + 0, /* tp_base */ | |
| 532 | + 0, /* tp_dict */ | |
| 533 | + (descrgetfunc)getset_get, /* tp_descr_get */ | |
| 534 | + (descrsetfunc)getset_set, /* tp_descr_set */ | |
| 535 | +}; | |
| 536 | + | |
| 537 | +PyTypeObject PyWrapperDescr_Type = { | |
| 538 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 539 | + 0, | |
| 540 | + "wrapper_descriptor", | |
| 541 | + sizeof(PyWrapperDescrObject), | |
| 542 | + 0, | |
| 543 | + (destructor)descr_dealloc, /* tp_dealloc */ | |
| 544 | + 0, /* tp_print */ | |
| 545 | + 0, /* tp_getattr */ | |
| 546 | + 0, /* tp_setattr */ | |
| 547 | + 0, /* tp_compare */ | |
| 548 | + (reprfunc)wrapperdescr_repr, /* tp_repr */ | |
| 549 | + 0, /* tp_as_number */ | |
| 550 | + 0, /* tp_as_sequence */ | |
| 551 | + 0, /* tp_as_mapping */ | |
| 552 | + 0, /* tp_hash */ | |
| 553 | + (ternaryfunc)wrapperdescr_call, /* tp_call */ | |
| 554 | + 0, /* tp_str */ | |
| 555 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 556 | + 0, /* tp_setattro */ | |
| 557 | + 0, /* tp_as_buffer */ | |
| 558 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ | |
| 559 | + 0, /* tp_doc */ | |
| 560 | + descr_traverse, /* tp_traverse */ | |
| 561 | + 0, /* tp_clear */ | |
| 562 | + 0, /* tp_richcompare */ | |
| 563 | + 0, /* tp_weaklistoffset */ | |
| 564 | + 0, /* tp_iter */ | |
| 565 | + 0, /* tp_iternext */ | |
| 566 | + 0, /* tp_methods */ | |
| 567 | + descr_members, /* tp_members */ | |
| 568 | + wrapperdescr_getset, /* tp_getset */ | |
| 569 | + 0, /* tp_base */ | |
| 570 | + 0, /* tp_dict */ | |
| 571 | + (descrgetfunc)wrapperdescr_get, /* tp_descr_get */ | |
| 572 | + 0, /* tp_descr_set */ | |
| 573 | +}; | |
| 574 | + | |
| 575 | +static PyDescrObject * | |
| 576 | +descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) | |
| 577 | +{ | |
| 578 | + PyDescrObject *descr; | |
| 579 | + | |
| 580 | + descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); | |
| 581 | + if (descr != NULL) { | |
| 582 | + Py_XINCREF(type); | |
| 583 | + descr->d_type = type; | |
| 584 | + descr->d_name = PyString_InternFromString(name); | |
| 585 | + if (descr->d_name == NULL) { | |
| 586 | + Py_DECREF(descr); | |
| 587 | + descr = NULL; | |
| 588 | + } | |
| 589 | + } | |
| 590 | + return descr; | |
| 591 | +} | |
| 592 | + | |
| 593 | +PyObject * | |
| 594 | +PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) | |
| 595 | +{ | |
| 596 | + PyMethodDescrObject *descr; | |
| 597 | + | |
| 598 | + descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, | |
| 599 | + type, method->ml_name); | |
| 600 | + if (descr != NULL) | |
| 601 | + descr->d_method = method; | |
| 602 | + return (PyObject *)descr; | |
| 603 | +} | |
| 604 | + | |
| 605 | +PyObject * | |
| 606 | +PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method) | |
| 607 | +{ | |
| 608 | + PyMethodDescrObject *descr; | |
| 609 | + | |
| 610 | + descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type, | |
| 611 | + type, method->ml_name); | |
| 612 | + if (descr != NULL) | |
| 613 | + descr->d_method = method; | |
| 614 | + return (PyObject *)descr; | |
| 615 | +} | |
| 616 | + | |
| 617 | +PyObject * | |
| 618 | +PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member) | |
| 619 | +{ | |
| 620 | + PyMemberDescrObject *descr; | |
| 621 | + | |
| 622 | + descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type, | |
| 623 | + type, member->name); | |
| 624 | + if (descr != NULL) | |
| 625 | + descr->d_member = member; | |
| 626 | + return (PyObject *)descr; | |
| 627 | +} | |
| 628 | + | |
| 629 | +PyObject * | |
| 630 | +PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset) | |
| 631 | +{ | |
| 632 | + PyGetSetDescrObject *descr; | |
| 633 | + | |
| 634 | + descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type, | |
| 635 | + type, getset->name); | |
| 636 | + if (descr != NULL) | |
| 637 | + descr->d_getset = getset; | |
| 638 | + return (PyObject *)descr; | |
| 639 | +} | |
| 640 | + | |
| 641 | +PyObject * | |
| 642 | +PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped) | |
| 643 | +{ | |
| 644 | + PyWrapperDescrObject *descr; | |
| 645 | + | |
| 646 | + descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type, | |
| 647 | + type, base->name); | |
| 648 | + if (descr != NULL) { | |
| 649 | + descr->d_base = base; | |
| 650 | + descr->d_wrapped = wrapped; | |
| 651 | + } | |
| 652 | + return (PyObject *)descr; | |
| 653 | +} | |
| 654 | + | |
| 655 | + | |
| 656 | +/* --- Readonly proxy for dictionaries (actually any mapping) --- */ | |
| 657 | + | |
| 658 | +/* This has no reason to be in this file except that adding new files is a | |
| 659 | + bit of a pain */ | |
| 660 | + | |
| 661 | +typedef struct { | |
| 662 | + PyObject_HEAD | |
| 663 | + PyObject *dict; | |
| 664 | +} proxyobject; | |
| 665 | + | |
| 666 | +static Py_ssize_t | |
| 667 | +proxy_len(proxyobject *pp) | |
| 668 | +{ | |
| 669 | + return PyObject_Size(pp->dict); | |
| 670 | +} | |
| 671 | + | |
| 672 | +static PyObject * | |
| 673 | +proxy_getitem(proxyobject *pp, PyObject *key) | |
| 674 | +{ | |
| 675 | + return PyObject_GetItem(pp->dict, key); | |
| 676 | +} | |
| 677 | + | |
| 678 | +static PyMappingMethods proxy_as_mapping = { | |
| 679 | + (lenfunc)proxy_len, /* mp_length */ | |
| 680 | + (binaryfunc)proxy_getitem, /* mp_subscript */ | |
| 681 | + 0, /* mp_ass_subscript */ | |
| 682 | +}; | |
| 683 | + | |
| 684 | +static int | |
| 685 | +proxy_contains(proxyobject *pp, PyObject *key) | |
| 686 | +{ | |
| 687 | + return PyDict_Contains(pp->dict, key); | |
| 688 | +} | |
| 689 | + | |
| 690 | +static PySequenceMethods proxy_as_sequence = { | |
| 691 | + 0, /* sq_length */ | |
| 692 | + 0, /* sq_concat */ | |
| 693 | + 0, /* sq_repeat */ | |
| 694 | + 0, /* sq_item */ | |
| 695 | + 0, /* sq_slice */ | |
| 696 | + 0, /* sq_ass_item */ | |
| 697 | + 0, /* sq_ass_slice */ | |
| 698 | + (objobjproc)proxy_contains, /* sq_contains */ | |
| 699 | + 0, /* sq_inplace_concat */ | |
| 700 | + 0, /* sq_inplace_repeat */ | |
| 701 | +}; | |
| 702 | + | |
| 703 | +static PyObject * | |
| 704 | +proxy_has_key(proxyobject *pp, PyObject *key) | |
| 705 | +{ | |
| 706 | + int res = PyDict_Contains(pp->dict, key); | |
| 707 | + if (res < 0) | |
| 708 | + return NULL; | |
| 709 | + return PyBool_FromLong(res); | |
| 710 | +} | |
| 711 | + | |
| 712 | +static PyObject * | |
| 713 | +proxy_get(proxyobject *pp, PyObject *args) | |
| 714 | +{ | |
| 715 | + PyObject *key, *def = Py_None; | |
| 716 | + | |
| 717 | + if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) | |
| 718 | + return NULL; | |
| 719 | + return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def); | |
| 720 | +} | |
| 721 | + | |
| 722 | +static PyObject * | |
| 723 | +proxy_keys(proxyobject *pp) | |
| 724 | +{ | |
| 725 | + return PyMapping_Keys(pp->dict); | |
| 726 | +} | |
| 727 | + | |
| 728 | +static PyObject * | |
| 729 | +proxy_values(proxyobject *pp) | |
| 730 | +{ | |
| 731 | + return PyMapping_Values(pp->dict); | |
| 732 | +} | |
| 733 | + | |
| 734 | +static PyObject * | |
| 735 | +proxy_items(proxyobject *pp) | |
| 736 | +{ | |
| 737 | + return PyMapping_Items(pp->dict); | |
| 738 | +} | |
| 739 | + | |
| 740 | +static PyObject * | |
| 741 | +proxy_iterkeys(proxyobject *pp) | |
| 742 | +{ | |
| 743 | + return PyObject_CallMethod(pp->dict, "iterkeys", NULL); | |
| 744 | +} | |
| 745 | + | |
| 746 | +static PyObject * | |
| 747 | +proxy_itervalues(proxyobject *pp) | |
| 748 | +{ | |
| 749 | + return PyObject_CallMethod(pp->dict, "itervalues", NULL); | |
| 750 | +} | |
| 751 | + | |
| 752 | +static PyObject * | |
| 753 | +proxy_iteritems(proxyobject *pp) | |
| 754 | +{ | |
| 755 | + return PyObject_CallMethod(pp->dict, "iteritems", NULL); | |
| 756 | +} | |
| 757 | +static PyObject * | |
| 758 | +proxy_copy(proxyobject *pp) | |
| 759 | +{ | |
| 760 | + return PyObject_CallMethod(pp->dict, "copy", NULL); | |
| 761 | +} | |
| 762 | + | |
| 763 | +static PyMethodDef proxy_methods[] = { | |
| 764 | + {"has_key", (PyCFunction)proxy_has_key, METH_O, | |
| 765 | + PyDoc_STR("D.has_key(k) -> True if D has a key k, else False")}, | |
| 766 | + {"get", (PyCFunction)proxy_get, METH_VARARGS, | |
| 767 | + PyDoc_STR("D.get(k[,d]) -> D[k] if D.has_key(k), else d." | |
| 768 | + " d defaults to None.")}, | |
| 769 | + {"keys", (PyCFunction)proxy_keys, METH_NOARGS, | |
| 770 | + PyDoc_STR("D.keys() -> list of D's keys")}, | |
| 771 | + {"values", (PyCFunction)proxy_values, METH_NOARGS, | |
| 772 | + PyDoc_STR("D.values() -> list of D's values")}, | |
| 773 | + {"items", (PyCFunction)proxy_items, METH_NOARGS, | |
| 774 | + PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")}, | |
| 775 | + {"iterkeys", (PyCFunction)proxy_iterkeys, METH_NOARGS, | |
| 776 | + PyDoc_STR("D.iterkeys() -> an iterator over the keys of D")}, | |
| 777 | + {"itervalues",(PyCFunction)proxy_itervalues, METH_NOARGS, | |
| 778 | + PyDoc_STR("D.itervalues() -> an iterator over the values of D")}, | |
| 779 | + {"iteritems", (PyCFunction)proxy_iteritems, METH_NOARGS, | |
| 780 | + PyDoc_STR("D.iteritems() ->" | |
| 781 | + " an iterator over the (key, value) items of D")}, | |
| 782 | + {"copy", (PyCFunction)proxy_copy, METH_NOARGS, | |
| 783 | + PyDoc_STR("D.copy() -> a shallow copy of D")}, | |
| 784 | + {0} | |
| 785 | +}; | |
| 786 | + | |
| 787 | +static void | |
| 788 | +proxy_dealloc(proxyobject *pp) | |
| 789 | +{ | |
| 790 | + _PyObject_GC_UNTRACK(pp); | |
| 791 | + Py_DECREF(pp->dict); | |
| 792 | + PyObject_GC_Del(pp); | |
| 793 | +} | |
| 794 | + | |
| 795 | +static PyObject * | |
| 796 | +proxy_getiter(proxyobject *pp) | |
| 797 | +{ | |
| 798 | + return PyObject_GetIter(pp->dict); | |
| 799 | +} | |
| 800 | + | |
| 801 | +static PyObject * | |
| 802 | +proxy_str(proxyobject *pp) | |
| 803 | +{ | |
| 804 | + return PyObject_Str(pp->dict); | |
| 805 | +} | |
| 806 | + | |
| 807 | +static int | |
| 808 | +proxy_traverse(PyObject *self, visitproc visit, void *arg) | |
| 809 | +{ | |
| 810 | + proxyobject *pp = (proxyobject *)self; | |
| 811 | + Py_VISIT(pp->dict); | |
| 812 | + return 0; | |
| 813 | +} | |
| 814 | + | |
| 815 | +static int | |
| 816 | +proxy_compare(proxyobject *v, PyObject *w) | |
| 817 | +{ | |
| 818 | + return PyObject_Compare(v->dict, w); | |
| 819 | +} | |
| 820 | + | |
| 821 | +static PyObject * | |
| 822 | +proxy_richcompare(proxyobject *v, PyObject *w, int op) | |
| 823 | +{ | |
| 824 | + return PyObject_RichCompare(v->dict, w, op); | |
| 825 | +} | |
| 826 | + | |
| 827 | +static PyTypeObject proxytype = { | |
| 828 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 829 | + 0, /* ob_size */ | |
| 830 | + "dictproxy", /* tp_name */ | |
| 831 | + sizeof(proxyobject), /* tp_basicsize */ | |
| 832 | + 0, /* tp_itemsize */ | |
| 833 | + /* methods */ | |
| 834 | + (destructor)proxy_dealloc, /* tp_dealloc */ | |
| 835 | + 0, /* tp_print */ | |
| 836 | + 0, /* tp_getattr */ | |
| 837 | + 0, /* tp_setattr */ | |
| 838 | + (cmpfunc)proxy_compare, /* tp_compare */ | |
| 839 | + 0, /* tp_repr */ | |
| 840 | + 0, /* tp_as_number */ | |
| 841 | + &proxy_as_sequence, /* tp_as_sequence */ | |
| 842 | + &proxy_as_mapping, /* tp_as_mapping */ | |
| 843 | + 0, /* tp_hash */ | |
| 844 | + 0, /* tp_call */ | |
| 845 | + (reprfunc)proxy_str, /* tp_str */ | |
| 846 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 847 | + 0, /* tp_setattro */ | |
| 848 | + 0, /* tp_as_buffer */ | |
| 849 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ | |
| 850 | + 0, /* tp_doc */ | |
| 851 | + proxy_traverse, /* tp_traverse */ | |
| 852 | + 0, /* tp_clear */ | |
| 853 | + (richcmpfunc)proxy_richcompare, /* tp_richcompare */ | |
| 854 | + 0, /* tp_weaklistoffset */ | |
| 855 | + (getiterfunc)proxy_getiter, /* tp_iter */ | |
| 856 | + 0, /* tp_iternext */ | |
| 857 | + proxy_methods, /* tp_methods */ | |
| 858 | + 0, /* tp_members */ | |
| 859 | + 0, /* tp_getset */ | |
| 860 | + 0, /* tp_base */ | |
| 861 | + 0, /* tp_dict */ | |
| 862 | + 0, /* tp_descr_get */ | |
| 863 | + 0, /* tp_descr_set */ | |
| 864 | +}; | |
| 865 | + | |
| 866 | +PyObject * | |
| 867 | +PyDictProxy_New(PyObject *dict) | |
| 868 | +{ | |
| 869 | + proxyobject *pp; | |
| 870 | + | |
| 871 | + pp = PyObject_GC_New(proxyobject, &proxytype); | |
| 872 | + if (pp != NULL) { | |
| 873 | + Py_INCREF(dict); | |
| 874 | + pp->dict = dict; | |
| 875 | + _PyObject_GC_TRACK(pp); | |
| 876 | + } | |
| 877 | + return (PyObject *)pp; | |
| 878 | +} | |
| 879 | + | |
| 880 | + | |
| 881 | +/* --- Wrapper object for "slot" methods --- */ | |
| 882 | + | |
| 883 | +/* This has no reason to be in this file except that adding new files is a | |
| 884 | + bit of a pain */ | |
| 885 | + | |
| 886 | +typedef struct { | |
| 887 | + PyObject_HEAD | |
| 888 | + PyWrapperDescrObject *descr; | |
| 889 | + PyObject *self; | |
| 890 | +} wrapperobject; | |
| 891 | + | |
| 892 | +static void | |
| 893 | +wrapper_dealloc(wrapperobject *wp) | |
| 894 | +{ | |
| 895 | + PyObject_GC_UnTrack(wp); | |
| 896 | + Py_TRASHCAN_SAFE_BEGIN(wp) | |
| 897 | + Py_XDECREF(wp->descr); | |
| 898 | + Py_XDECREF(wp->self); | |
| 899 | + PyObject_GC_Del(wp); | |
| 900 | + Py_TRASHCAN_SAFE_END(wp) | |
| 901 | +} | |
| 902 | + | |
| 903 | +static int | |
| 904 | +wrapper_compare(wrapperobject *a, wrapperobject *b) | |
| 905 | +{ | |
| 906 | + if (a->descr == b->descr) | |
| 907 | + return PyObject_Compare(a->self, b->self); | |
| 908 | + else | |
| 909 | + return (a->descr < b->descr) ? -1 : 1; | |
| 910 | +} | |
| 911 | + | |
| 912 | +static long | |
| 913 | +wrapper_hash(wrapperobject *wp) | |
| 914 | +{ | |
| 915 | + int x, y; | |
| 916 | + x = _Py_HashPointer(wp->descr); | |
| 917 | + if (x == -1) | |
| 918 | + return -1; | |
| 919 | + y = PyObject_Hash(wp->self); | |
| 920 | + if (y == -1) | |
| 921 | + return -1; | |
| 922 | + x = x ^ y; | |
| 923 | + if (x == -1) | |
| 924 | + x = -2; | |
| 925 | + return x; | |
| 926 | +} | |
| 927 | + | |
| 928 | +static PyObject * | |
| 929 | +wrapper_repr(wrapperobject *wp) | |
| 930 | +{ | |
| 931 | + return PyString_FromFormat("<method-wrapper '%s' of %s object at %p>", | |
| 932 | + wp->descr->d_base->name, | |
| 933 | + wp->self->ob_type->tp_name, | |
| 934 | + wp->self); | |
| 935 | +} | |
| 936 | + | |
| 937 | +static PyMemberDef wrapper_members[] = { | |
| 938 | + {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY}, | |
| 939 | + {0} | |
| 940 | +}; | |
| 941 | + | |
| 942 | +static PyObject * | |
| 943 | +wrapper_objclass(wrapperobject *wp) | |
| 944 | +{ | |
| 945 | + PyObject *c = (PyObject *)wp->descr->d_type; | |
| 946 | + | |
| 947 | + Py_INCREF(c); | |
| 948 | + return c; | |
| 949 | +} | |
| 950 | + | |
| 951 | +static PyObject * | |
| 952 | +wrapper_name(wrapperobject *wp) | |
| 953 | +{ | |
| 954 | + char *s = wp->descr->d_base->name; | |
| 955 | + | |
| 956 | + return PyString_FromString(s); | |
| 957 | +} | |
| 958 | + | |
| 959 | +static PyObject * | |
| 960 | +wrapper_doc(wrapperobject *wp) | |
| 961 | +{ | |
| 962 | + char *s = wp->descr->d_base->doc; | |
| 963 | + | |
| 964 | + if (s == NULL) { | |
| 965 | + Py_INCREF(Py_None); | |
| 966 | + return Py_None; | |
| 967 | + } | |
| 968 | + else { | |
| 969 | + return PyString_FromString(s); | |
| 970 | + } | |
| 971 | +} | |
| 972 | + | |
| 973 | +static PyGetSetDef wrapper_getsets[] = { | |
| 974 | + {"__objclass__", (getter)wrapper_objclass}, | |
| 975 | + {"__name__", (getter)wrapper_name}, | |
| 976 | + {"__doc__", (getter)wrapper_doc}, | |
| 977 | + {0} | |
| 978 | +}; | |
| 979 | + | |
| 980 | +static PyObject * | |
| 981 | +wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) | |
| 982 | +{ | |
| 983 | + wrapperfunc wrapper = wp->descr->d_base->wrapper; | |
| 984 | + PyObject *self = wp->self; | |
| 985 | + | |
| 986 | + if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) { | |
| 987 | + wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; | |
| 988 | + return (*wk)(self, args, wp->descr->d_wrapped, kwds); | |
| 989 | + } | |
| 990 | + | |
| 991 | + if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) { | |
| 992 | + PyErr_Format(PyExc_TypeError, | |
| 993 | + "wrapper %s doesn't take keyword arguments", | |
| 994 | + wp->descr->d_base->name); | |
| 995 | + return NULL; | |
| 996 | + } | |
| 997 | + return (*wrapper)(self, args, wp->descr->d_wrapped); | |
| 998 | +} | |
| 999 | + | |
| 1000 | +static int | |
| 1001 | +wrapper_traverse(PyObject *self, visitproc visit, void *arg) | |
| 1002 | +{ | |
| 1003 | + wrapperobject *wp = (wrapperobject *)self; | |
| 1004 | + Py_VISIT(wp->descr); | |
| 1005 | + Py_VISIT(wp->self); | |
| 1006 | + return 0; | |
| 1007 | +} | |
| 1008 | + | |
| 1009 | +static PyTypeObject wrappertype = { | |
| 1010 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 1011 | + 0, /* ob_size */ | |
| 1012 | + "method-wrapper", /* tp_name */ | |
| 1013 | + sizeof(wrapperobject), /* tp_basicsize */ | |
| 1014 | + 0, /* tp_itemsize */ | |
| 1015 | + /* methods */ | |
| 1016 | + (destructor)wrapper_dealloc, /* tp_dealloc */ | |
| 1017 | + 0, /* tp_print */ | |
| 1018 | + 0, /* tp_getattr */ | |
| 1019 | + 0, /* tp_setattr */ | |
| 1020 | + (cmpfunc)wrapper_compare, /* tp_compare */ | |
| 1021 | + (reprfunc)wrapper_repr, /* tp_repr */ | |
| 1022 | + 0, /* tp_as_number */ | |
| 1023 | + 0, /* tp_as_sequence */ | |
| 1024 | + 0, /* tp_as_mapping */ | |
| 1025 | + (hashfunc)wrapper_hash, /* tp_hash */ | |
| 1026 | + (ternaryfunc)wrapper_call, /* tp_call */ | |
| 1027 | + 0, /* tp_str */ | |
| 1028 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 1029 | + 0, /* tp_setattro */ | |
| 1030 | + 0, /* tp_as_buffer */ | |
| 1031 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ | |
| 1032 | + 0, /* tp_doc */ | |
| 1033 | + wrapper_traverse, /* tp_traverse */ | |
| 1034 | + 0, /* tp_clear */ | |
| 1035 | + 0, /* tp_richcompare */ | |
| 1036 | + 0, /* tp_weaklistoffset */ | |
| 1037 | + 0, /* tp_iter */ | |
| 1038 | + 0, /* tp_iternext */ | |
| 1039 | + 0, /* tp_methods */ | |
| 1040 | + wrapper_members, /* tp_members */ | |
| 1041 | + wrapper_getsets, /* tp_getset */ | |
| 1042 | + 0, /* tp_base */ | |
| 1043 | + 0, /* tp_dict */ | |
| 1044 | + 0, /* tp_descr_get */ | |
| 1045 | + 0, /* tp_descr_set */ | |
| 1046 | +}; | |
| 1047 | + | |
| 1048 | +PyObject * | |
| 1049 | +PyWrapper_New(PyObject *d, PyObject *self) | |
| 1050 | +{ | |
| 1051 | + wrapperobject *wp; | |
| 1052 | + PyWrapperDescrObject *descr; | |
| 1053 | + | |
| 1054 | + assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); | |
| 1055 | + descr = (PyWrapperDescrObject *)d; | |
| 1056 | + assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type))); | |
| 1057 | + | |
| 1058 | + wp = PyObject_GC_New(wrapperobject, &wrappertype); | |
| 1059 | + if (wp != NULL) { | |
| 1060 | + Py_INCREF(descr); | |
| 1061 | + wp->descr = descr; | |
| 1062 | + Py_INCREF(self); | |
| 1063 | + wp->self = self; | |
| 1064 | + _PyObject_GC_TRACK(wp); | |
| 1065 | + } | |
| 1066 | + return (PyObject *)wp; | |
| 1067 | +} | |
| 1068 | + | |
| 1069 | + | |
| 1070 | +/* A built-in 'property' type */ | |
| 1071 | + | |
| 1072 | +/* | |
| 1073 | + class property(object): | |
| 1074 | + | |
| 1075 | + def __init__(self, fget=None, fset=None, fdel=None, doc=None): | |
| 1076 | + if doc is None and fget is not None and hasattr(fget, "__doc__"): | |
| 1077 | + doc = fget.__doc__ | |
| 1078 | + self.__get = fget | |
| 1079 | + self.__set = fset | |
| 1080 | + self.__del = fdel | |
| 1081 | + self.__doc__ = doc | |
| 1082 | + | |
| 1083 | + def __get__(self, inst, type=None): | |
| 1084 | + if inst is None: | |
| 1085 | + return self | |
| 1086 | + if self.__get is None: | |
| 1087 | + raise AttributeError, "unreadable attribute" | |
| 1088 | + return self.__get(inst) | |
| 1089 | + | |
| 1090 | + def __set__(self, inst, value): | |
| 1091 | + if self.__set is None: | |
| 1092 | + raise AttributeError, "can't set attribute" | |
| 1093 | + return self.__set(inst, value) | |
| 1094 | + | |
| 1095 | + def __delete__(self, inst): | |
| 1096 | + if self.__del is None: | |
| 1097 | + raise AttributeError, "can't delete attribute" | |
| 1098 | + return self.__del(inst) | |
| 1099 | + | |
| 1100 | +*/ | |
| 1101 | + | |
| 1102 | +typedef struct { | |
| 1103 | + PyObject_HEAD | |
| 1104 | + PyObject *prop_get; | |
| 1105 | + PyObject *prop_set; | |
| 1106 | + PyObject *prop_del; | |
| 1107 | + PyObject *prop_doc; | |
| 1108 | +} propertyobject; | |
| 1109 | + | |
| 1110 | +static PyMemberDef property_members[] = { | |
| 1111 | + {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, | |
| 1112 | + {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY}, | |
| 1113 | + {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY}, | |
| 1114 | + {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), READONLY}, | |
| 1115 | + {0} | |
| 1116 | +}; | |
| 1117 | + | |
| 1118 | + | |
| 1119 | +static void | |
| 1120 | +property_dealloc(PyObject *self) | |
| 1121 | +{ | |
| 1122 | + propertyobject *gs = (propertyobject *)self; | |
| 1123 | + | |
| 1124 | + _PyObject_GC_UNTRACK(self); | |
| 1125 | + Py_XDECREF(gs->prop_get); | |
| 1126 | + Py_XDECREF(gs->prop_set); | |
| 1127 | + Py_XDECREF(gs->prop_del); | |
| 1128 | + Py_XDECREF(gs->prop_doc); | |
| 1129 | + self->ob_type->tp_free(self); | |
| 1130 | +} | |
| 1131 | + | |
| 1132 | +static PyObject * | |
| 1133 | +property_descr_get(PyObject *self, PyObject *obj, PyObject *type) | |
| 1134 | +{ | |
| 1135 | + propertyobject *gs = (propertyobject *)self; | |
| 1136 | + | |
| 1137 | + if (obj == NULL || obj == Py_None) { | |
| 1138 | + Py_INCREF(self); | |
| 1139 | + return self; | |
| 1140 | + } | |
| 1141 | + if (gs->prop_get == NULL) { | |
| 1142 | + PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); | |
| 1143 | + return NULL; | |
| 1144 | + } | |
| 1145 | + return PyObject_CallFunction(gs->prop_get, "(O)", obj); | |
| 1146 | +} | |
| 1147 | + | |
| 1148 | +static int | |
| 1149 | +property_descr_set(PyObject *self, PyObject *obj, PyObject *value) | |
| 1150 | +{ | |
| 1151 | + propertyobject *gs = (propertyobject *)self; | |
| 1152 | + PyObject *func, *res; | |
| 1153 | + | |
| 1154 | + if (value == NULL) | |
| 1155 | + func = gs->prop_del; | |
| 1156 | + else | |
| 1157 | + func = gs->prop_set; | |
| 1158 | + if (func == NULL) { | |
| 1159 | + PyErr_SetString(PyExc_AttributeError, | |
| 1160 | + value == NULL ? | |
| 1161 | + "can't delete attribute" : | |
| 1162 | + "can't set attribute"); | |
| 1163 | + return -1; | |
| 1164 | + } | |
| 1165 | + if (value == NULL) | |
| 1166 | + res = PyObject_CallFunction(func, "(O)", obj); | |
| 1167 | + else | |
| 1168 | + res = PyObject_CallFunction(func, "(OO)", obj, value); | |
| 1169 | + if (res == NULL) | |
| 1170 | + return -1; | |
| 1171 | + Py_DECREF(res); | |
| 1172 | + return 0; | |
| 1173 | +} | |
| 1174 | + | |
| 1175 | +static int | |
| 1176 | +property_init(PyObject *self, PyObject *args, PyObject *kwds) | |
| 1177 | +{ | |
| 1178 | + PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL; | |
| 1179 | + static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0}; | |
| 1180 | + propertyobject *gs = (propertyobject *)self; | |
| 1181 | + | |
| 1182 | + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property", | |
| 1183 | + kwlist, &get, &set, &del, &doc)) | |
| 1184 | + return -1; | |
| 1185 | + | |
| 1186 | + if (get == Py_None) | |
| 1187 | + get = NULL; | |
| 1188 | + if (set == Py_None) | |
| 1189 | + set = NULL; | |
| 1190 | + if (del == Py_None) | |
| 1191 | + del = NULL; | |
| 1192 | + | |
| 1193 | + Py_XINCREF(get); | |
| 1194 | + Py_XINCREF(set); | |
| 1195 | + Py_XINCREF(del); | |
| 1196 | + Py_XINCREF(doc); | |
| 1197 | + | |
| 1198 | + /* if no docstring given and the getter has one, use that one */ | |
| 1199 | + if ((doc == NULL || doc == Py_None) && get != NULL) { | |
| 1200 | + PyObject *get_doc = PyObject_GetAttrString(get, "__doc__"); | |
| 1201 | + if (get_doc != NULL) { | |
| 1202 | + Py_XDECREF(doc); | |
| 1203 | + doc = get_doc; /* get_doc already INCREF'd by GetAttr */ | |
| 1204 | + } else { | |
| 1205 | + PyErr_Clear(); | |
| 1206 | + } | |
| 1207 | + } | |
| 1208 | + | |
| 1209 | + gs->prop_get = get; | |
| 1210 | + gs->prop_set = set; | |
| 1211 | + gs->prop_del = del; | |
| 1212 | + gs->prop_doc = doc; | |
| 1213 | + | |
| 1214 | + return 0; | |
| 1215 | +} | |
| 1216 | + | |
| 1217 | +PyDoc_STRVAR(property_doc, | |
| 1218 | +"property(fget=None, fset=None, fdel=None, doc=None) -> property attribute\n" | |
| 1219 | +"\n" | |
| 1220 | +"fget is a function to be used for getting an attribute value, and likewise\n" | |
| 1221 | +"fset is a function for setting, and fdel a function for del'ing, an\n" | |
| 1222 | +"attribute. Typical use is to define a managed attribute x:\n" | |
| 1223 | +"class C(object):\n" | |
| 1224 | +" def getx(self): return self.__x\n" | |
| 1225 | +" def setx(self, value): self.__x = value\n" | |
| 1226 | +" def delx(self): del self.__x\n" | |
| 1227 | +" x = property(getx, setx, delx, \"I'm the 'x' property.\")"); | |
| 1228 | + | |
| 1229 | +static int | |
| 1230 | +property_traverse(PyObject *self, visitproc visit, void *arg) | |
| 1231 | +{ | |
| 1232 | + propertyobject *pp = (propertyobject *)self; | |
| 1233 | + Py_VISIT(pp->prop_get); | |
| 1234 | + Py_VISIT(pp->prop_set); | |
| 1235 | + Py_VISIT(pp->prop_del); | |
| 1236 | + Py_VISIT(pp->prop_doc); | |
| 1237 | + return 0; | |
| 1238 | +} | |
| 1239 | + | |
| 1240 | +PyTypeObject PyProperty_Type = { | |
| 1241 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 1242 | + 0, /* ob_size */ | |
| 1243 | + "property", /* tp_name */ | |
| 1244 | + sizeof(propertyobject), /* tp_basicsize */ | |
| 1245 | + 0, /* tp_itemsize */ | |
| 1246 | + /* methods */ | |
| 1247 | + property_dealloc, /* tp_dealloc */ | |
| 1248 | + 0, /* tp_print */ | |
| 1249 | + 0, /* tp_getattr */ | |
| 1250 | + 0, /* tp_setattr */ | |
| 1251 | + 0, /* tp_compare */ | |
| 1252 | + 0, /* tp_repr */ | |
| 1253 | + 0, /* tp_as_number */ | |
| 1254 | + 0, /* tp_as_sequence */ | |
| 1255 | + 0, /* tp_as_mapping */ | |
| 1256 | + 0, /* tp_hash */ | |
| 1257 | + 0, /* tp_call */ | |
| 1258 | + 0, /* tp_str */ | |
| 1259 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 1260 | + 0, /* tp_setattro */ | |
| 1261 | + 0, /* tp_as_buffer */ | |
| 1262 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | |
| 1263 | + Py_TPFLAGS_BASETYPE, /* tp_flags */ | |
| 1264 | + property_doc, /* tp_doc */ | |
| 1265 | + property_traverse, /* tp_traverse */ | |
| 1266 | + 0, /* tp_clear */ | |
| 1267 | + 0, /* tp_richcompare */ | |
| 1268 | + 0, /* tp_weaklistoffset */ | |
| 1269 | + 0, /* tp_iter */ | |
| 1270 | + 0, /* tp_iternext */ | |
| 1271 | + 0, /* tp_methods */ | |
| 1272 | + property_members, /* tp_members */ | |
| 1273 | + 0, /* tp_getset */ | |
| 1274 | + 0, /* tp_base */ | |
| 1275 | + 0, /* tp_dict */ | |
| 1276 | + property_descr_get, /* tp_descr_get */ | |
| 1277 | + property_descr_set, /* tp_descr_set */ | |
| 1278 | + 0, /* tp_dictoffset */ | |
| 1279 | + property_init, /* tp_init */ | |
| 1280 | + PyType_GenericAlloc, /* tp_alloc */ | |
| 1281 | + PyType_GenericNew, /* tp_new */ | |
| 1282 | + PyObject_GC_Del, /* tp_free */ | |
| 1283 | +}; | |
| @@ -0,0 +1,250 @@ | ||
| 1 | +NOTES ON OPTIMIZING DICTIONARIES | |
| 2 | +================================ | |
| 3 | + | |
| 4 | + | |
| 5 | +Principal Use Cases for Dictionaries | |
| 6 | +------------------------------------ | |
| 7 | + | |
| 8 | +Passing keyword arguments | |
| 9 | + Typically, one read and one write for 1 to 3 elements. | |
| 10 | + Occurs frequently in normal python code. | |
| 11 | + | |
| 12 | +Class method lookup | |
| 13 | + Dictionaries vary in size with 8 to 16 elements being common. | |
| 14 | + Usually written once with many lookups. | |
| 15 | + When base classes are used, there are many failed lookups | |
| 16 | + followed by a lookup in a base class. | |
| 17 | + | |
| 18 | +Instance attribute lookup and Global variables | |
| 19 | + Dictionaries vary in size. 4 to 10 elements are common. | |
| 20 | + Both reads and writes are common. | |
| 21 | + | |
| 22 | +Builtins | |
| 23 | + Frequent reads. Almost never written. | |
| 24 | + Size 126 interned strings (as of Py2.3b1). | |
| 25 | + A few keys are accessed much more frequently than others. | |
| 26 | + | |
| 27 | +Uniquification | |
| 28 | + Dictionaries of any size. Bulk of work is in creation. | |
| 29 | + Repeated writes to a smaller set of keys. | |
| 30 | + Single read of each key. | |
| 31 | + Some use cases have two consecutive accesses to the same key. | |
| 32 | + | |
| 33 | + * Removing duplicates from a sequence. | |
| 34 | + dict.fromkeys(seqn).keys() | |
| 35 | + | |
| 36 | + * Counting elements in a sequence. | |
| 37 | + for e in seqn: | |
| 38 | + d[e] = d.get(e,0) + 1 | |
| 39 | + | |
| 40 | + * Accumulating references in a dictionary of lists: | |
| 41 | + | |
| 42 | + for pagenumber, page in enumerate(pages): | |
| 43 | + for word in page: | |
| 44 | + d.setdefault(word, []).append(pagenumber) | |
| 45 | + | |
| 46 | + Note, the second example is a use case characterized by a get and set | |
| 47 | + to the same key. There are similar used cases with a __contains__ | |
| 48 | + followed by a get, set, or del to the same key. Part of the | |
| 49 | + justification for d.setdefault is combining the two lookups into one. | |
| 50 | + | |
| 51 | +Membership Testing | |
| 52 | + Dictionaries of any size. Created once and then rarely changes. | |
| 53 | + Single write to each key. | |
| 54 | + Many calls to __contains__() or has_key(). | |
| 55 | + Similar access patterns occur with replacement dictionaries | |
| 56 | + such as with the % formatting operator. | |
| 57 | + | |
| 58 | +Dynamic Mappings | |
| 59 | + Characterized by deletions interspersed with adds and replacements. | |
| 60 | + Performance benefits greatly from the re-use of dummy entries. | |
| 61 | + | |
| 62 | + | |
| 63 | +Data Layout (assuming a 32-bit box with 64 bytes per cache line) | |
| 64 | +---------------------------------------------------------------- | |
| 65 | + | |
| 66 | +Smalldicts (8 entries) are attached to the dictobject structure | |
| 67 | +and the whole group nearly fills two consecutive cache lines. | |
| 68 | + | |
| 69 | +Larger dicts use the first half of the dictobject structure (one cache | |
| 70 | +line) and a separate, continuous block of entries (at 12 bytes each | |
| 71 | +for a total of 5.333 entries per cache line). | |
| 72 | + | |
| 73 | + | |
| 74 | +Tunable Dictionary Parameters | |
| 75 | +----------------------------- | |
| 76 | + | |
| 77 | +* PyDict_MINSIZE. Currently set to 8. | |
| 78 | + Must be a power of two. New dicts have to zero-out every cell. | |
| 79 | + Each additional 8 consumes 1.5 cache lines. Increasing improves | |
| 80 | + the sparseness of small dictionaries but costs time to read in | |
| 81 | + the additional cache lines if they are not already in cache. | |
| 82 | + That case is common when keyword arguments are passed. | |
| 83 | + | |
| 84 | +* Maximum dictionary load in PyDict_SetItem. Currently set to 2/3. | |
| 85 | + Increasing this ratio makes dictionaries more dense resulting | |
| 86 | + in more collisions. Decreasing it improves sparseness at the | |
| 87 | + expense of spreading entries over more cache lines and at the | |
| 88 | + cost of total memory consumed. | |
| 89 | + | |
| 90 | + The load test occurs in highly time sensitive code. Efforts | |
| 91 | + to make the test more complex (for example, varying the load | |
| 92 | + for different sizes) have degraded performance. | |
| 93 | + | |
| 94 | +* Growth rate upon hitting maximum load. Currently set to *2. | |
| 95 | + Raising this to *4 results in half the number of resizes, | |
| 96 | + less effort to resize, better sparseness for some (but not | |
| 97 | + all dict sizes), and potentially doubles memory consumption | |
| 98 | + depending on the size of the dictionary. Setting to *4 | |
| 99 | + eliminates every other resize step. | |
| 100 | + | |
| 101 | +Tune-ups should be measured across a broad range of applications and | |
| 102 | +use cases. A change to any parameter will help in some situations and | |
| 103 | +hurt in others. The key is to find settings that help the most common | |
| 104 | +cases and do the least damage to the less common cases. Results will | |
| 105 | +vary dramatically depending on the exact number of keys, whether the | |
| 106 | +keys are all strings, whether reads or writes dominate, the exact | |
| 107 | +hash values of the keys (some sets of values have fewer collisions than | |
| 108 | +others). Any one test or benchmark is likely to prove misleading. | |
| 109 | + | |
| 110 | +While making a dictionary more sparse reduces collisions, it impairs | |
| 111 | +iteration and key listing. Those methods loop over every potential | |
| 112 | +entry. Doubling the size of dictionary results in twice as many | |
| 113 | +non-overlapping memory accesses for keys(), items(), values(), | |
| 114 | +__iter__(), iterkeys(), iteritems(), itervalues(), and update(). | |
| 115 | +Also, every dictionary iterates at least twice, once for the memset() | |
| 116 | +when it is created and once by dealloc(). | |
| 117 | + | |
| 118 | + | |
| 119 | +Results of Cache Locality Experiments | |
| 120 | +------------------------------------- | |
| 121 | + | |
| 122 | +When an entry is retrieved from memory, 4.333 adjacent entries are also | |
| 123 | +retrieved into a cache line. Since accessing items in cache is *much* | |
| 124 | +cheaper than a cache miss, an enticing idea is to probe the adjacent | |
| 125 | +entries as a first step in collision resolution. Unfortunately, the | |
| 126 | +introduction of any regularity into collision searches results in more | |
| 127 | +collisions than the current random chaining approach. | |
| 128 | + | |
| 129 | +Exploiting cache locality at the expense of additional collisions fails | |
| 130 | +to payoff when the entries are already loaded in cache (the expense | |
| 131 | +is paid with no compensating benefit). This occurs in small dictionaries | |
| 132 | +where the whole dictionary fits into a pair of cache lines. It also | |
| 133 | +occurs frequently in large dictionaries which have a common access pattern | |
| 134 | +where some keys are accessed much more frequently than others. The | |
| 135 | +more popular entries *and* their collision chains tend to remain in cache. | |
| 136 | + | |
| 137 | +To exploit cache locality, change the collision resolution section | |
| 138 | +in lookdict() and lookdict_string(). Set i^=1 at the top of the | |
| 139 | +loop and move the i = (i << 2) + i + perturb + 1 to an unrolled | |
| 140 | +version of the loop. | |
| 141 | + | |
| 142 | +This optimization strategy can be leveraged in several ways: | |
| 143 | + | |
| 144 | +* If the dictionary is kept sparse (through the tunable parameters), | |
| 145 | +then the occurrence of additional collisions is lessened. | |
| 146 | + | |
| 147 | +* If lookdict() and lookdict_string() are specialized for small dicts | |
| 148 | +and for largedicts, then the versions for large_dicts can be given | |
| 149 | +an alternate search strategy without increasing collisions in small dicts | |
| 150 | +which already have the maximum benefit of cache locality. | |
| 151 | + | |
| 152 | +* If the use case for a dictionary is known to have a random key | |
| 153 | +access pattern (as opposed to a more common pattern with a Zipf's law | |
| 154 | +distribution), then there will be more benefit for large dictionaries | |
| 155 | +because any given key is no more likely than another to already be | |
| 156 | +in cache. | |
| 157 | + | |
| 158 | +* In use cases with paired accesses to the same key, the second access | |
| 159 | +is always in cache and gets no benefit from efforts to further improve | |
| 160 | +cache locality. | |
| 161 | + | |
| 162 | +Optimizing the Search of Small Dictionaries | |
| 163 | +------------------------------------------- | |
| 164 | + | |
| 165 | +If lookdict() and lookdict_string() are specialized for smaller dictionaries, | |
| 166 | +then a custom search approach can be implemented that exploits the small | |
| 167 | +search space and cache locality. | |
| 168 | + | |
| 169 | +* The simplest example is a linear search of contiguous entries. This is | |
| 170 | + simple to implement, guaranteed to terminate rapidly, never searches | |
| 171 | + the same entry twice, and precludes the need to check for dummy entries. | |
| 172 | + | |
| 173 | +* A more advanced example is a self-organizing search so that the most | |
| 174 | + frequently accessed entries get probed first. The organization | |
| 175 | + adapts if the access pattern changes over time. Treaps are ideally | |
| 176 | + suited for self-organization with the most common entries at the | |
| 177 | + top of the heap and a rapid binary search pattern. Most probes and | |
| 178 | + results are all located at the top of the tree allowing them all to | |
| 179 | + be located in one or two cache lines. | |
| 180 | + | |
| 181 | +* Also, small dictionaries may be made more dense, perhaps filling all | |
| 182 | + eight cells to take the maximum advantage of two cache lines. | |
| 183 | + | |
| 184 | + | |
| 185 | +Strategy Pattern | |
| 186 | +---------------- | |
| 187 | + | |
| 188 | +Consider allowing the user to set the tunable parameters or to select a | |
| 189 | +particular search method. Since some dictionary use cases have known | |
| 190 | +sizes and access patterns, the user may be able to provide useful hints. | |
| 191 | + | |
| 192 | +1) For example, if membership testing or lookups dominate runtime and memory | |
| 193 | + is not at a premium, the user may benefit from setting the maximum load | |
| 194 | + ratio at 5% or 10% instead of the usual 66.7%. This will sharply | |
| 195 | + curtail the number of collisions but will increase iteration time. | |
| 196 | + The builtin namespace is a prime example of a dictionary that can | |
| 197 | + benefit from being highly sparse. | |
| 198 | + | |
| 199 | +2) Dictionary creation time can be shortened in cases where the ultimate | |
| 200 | + size of the dictionary is known in advance. The dictionary can be | |
| 201 | + pre-sized so that no resize operations are required during creation. | |
| 202 | + Not only does this save resizes, but the key insertion will go | |
| 203 | + more quickly because the first half of the keys will be inserted into | |
| 204 | + a more sparse environment than before. The preconditions for this | |
| 205 | + strategy arise whenever a dictionary is created from a key or item | |
| 206 | + sequence and the number of *unique* keys is known. | |
| 207 | + | |
| 208 | +3) If the key space is large and the access pattern is known to be random, | |
| 209 | + then search strategies exploiting cache locality can be fruitful. | |
| 210 | + The preconditions for this strategy arise in simulations and | |
| 211 | + numerical analysis. | |
| 212 | + | |
| 213 | +4) If the keys are fixed and the access pattern strongly favors some of | |
| 214 | + the keys, then the entries can be stored contiguously and accessed | |
| 215 | + with a linear search or treap. This exploits knowledge of the data, | |
| 216 | + cache locality, and a simplified search routine. It also eliminates | |
| 217 | + the need to test for dummy entries on each probe. The preconditions | |
| 218 | + for this strategy arise in symbol tables and in the builtin dictionary. | |
| 219 | + | |
| 220 | + | |
| 221 | +Readonly Dictionaries | |
| 222 | +--------------------- | |
| 223 | +Some dictionary use cases pass through a build stage and then move to a | |
| 224 | +more heavily exercised lookup stage with no further changes to the | |
| 225 | +dictionary. | |
| 226 | + | |
| 227 | +An idea that emerged on python-dev is to be able to convert a dictionary | |
| 228 | +to a read-only state. This can help prevent programming errors and also | |
| 229 | +provide knowledge that can be exploited for lookup optimization. | |
| 230 | + | |
| 231 | +The dictionary can be immediately rebuilt (eliminating dummy entries), | |
| 232 | +resized (to an appropriate level of sparseness), and the keys can be | |
| 233 | +jostled (to minimize collisions). The lookdict() routine can then | |
| 234 | +eliminate the test for dummy entries (saving about 1/4 of the time | |
| 235 | +spent in the collision resolution loop). | |
| 236 | + | |
| 237 | +An additional possibility is to insert links into the empty spaces | |
| 238 | +so that dictionary iteration can proceed in len(d) steps instead of | |
| 239 | +(mp->mask + 1) steps. Alternatively, a separate tuple of keys can be | |
| 240 | +kept just for iteration. | |
| 241 | + | |
| 242 | + | |
| 243 | +Caching Lookups | |
| 244 | +--------------- | |
| 245 | +The idea is to exploit key access patterns by anticipating future lookups | |
| 246 | +based on previous lookups. | |
| 247 | + | |
| 248 | +The simplest incarnation is to save the most recently accessed entry. | |
| 249 | +This gives optimal performance for use cases where every get is followed | |
| 250 | +by a set or del to the same key. | |
| @@ -0,0 +1,2486 @@ | ||
| 1 | + | |
| 2 | +/* Dictionary object implementation using a hash table */ | |
| 3 | + | |
| 4 | +/* The distribution includes a separate file, Objects/dictnotes.txt, | |
| 5 | + describing explorations into dictionary design and optimization. | |
| 6 | + It covers typical dictionary use patterns, the parameters for | |
| 7 | + tuning dictionaries, and several ideas for possible optimizations. | |
| 8 | +*/ | |
| 9 | + | |
| 10 | +#include "Python.h" | |
| 11 | + | |
| 12 | +typedef PyDictEntry dictentry; | |
| 13 | +typedef PyDictObject dictobject; | |
| 14 | + | |
| 15 | +/* Set a key error with the specified argument, wrapping it in a | |
| 16 | + * tuple automatically so that tuple keys are not unpacked as the | |
| 17 | + * exception arguments. */ | |
| 18 | +static void | |
| 19 | +set_key_error(PyObject *arg) | |
| 20 | +{ | |
| 21 | + PyObject *tup; | |
| 22 | + tup = PyTuple_Pack(1, arg); | |
| 23 | + if (!tup) | |
| 24 | + return; /* caller will expect error to be set anyway */ | |
| 25 | + PyErr_SetObject(PyExc_KeyError, tup); | |
| 26 | + Py_DECREF(tup); | |
| 27 | +} | |
| 28 | + | |
| 29 | +/* Define this out if you don't want conversion statistics on exit. */ | |
| 30 | +#undef SHOW_CONVERSION_COUNTS | |
| 31 | + | |
| 32 | +/* See large comment block below. This must be >= 1. */ | |
| 33 | +#define PERTURB_SHIFT 5 | |
| 34 | + | |
| 35 | +/* | |
| 36 | +Major subtleties ahead: Most hash schemes depend on having a "good" hash | |
| 37 | +function, in the sense of simulating randomness. Python doesn't: its most | |
| 38 | +important hash functions (for strings and ints) are very regular in common | |
| 39 | +cases: | |
| 40 | + | |
| 41 | +>>> map(hash, (0, 1, 2, 3)) | |
| 42 | +[0, 1, 2, 3] | |
| 43 | +>>> map(hash, ("namea", "nameb", "namec", "named")) | |
| 44 | +[-1658398457, -1658398460, -1658398459, -1658398462] | |
| 45 | +>>> | |
| 46 | + | |
| 47 | +This isn't necessarily bad! To the contrary, in a table of size 2**i, taking | |
| 48 | +the low-order i bits as the initial table index is extremely fast, and there | |
| 49 | +are no collisions at all for dicts indexed by a contiguous range of ints. | |
| 50 | +The same is approximately true when keys are "consecutive" strings. So this | |
| 51 | +gives better-than-random behavior in common cases, and that's very desirable. | |
| 52 | + | |
| 53 | +OTOH, when collisions occur, the tendency to fill contiguous slices of the | |
| 54 | +hash table makes a good collision resolution strategy crucial. Taking only | |
| 55 | +the last i bits of the hash code is also vulnerable: for example, consider | |
| 56 | +[i << 16 for i in range(20000)] as a set of keys. Since ints are their own | |
| 57 | +hash codes, and this fits in a dict of size 2**15, the last 15 bits of every | |
| 58 | +hash code are all 0: they *all* map to the same table index. | |
| 59 | + | |
| 60 | +But catering to unusual cases should not slow the usual ones, so we just take | |
| 61 | +the last i bits anyway. It's up to collision resolution to do the rest. If | |
| 62 | +we *usually* find the key we're looking for on the first try (and, it turns | |
| 63 | +out, we usually do -- the table load factor is kept under 2/3, so the odds | |
| 64 | +are solidly in our favor), then it makes best sense to keep the initial index | |
| 65 | +computation dirt cheap. | |
| 66 | + | |
| 67 | +The first half of collision resolution is to visit table indices via this | |
| 68 | +recurrence: | |
| 69 | + | |
| 70 | + j = ((5*j) + 1) mod 2**i | |
| 71 | + | |
| 72 | +For any initial j in range(2**i), repeating that 2**i times generates each | |
| 73 | +int in range(2**i) exactly once (see any text on random-number generation for | |
| 74 | +proof). By itself, this doesn't help much: like linear probing (setting | |
| 75 | +j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed | |
| 76 | +order. This would be bad, except that's not the only thing we do, and it's | |
| 77 | +actually *good* in the common cases where hash keys are consecutive. In an | |
| 78 | +example that's really too small to make this entirely clear, for a table of | |
| 79 | +size 2**3 the order of indices is: | |
| 80 | + | |
| 81 | + 0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating] | |
| 82 | + | |
| 83 | +If two things come in at index 5, the first place we look after is index 2, | |
| 84 | +not 6, so if another comes in at index 6 the collision at 5 didn't hurt it. | |
| 85 | +Linear probing is deadly in this case because there the fixed probe order | |
| 86 | +is the *same* as the order consecutive keys are likely to arrive. But it's | |
| 87 | +extremely unlikely hash codes will follow a 5*j+1 recurrence by accident, | |
| 88 | +and certain that consecutive hash codes do not. | |
| 89 | + | |
| 90 | +The other half of the strategy is to get the other bits of the hash code | |
| 91 | +into play. This is done by initializing a (unsigned) vrbl "perturb" to the | |
| 92 | +full hash code, and changing the recurrence to: | |
| 93 | + | |
| 94 | + j = (5*j) + 1 + perturb; | |
| 95 | + perturb >>= PERTURB_SHIFT; | |
| 96 | + use j % 2**i as the next table index; | |
| 97 | + | |
| 98 | +Now the probe sequence depends (eventually) on every bit in the hash code, | |
| 99 | +and the pseudo-scrambling property of recurring on 5*j+1 is more valuable, | |
| 100 | +because it quickly magnifies small differences in the bits that didn't affect | |
| 101 | +the initial index. Note that because perturb is unsigned, if the recurrence | |
| 102 | +is executed often enough perturb eventually becomes and remains 0. At that | |
| 103 | +point (very rarely reached) the recurrence is on (just) 5*j+1 again, and | |
| 104 | +that's certain to find an empty slot eventually (since it generates every int | |
| 105 | +in range(2**i), and we make sure there's always at least one empty slot). | |
| 106 | + | |
| 107 | +Selecting a good value for PERTURB_SHIFT is a balancing act. You want it | |
| 108 | +small so that the high bits of the hash code continue to affect the probe | |
| 109 | +sequence across iterations; but you want it large so that in really bad cases | |
| 110 | +the high-order hash bits have an effect on early iterations. 5 was "the | |
| 111 | +best" in minimizing total collisions across experiments Tim Peters ran (on | |
| 112 | +both normal and pathological cases), but 4 and 6 weren't significantly worse. | |
| 113 | + | |
| 114 | +Historical: Reimer Behrends contributed the idea of using a polynomial-based | |
| 115 | +approach, using repeated multiplication by x in GF(2**n) where an irreducible | |
| 116 | +polynomial for each table size was chosen such that x was a primitive root. | |
| 117 | +Christian Tismer later extended that to use division by x instead, as an | |
| 118 | +efficient way to get the high bits of the hash code into play. This scheme | |
| 119 | +also gave excellent collision statistics, but was more expensive: two | |
| 120 | +if-tests were required inside the loop; computing "the next" index took about | |
| 121 | +the same number of operations but without as much potential parallelism | |
| 122 | +(e.g., computing 5*j can go on at the same time as computing 1+perturb in the | |
| 123 | +above, and then shifting perturb can be done while the table index is being | |
| 124 | +masked); and the dictobject struct required a member to hold the table's | |
| 125 | +polynomial. In Tim's experiments the current scheme ran faster, produced | |
| 126 | +equally good collision statistics, needed less code & used less memory. | |
| 127 | + | |
| 128 | +Theoretical Python 2.5 headache: hash codes are only C "long", but | |
| 129 | +sizeof(Py_ssize_t) > sizeof(long) may be possible. In that case, and if a | |
| 130 | +dict is genuinely huge, then only the slots directly reachable via indexing | |
| 131 | +by a C long can be the first slot in a probe sequence. The probe sequence | |
| 132 | +will still eventually reach every slot in the table, but the collision rate | |
| 133 | +on initial probes may be much higher than this scheme was designed for. | |
| 134 | +Getting a hash code as fat as Py_ssize_t is the only real cure. But in | |
| 135 | +practice, this probably won't make a lick of difference for many years (at | |
| 136 | +which point everyone will have terabytes of RAM on 64-bit boxes). | |
| 137 | +*/ | |
| 138 | + | |
| 139 | +/* Object used as dummy key to fill deleted entries */ | |
| 140 | +static PyObject *dummy = NULL; /* Initialized by first call to newdictobject() */ | |
| 141 | + | |
| 142 | +#ifdef Py_REF_DEBUG | |
| 143 | +PyObject * | |
| 144 | +_PyDict_Dummy(void) | |
| 145 | +{ | |
| 146 | + return dummy; | |
| 147 | +} | |
| 148 | +#endif | |
| 149 | + | |
| 150 | +/* forward declarations */ | |
| 151 | +static dictentry * | |
| 152 | +lookdict_string(dictobject *mp, PyObject *key, long hash); | |
| 153 | + | |
| 154 | +#ifdef SHOW_CONVERSION_COUNTS | |
| 155 | +static long created = 0L; | |
| 156 | +static long converted = 0L; | |
| 157 | + | |
| 158 | +static void | |
| 159 | +show_counts(void) | |
| 160 | +{ | |
| 161 | + fprintf(stderr, "created %ld string dicts\n", created); | |
| 162 | + fprintf(stderr, "converted %ld to normal dicts\n", converted); | |
| 163 | + fprintf(stderr, "%.2f%% conversion rate\n", (100.0*converted)/created); | |
| 164 | +} | |
| 165 | +#endif | |
| 166 | + | |
| 167 | +/* Initialization macros. | |
| 168 | + There are two ways to create a dict: PyDict_New() is the main C API | |
| 169 | + function, and the tp_new slot maps to dict_new(). In the latter case we | |
| 170 | + can save a little time over what PyDict_New does because it's guaranteed | |
| 171 | + that the PyDictObject struct is already zeroed out. | |
| 172 | + Everyone except dict_new() should use EMPTY_TO_MINSIZE (unless they have | |
| 173 | + an excellent reason not to). | |
| 174 | +*/ | |
| 175 | + | |
| 176 | +#define INIT_NONZERO_DICT_SLOTS(mp) do { \ | |
| 177 | + (mp)->ma_table = (mp)->ma_smalltable; \ | |
| 178 | + (mp)->ma_mask = PyDict_MINSIZE - 1; \ | |
| 179 | + } while(0) | |
| 180 | + | |
| 181 | +#define EMPTY_TO_MINSIZE(mp) do { \ | |
| 182 | + memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable)); \ | |
| 183 | + (mp)->ma_used = (mp)->ma_fill = 0; \ | |
| 184 | + INIT_NONZERO_DICT_SLOTS(mp); \ | |
| 185 | + } while(0) | |
| 186 | + | |
| 187 | +/* Dictionary reuse scheme to save calls to malloc, free, and memset */ | |
| 188 | +#define MAXFREEDICTS 80 | |
| 189 | +static PyDictObject *free_dicts[MAXFREEDICTS]; | |
| 190 | +static int num_free_dicts = 0; | |
| 191 | + | |
| 192 | +PyObject * | |
| 193 | +PyDict_New(void) | |
| 194 | +{ | |
| 195 | + register dictobject *mp; | |
| 196 | + if (dummy == NULL) { /* Auto-initialize dummy */ | |
| 197 | + dummy = PyString_FromString("<dummy key>"); | |
| 198 | + if (dummy == NULL) | |
| 199 | + return NULL; | |
| 200 | +#ifdef SHOW_CONVERSION_COUNTS | |
| 201 | + Py_AtExit(show_counts); | |
| 202 | +#endif | |
| 203 | + } | |
| 204 | + if (num_free_dicts) { | |
| 205 | + mp = free_dicts[--num_free_dicts]; | |
| 206 | + assert (mp != NULL); | |
| 207 | + assert (mp->ob_type == &PyDict_Type); | |
| 208 | + _Py_NewReference((PyObject *)mp); | |
| 209 | + if (mp->ma_fill) { | |
| 210 | + EMPTY_TO_MINSIZE(mp); | |
| 211 | + } | |
| 212 | + assert (mp->ma_used == 0); | |
| 213 | + assert (mp->ma_table == mp->ma_smalltable); | |
| 214 | + assert (mp->ma_mask == PyDict_MINSIZE - 1); | |
| 215 | + } else { | |
| 216 | + mp = PyObject_GC_New(dictobject, &PyDict_Type); | |
| 217 | + if (mp == NULL) | |
| 218 | + return NULL; | |
| 219 | + EMPTY_TO_MINSIZE(mp); | |
| 220 | + } | |
| 221 | + mp->ma_lookup = lookdict_string; | |
| 222 | +#ifdef SHOW_CONVERSION_COUNTS | |
| 223 | + ++created; | |
| 224 | +#endif | |
| 225 | + _PyObject_GC_TRACK(mp); | |
| 226 | + return (PyObject *)mp; | |
| 227 | +} | |
| 228 | + | |
| 229 | +/* | |
| 230 | +The basic lookup function used by all operations. | |
| 231 | +This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4. | |
| 232 | +Open addressing is preferred over chaining since the link overhead for | |
| 233 | +chaining would be substantial (100% with typical malloc overhead). | |
| 234 | + | |
| 235 | +The initial probe index is computed as hash mod the table size. Subsequent | |
| 236 | +probe indices are computed as explained earlier. | |
| 237 | + | |
| 238 | +All arithmetic on hash should ignore overflow. | |
| 239 | + | |
| 240 | +(The details in this version are due to Tim Peters, building on many past | |
| 241 | +contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and | |
| 242 | +Christian Tismer). | |
| 243 | + | |
| 244 | +lookdict() is general-purpose, and may return NULL if (and only if) a | |
| 245 | +comparison raises an exception (this was new in Python 2.5). | |
| 246 | +lookdict_string() below is specialized to string keys, comparison of which can | |
| 247 | +never raise an exception; that function can never return NULL. For both, when | |
| 248 | +the key isn't found a dictentry* is returned for which the me_value field is | |
| 249 | +NULL; this is the slot in the dict at which the key would have been found, and | |
| 250 | +the caller can (if it wishes) add the <key, value> pair to the returned | |
| 251 | +dictentry*. | |
| 252 | +*/ | |
| 253 | +static dictentry * | |
| 254 | +lookdict(dictobject *mp, PyObject *key, register long hash) | |
| 255 | +{ | |
| 256 | + register size_t i; | |
| 257 | + register size_t perturb; | |
| 258 | + register dictentry *freeslot; | |
| 259 | + register size_t mask = (size_t)mp->ma_mask; | |
| 260 | + dictentry *ep0 = mp->ma_table; | |
| 261 | + register dictentry *ep; | |
| 262 | + register int cmp; | |
| 263 | + PyObject *startkey; | |
| 264 | + | |
| 265 | + i = (size_t)hash & mask; | |
| 266 | + ep = &ep0[i]; | |
| 267 | + if (ep->me_key == NULL || ep->me_key == key) | |
| 268 | + return ep; | |
| 269 | + | |
| 270 | + if (ep->me_key == dummy) | |
| 271 | + freeslot = ep; | |
| 272 | + else { | |
| 273 | + if (ep->me_hash == hash) { | |
| 274 | + startkey = ep->me_key; | |
| 275 | + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); | |
| 276 | + if (cmp < 0) | |
| 277 | + return NULL; | |
| 278 | + if (ep0 == mp->ma_table && ep->me_key == startkey) { | |
| 279 | + if (cmp > 0) | |
| 280 | + return ep; | |
| 281 | + } | |
| 282 | + else { | |
| 283 | + /* The compare did major nasty stuff to the | |
| 284 | + * dict: start over. | |
| 285 | + * XXX A clever adversary could prevent this | |
| 286 | + * XXX from terminating. | |
| 287 | + */ | |
| 288 | + return lookdict(mp, key, hash); | |
| 289 | + } | |
| 290 | + } | |
| 291 | + freeslot = NULL; | |
| 292 | + } | |
| 293 | + | |
| 294 | + /* In the loop, me_key == dummy is by far (factor of 100s) the | |
| 295 | + least likely outcome, so test for that last. */ | |
| 296 | + for (perturb = hash; ; perturb >>= PERTURB_SHIFT) { | |
| 297 | + i = (i << 2) + i + perturb + 1; | |
| 298 | + ep = &ep0[i & mask]; | |
| 299 | + if (ep->me_key == NULL) | |
| 300 | + return freeslot == NULL ? ep : freeslot; | |
| 301 | + if (ep->me_key == key) | |
| 302 | + return ep; | |
| 303 | + if (ep->me_hash == hash && ep->me_key != dummy) { | |
| 304 | + startkey = ep->me_key; | |
| 305 | + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); | |
| 306 | + if (cmp < 0) | |
| 307 | + return NULL; | |
| 308 | + if (ep0 == mp->ma_table && ep->me_key == startkey) { | |
| 309 | + if (cmp > 0) | |
| 310 | + return ep; | |
| 311 | + } | |
| 312 | + else { | |
| 313 | + /* The compare did major nasty stuff to the | |
| 314 | + * dict: start over. | |
| 315 | + * XXX A clever adversary could prevent this | |
| 316 | + * XXX from terminating. | |
| 317 | + */ | |
| 318 | + return lookdict(mp, key, hash); | |
| 319 | + } | |
| 320 | + } | |
| 321 | + else if (ep->me_key == dummy && freeslot == NULL) | |
| 322 | + freeslot = ep; | |
| 323 | + } | |
| 324 | + assert(0); /* NOT REACHED */ | |
| 325 | + return 0; | |
| 326 | +} | |
| 327 | + | |
| 328 | +/* | |
| 329 | + * Hacked up version of lookdict which can assume keys are always strings; | |
| 330 | + * this assumption allows testing for errors during PyObject_RichCompareBool() | |
| 331 | + * to be dropped; string-string comparisons never raise exceptions. This also | |
| 332 | + * means we don't need to go through PyObject_RichCompareBool(); we can always | |
| 333 | + * use _PyString_Eq() directly. | |
| 334 | + * | |
| 335 | + * This is valuable because dicts with only string keys are very common. | |
| 336 | + */ | |
| 337 | +static dictentry * | |
| 338 | +lookdict_string(dictobject *mp, PyObject *key, register long hash) | |
| 339 | +{ | |
| 340 | + register size_t i; | |
| 341 | + register size_t perturb; | |
| 342 | + register dictentry *freeslot; | |
| 343 | + register size_t mask = (size_t)mp->ma_mask; | |
| 344 | + dictentry *ep0 = mp->ma_table; | |
| 345 | + register dictentry *ep; | |
| 346 | + | |
| 347 | + /* Make sure this function doesn't have to handle non-string keys, | |
| 348 | + including subclasses of str; e.g., one reason to subclass | |
| 349 | + strings is to override __eq__, and for speed we don't cater to | |
| 350 | + that here. */ | |
| 351 | + if (!PyString_CheckExact(key)) { | |
| 352 | +#ifdef SHOW_CONVERSION_COUNTS | |
| 353 | + ++converted; | |
| 354 | +#endif | |
| 355 | + mp->ma_lookup = lookdict; | |
| 356 | + return lookdict(mp, key, hash); | |
| 357 | + } | |
| 358 | + i = hash & mask; | |
| 359 | + ep = &ep0[i]; | |
| 360 | + if (ep->me_key == NULL || ep->me_key == key) | |
| 361 | + return ep; | |
| 362 | + if (ep->me_key == dummy) | |
| 363 | + freeslot = ep; | |
| 364 | + else { | |
| 365 | + if (ep->me_hash == hash && _PyString_Eq(ep->me_key, key)) | |
| 366 | + return ep; | |
| 367 | + freeslot = NULL; | |
| 368 | + } | |
| 369 | + | |
| 370 | + /* In the loop, me_key == dummy is by far (factor of 100s) the | |
| 371 | + least likely outcome, so test for that last. */ | |
| 372 | + for (perturb = hash; ; perturb >>= PERTURB_SHIFT) { | |
| 373 | + i = (i << 2) + i + perturb + 1; | |
| 374 | + ep = &ep0[i & mask]; | |
| 375 | + if (ep->me_key == NULL) | |
| 376 | + return freeslot == NULL ? ep : freeslot; | |
| 377 | + if (ep->me_key == key | |
| 378 | + || (ep->me_hash == hash | |
| 379 | + && ep->me_key != dummy | |
| 380 | + && _PyString_Eq(ep->me_key, key))) | |
| 381 | + return ep; | |
| 382 | + if (ep->me_key == dummy && freeslot == NULL) | |
| 383 | + freeslot = ep; | |
| 384 | + } | |
| 385 | + assert(0); /* NOT REACHED */ | |
| 386 | + return 0; | |
| 387 | +} | |
| 388 | + | |
| 389 | +/* | |
| 390 | +Internal routine to insert a new item into the table. | |
| 391 | +Used both by the internal resize routine and by the public insert routine. | |
| 392 | +Eats a reference to key and one to value. | |
| 393 | +Returns -1 if an error occurred, or 0 on success. | |
| 394 | +*/ | |
| 395 | +static int | |
| 396 | +insertdict(register dictobject *mp, PyObject *key, long hash, PyObject *value) | |
| 397 | +{ | |
| 398 | + PyObject *old_value; | |
| 399 | + register dictentry *ep; | |
| 400 | + typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long); | |
| 401 | + | |
| 402 | + assert(mp->ma_lookup != NULL); | |
| 403 | + ep = mp->ma_lookup(mp, key, hash); | |
| 404 | + if (ep == NULL) { | |
| 405 | + Py_DECREF(key); | |
| 406 | + Py_DECREF(value); | |
| 407 | + return -1; | |
| 408 | + } | |
| 409 | + if (ep->me_value != NULL) { | |
| 410 | + old_value = ep->me_value; | |
| 411 | + ep->me_value = value; | |
| 412 | + Py_DECREF(old_value); /* which **CAN** re-enter */ | |
| 413 | + Py_DECREF(key); | |
| 414 | + } | |
| 415 | + else { | |
| 416 | + if (ep->me_key == NULL) | |
| 417 | + mp->ma_fill++; | |
| 418 | + else { | |
| 419 | + assert(ep->me_key == dummy); | |
| 420 | + Py_DECREF(dummy); | |
| 421 | + } | |
| 422 | + ep->me_key = key; | |
| 423 | + ep->me_hash = (Py_ssize_t)hash; | |
| 424 | + ep->me_value = value; | |
| 425 | + mp->ma_used++; | |
| 426 | + } | |
| 427 | + return 0; | |
| 428 | +} | |
| 429 | + | |
| 430 | +/* | |
| 431 | +Internal routine used by dictresize() to insert an item which is | |
| 432 | +known to be absent from the dict. This routine also assumes that | |
| 433 | +the dict contains no deleted entries. Besides the performance benefit, | |
| 434 | +using insertdict() in dictresize() is dangerous (SF bug #1456209). | |
| 435 | +Note that no refcounts are changed by this routine; if needed, the caller | |
| 436 | +is responsible for incref'ing `key` and `value`. | |
| 437 | +*/ | |
| 438 | +static void | |
| 439 | +insertdict_clean(register dictobject *mp, PyObject *key, long hash, | |
| 440 | + PyObject *value) | |
| 441 | +{ | |
| 442 | + register size_t i; | |
| 443 | + register size_t perturb; | |
| 444 | + register size_t mask = (size_t)mp->ma_mask; | |
| 445 | + dictentry *ep0 = mp->ma_table; | |
| 446 | + register dictentry *ep; | |
| 447 | + | |
| 448 | + i = hash & mask; | |
| 449 | + ep = &ep0[i]; | |
| 450 | + for (perturb = hash; ep->me_key != NULL; perturb >>= PERTURB_SHIFT) { | |
| 451 | + i = (i << 2) + i + perturb + 1; | |
| 452 | + ep = &ep0[i & mask]; | |
| 453 | + } | |
| 454 | + assert(ep->me_value == NULL); | |
| 455 | + mp->ma_fill++; | |
| 456 | + ep->me_key = key; | |
| 457 | + ep->me_hash = (Py_ssize_t)hash; | |
| 458 | + ep->me_value = value; | |
| 459 | + mp->ma_used++; | |
| 460 | +} | |
| 461 | + | |
| 462 | +/* | |
| 463 | +Restructure the table by allocating a new table and reinserting all | |
| 464 | +items again. When entries have been deleted, the new table may | |
| 465 | +actually be smaller than the old one. | |
| 466 | +*/ | |
| 467 | +static int | |
| 468 | +dictresize(dictobject *mp, Py_ssize_t minused) | |
| 469 | +{ | |
| 470 | + Py_ssize_t newsize; | |
| 471 | + dictentry *oldtable, *newtable, *ep; | |
| 472 | + Py_ssize_t i; | |
| 473 | + int is_oldtable_malloced; | |
| 474 | + dictentry small_copy[PyDict_MINSIZE]; | |
| 475 | + | |
| 476 | + assert(minused >= 0); | |
| 477 | + | |
| 478 | + /* Find the smallest table size > minused. */ | |
| 479 | + for (newsize = PyDict_MINSIZE; | |
| 480 | + newsize <= minused && newsize > 0; | |
| 481 | + newsize <<= 1) | |
| 482 | + ; | |
| 483 | + if (newsize <= 0) { | |
| 484 | + PyErr_NoMemory(); | |
| 485 | + return -1; | |
| 486 | + } | |
| 487 | + | |
| 488 | + /* Get space for a new table. */ | |
| 489 | + oldtable = mp->ma_table; | |
| 490 | + assert(oldtable != NULL); | |
| 491 | + is_oldtable_malloced = oldtable != mp->ma_smalltable; | |
| 492 | + | |
| 493 | + if (newsize == PyDict_MINSIZE) { | |
| 494 | + /* A large table is shrinking, or we can't get any smaller. */ | |
| 495 | + newtable = mp->ma_smalltable; | |
| 496 | + if (newtable == oldtable) { | |
| 497 | + if (mp->ma_fill == mp->ma_used) { | |
| 498 | + /* No dummies, so no point doing anything. */ | |
| 499 | + return 0; | |
| 500 | + } | |
| 501 | + /* We're not going to resize it, but rebuild the | |
| 502 | + table anyway to purge old dummy entries. | |
| 503 | + Subtle: This is *necessary* if fill==size, | |
| 504 | + as lookdict needs at least one virgin slot to | |
| 505 | + terminate failing searches. If fill < size, it's | |
| 506 | + merely desirable, as dummies slow searches. */ | |
| 507 | + assert(mp->ma_fill > mp->ma_used); | |
| 508 | + memcpy(small_copy, oldtable, sizeof(small_copy)); | |
| 509 | + oldtable = small_copy; | |
| 510 | + } | |
| 511 | + } | |
| 512 | + else { | |
| 513 | + newtable = PyMem_NEW(dictentry, newsize); | |
| 514 | + if (newtable == NULL) { | |
| 515 | + PyErr_NoMemory(); | |
| 516 | + return -1; | |
| 517 | + } | |
| 518 | + } | |
| 519 | + | |
| 520 | + /* Make the dict empty, using the new table. */ | |
| 521 | + assert(newtable != oldtable); | |
| 522 | + mp->ma_table = newtable; | |
| 523 | + mp->ma_mask = newsize - 1; | |
| 524 | + memset(newtable, 0, sizeof(dictentry) * newsize); | |
| 525 | + mp->ma_used = 0; | |
| 526 | + i = mp->ma_fill; | |
| 527 | + mp->ma_fill = 0; | |
| 528 | + | |
| 529 | + /* Copy the data over; this is refcount-neutral for active entries; | |
| 530 | + dummy entries aren't copied over, of course */ | |
| 531 | + for (ep = oldtable; i > 0; ep++) { | |
| 532 | + if (ep->me_value != NULL) { /* active entry */ | |
| 533 | + --i; | |
| 534 | + insertdict_clean(mp, ep->me_key, (long)ep->me_hash, | |
| 535 | + ep->me_value); | |
| 536 | + } | |
| 537 | + else if (ep->me_key != NULL) { /* dummy entry */ | |
| 538 | + --i; | |
| 539 | + assert(ep->me_key == dummy); | |
| 540 | + Py_DECREF(ep->me_key); | |
| 541 | + } | |
| 542 | + /* else key == value == NULL: nothing to do */ | |
| 543 | + } | |
| 544 | + | |
| 545 | + if (is_oldtable_malloced) | |
| 546 | + PyMem_DEL(oldtable); | |
| 547 | + return 0; | |
| 548 | +} | |
| 549 | + | |
| 550 | +/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors | |
| 551 | + * that may occur (originally dicts supported only string keys, and exceptions | |
| 552 | + * weren't possible). So, while the original intent was that a NULL return | |
| 553 | + * meant the key wasn't present, in reality it can mean that, or that an error | |
| 554 | + * (suppressed) occurred while computing the key's hash, or that some error | |
| 555 | + * (suppressed) occurred when comparing keys in the dict's internal probe | |
| 556 | + * sequence. A nasty example of the latter is when a Python-coded comparison | |
| 557 | + * function hits a stack-depth error, which can cause this to return NULL | |
| 558 | + * even if the key is present. | |
| 559 | + */ | |
| 560 | +PyObject * | |
| 561 | +PyDict_GetItem(PyObject *op, PyObject *key) | |
| 562 | +{ | |
| 563 | + long hash; | |
| 564 | + dictobject *mp = (dictobject *)op; | |
| 565 | + dictentry *ep; | |
| 566 | + PyThreadState *tstate; | |
| 567 | + if (!PyDict_Check(op)) | |
| 568 | + return NULL; | |
| 569 | + if (!PyString_CheckExact(key) || | |
| 570 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) | |
| 571 | + { | |
| 572 | + hash = PyObject_Hash(key); | |
| 573 | + if (hash == -1) { | |
| 574 | + PyErr_Clear(); | |
| 575 | + return NULL; | |
| 576 | + } | |
| 577 | + } | |
| 578 | + | |
| 579 | + /* We can arrive here with a NULL tstate during initialization: | |
| 580 | + try running "python -Wi" for an example related to string | |
| 581 | + interning. Let's just hope that no exception occurs then... */ | |
| 582 | + tstate = _PyThreadState_Current; | |
| 583 | + if (tstate != NULL && tstate->curexc_type != NULL) { | |
| 584 | + /* preserve the existing exception */ | |
| 585 | + PyObject *err_type, *err_value, *err_tb; | |
| 586 | + PyErr_Fetch(&err_type, &err_value, &err_tb); | |
| 587 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 588 | + /* ignore errors */ | |
| 589 | + PyErr_Restore(err_type, err_value, err_tb); | |
| 590 | + if (ep == NULL) | |
| 591 | + return NULL; | |
| 592 | + } | |
| 593 | + else { | |
| 594 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 595 | + if (ep == NULL) { | |
| 596 | + PyErr_Clear(); | |
| 597 | + return NULL; | |
| 598 | + } | |
| 599 | + } | |
| 600 | + return ep->me_value; | |
| 601 | +} | |
| 602 | + | |
| 603 | +/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the | |
| 604 | + * dictionary if it's merely replacing the value for an existing key. | |
| 605 | + * This means that it's safe to loop over a dictionary with PyDict_Next() | |
| 606 | + * and occasionally replace a value -- but you can't insert new keys or | |
| 607 | + * remove them. | |
| 608 | + */ | |
| 609 | +int | |
| 610 | +PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value) | |
| 611 | +{ | |
| 612 | + register dictobject *mp; | |
| 613 | + register long hash; | |
| 614 | + register Py_ssize_t n_used; | |
| 615 | + | |
| 616 | + if (!PyDict_Check(op)) { | |
| 617 | + PyErr_BadInternalCall(); | |
| 618 | + return -1; | |
| 619 | + } | |
| 620 | + assert(key); | |
| 621 | + assert(value); | |
| 622 | + mp = (dictobject *)op; | |
| 623 | + if (PyString_CheckExact(key)) { | |
| 624 | + hash = ((PyStringObject *)key)->ob_shash; | |
| 625 | + if (hash == -1) | |
| 626 | + hash = PyObject_Hash(key); | |
| 627 | + } | |
| 628 | + else { | |
| 629 | + hash = PyObject_Hash(key); | |
| 630 | + if (hash == -1) | |
| 631 | + return -1; | |
| 632 | + } | |
| 633 | + assert(mp->ma_fill <= mp->ma_mask); /* at least one empty slot */ | |
| 634 | + n_used = mp->ma_used; | |
| 635 | + Py_INCREF(value); | |
| 636 | + Py_INCREF(key); | |
| 637 | + if (insertdict(mp, key, hash, value) != 0) | |
| 638 | + return -1; | |
| 639 | + /* If we added a key, we can safely resize. Otherwise just return! | |
| 640 | + * If fill >= 2/3 size, adjust size. Normally, this doubles or | |
| 641 | + * quaduples the size, but it's also possible for the dict to shrink | |
| 642 | + * (if ma_fill is much larger than ma_used, meaning a lot of dict | |
| 643 | + * keys have been * deleted). | |
| 644 | + * | |
| 645 | + * Quadrupling the size improves average dictionary sparseness | |
| 646 | + * (reducing collisions) at the cost of some memory and iteration | |
| 647 | + * speed (which loops over every possible entry). It also halves | |
| 648 | + * the number of expensive resize operations in a growing dictionary. | |
| 649 | + * | |
| 650 | + * Very large dictionaries (over 50K items) use doubling instead. | |
| 651 | + * This may help applications with severe memory constraints. | |
| 652 | + */ | |
| 653 | + if (!(mp->ma_used > n_used && mp->ma_fill*3 >= (mp->ma_mask+1)*2)) | |
| 654 | + return 0; | |
| 655 | + return dictresize(mp, (mp->ma_used > 50000 ? 2 : 4) * mp->ma_used); | |
| 656 | +} | |
| 657 | + | |
| 658 | +int | |
| 659 | +PyDict_DelItem(PyObject *op, PyObject *key) | |
| 660 | +{ | |
| 661 | + register dictobject *mp; | |
| 662 | + register long hash; | |
| 663 | + register dictentry *ep; | |
| 664 | + PyObject *old_value, *old_key; | |
| 665 | + | |
| 666 | + if (!PyDict_Check(op)) { | |
| 667 | + PyErr_BadInternalCall(); | |
| 668 | + return -1; | |
| 669 | + } | |
| 670 | + assert(key); | |
| 671 | + if (!PyString_CheckExact(key) || | |
| 672 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | |
| 673 | + hash = PyObject_Hash(key); | |
| 674 | + if (hash == -1) | |
| 675 | + return -1; | |
| 676 | + } | |
| 677 | + mp = (dictobject *)op; | |
| 678 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 679 | + if (ep == NULL) | |
| 680 | + return -1; | |
| 681 | + if (ep->me_value == NULL) { | |
| 682 | + set_key_error(key); | |
| 683 | + return -1; | |
| 684 | + } | |
| 685 | + old_key = ep->me_key; | |
| 686 | + Py_INCREF(dummy); | |
| 687 | + ep->me_key = dummy; | |
| 688 | + old_value = ep->me_value; | |
| 689 | + ep->me_value = NULL; | |
| 690 | + mp->ma_used--; | |
| 691 | + Py_DECREF(old_value); | |
| 692 | + Py_DECREF(old_key); | |
| 693 | + return 0; | |
| 694 | +} | |
| 695 | + | |
| 696 | +void | |
| 697 | +PyDict_Clear(PyObject *op) | |
| 698 | +{ | |
| 699 | + dictobject *mp; | |
| 700 | + dictentry *ep, *table; | |
| 701 | + int table_is_malloced; | |
| 702 | + Py_ssize_t fill; | |
| 703 | + dictentry small_copy[PyDict_MINSIZE]; | |
| 704 | +#ifdef Py_DEBUG | |
| 705 | + Py_ssize_t i, n; | |
| 706 | +#endif | |
| 707 | + | |
| 708 | + if (!PyDict_Check(op)) | |
| 709 | + return; | |
| 710 | + mp = (dictobject *)op; | |
| 711 | +#ifdef Py_DEBUG | |
| 712 | + n = mp->ma_mask + 1; | |
| 713 | + i = 0; | |
| 714 | +#endif | |
| 715 | + | |
| 716 | + table = mp->ma_table; | |
| 717 | + assert(table != NULL); | |
| 718 | + table_is_malloced = table != mp->ma_smalltable; | |
| 719 | + | |
| 720 | + /* This is delicate. During the process of clearing the dict, | |
| 721 | + * decrefs can cause the dict to mutate. To avoid fatal confusion | |
| 722 | + * (voice of experience), we have to make the dict empty before | |
| 723 | + * clearing the slots, and never refer to anything via mp->xxx while | |
| 724 | + * clearing. | |
| 725 | + */ | |
| 726 | + fill = mp->ma_fill; | |
| 727 | + if (table_is_malloced) | |
| 728 | + EMPTY_TO_MINSIZE(mp); | |
| 729 | + | |
| 730 | + else if (fill > 0) { | |
| 731 | + /* It's a small table with something that needs to be cleared. | |
| 732 | + * Afraid the only safe way is to copy the dict entries into | |
| 733 | + * another small table first. | |
| 734 | + */ | |
| 735 | + memcpy(small_copy, table, sizeof(small_copy)); | |
| 736 | + table = small_copy; | |
| 737 | + EMPTY_TO_MINSIZE(mp); | |
| 738 | + } | |
| 739 | + /* else it's a small table that's already empty */ | |
| 740 | + | |
| 741 | + /* Now we can finally clear things. If C had refcounts, we could | |
| 742 | + * assert that the refcount on table is 1 now, i.e. that this function | |
| 743 | + * has unique access to it, so decref side-effects can't alter it. | |
| 744 | + */ | |
| 745 | + for (ep = table; fill > 0; ++ep) { | |
| 746 | +#ifdef Py_DEBUG | |
| 747 | + assert(i < n); | |
| 748 | + ++i; | |
| 749 | +#endif | |
| 750 | + if (ep->me_key) { | |
| 751 | + --fill; | |
| 752 | + Py_DECREF(ep->me_key); | |
| 753 | + Py_XDECREF(ep->me_value); | |
| 754 | + } | |
| 755 | +#ifdef Py_DEBUG | |
| 756 | + else | |
| 757 | + assert(ep->me_value == NULL); | |
| 758 | +#endif | |
| 759 | + } | |
| 760 | + | |
| 761 | + if (table_is_malloced) | |
| 762 | + PyMem_DEL(table); | |
| 763 | +} | |
| 764 | + | |
| 765 | +/* | |
| 766 | + * Iterate over a dict. Use like so: | |
| 767 | + * | |
| 768 | + * Py_ssize_t i; | |
| 769 | + * PyObject *key, *value; | |
| 770 | + * i = 0; # important! i should not otherwise be changed by you | |
| 771 | + * while (PyDict_Next(yourdict, &i, &key, &value)) { | |
| 772 | + * Refer to borrowed references in key and value. | |
| 773 | + * } | |
| 774 | + * | |
| 775 | + * CAUTION: In general, it isn't safe to use PyDict_Next in a loop that | |
| 776 | + * mutates the dict. One exception: it is safe if the loop merely changes | |
| 777 | + * the values associated with the keys (but doesn't insert new keys or | |
| 778 | + * delete keys), via PyDict_SetItem(). | |
| 779 | + */ | |
| 780 | +int | |
| 781 | +PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) | |
| 782 | +{ | |
| 783 | + register Py_ssize_t i; | |
| 784 | + register Py_ssize_t mask; | |
| 785 | + register dictentry *ep; | |
| 786 | + | |
| 787 | + if (!PyDict_Check(op)) | |
| 788 | + return 0; | |
| 789 | + i = *ppos; | |
| 790 | + if (i < 0) | |
| 791 | + return 0; | |
| 792 | + ep = ((dictobject *)op)->ma_table; | |
| 793 | + mask = ((dictobject *)op)->ma_mask; | |
| 794 | + while (i <= mask && ep[i].me_value == NULL) | |
| 795 | + i++; | |
| 796 | + *ppos = i+1; | |
| 797 | + if (i > mask) | |
| 798 | + return 0; | |
| 799 | + if (pkey) | |
| 800 | + *pkey = ep[i].me_key; | |
| 801 | + if (pvalue) | |
| 802 | + *pvalue = ep[i].me_value; | |
| 803 | + return 1; | |
| 804 | +} | |
| 805 | + | |
| 806 | +/* Internal version of PyDict_Next that returns a hash value in addition to the key and value.*/ | |
| 807 | +int | |
| 808 | +_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, long *phash) | |
| 809 | +{ | |
| 810 | + register Py_ssize_t i; | |
| 811 | + register Py_ssize_t mask; | |
| 812 | + register dictentry *ep; | |
| 813 | + | |
| 814 | + if (!PyDict_Check(op)) | |
| 815 | + return 0; | |
| 816 | + i = *ppos; | |
| 817 | + if (i < 0) | |
| 818 | + return 0; | |
| 819 | + ep = ((dictobject *)op)->ma_table; | |
| 820 | + mask = ((dictobject *)op)->ma_mask; | |
| 821 | + while (i <= mask && ep[i].me_value == NULL) | |
| 822 | + i++; | |
| 823 | + *ppos = i+1; | |
| 824 | + if (i > mask) | |
| 825 | + return 0; | |
| 826 | + *phash = (long)(ep[i].me_hash); | |
| 827 | + if (pkey) | |
| 828 | + *pkey = ep[i].me_key; | |
| 829 | + if (pvalue) | |
| 830 | + *pvalue = ep[i].me_value; | |
| 831 | + return 1; | |
| 832 | +} | |
| 833 | + | |
| 834 | +/* Methods */ | |
| 835 | + | |
| 836 | +static void | |
| 837 | +dict_dealloc(register dictobject *mp) | |
| 838 | +{ | |
| 839 | + register dictentry *ep; | |
| 840 | + Py_ssize_t fill = mp->ma_fill; | |
| 841 | + PyObject_GC_UnTrack(mp); | |
| 842 | + Py_TRASHCAN_SAFE_BEGIN(mp) | |
| 843 | + for (ep = mp->ma_table; fill > 0; ep++) { | |
| 844 | + if (ep->me_key) { | |
| 845 | + --fill; | |
| 846 | + Py_DECREF(ep->me_key); | |
| 847 | + Py_XDECREF(ep->me_value); | |
| 848 | + } | |
| 849 | + } | |
| 850 | + if (mp->ma_table != mp->ma_smalltable) | |
| 851 | + PyMem_DEL(mp->ma_table); | |
| 852 | + if (num_free_dicts < MAXFREEDICTS && mp->ob_type == &PyDict_Type) | |
| 853 | + free_dicts[num_free_dicts++] = mp; | |
| 854 | + else | |
| 855 | + mp->ob_type->tp_free((PyObject *)mp); | |
| 856 | + Py_TRASHCAN_SAFE_END(mp) | |
| 857 | +} | |
| 858 | + | |
| 859 | +static int | |
| 860 | +dict_print(register dictobject *mp, register FILE *fp, register int flags) | |
| 861 | +{ | |
| 862 | + register Py_ssize_t i; | |
| 863 | + register Py_ssize_t any; | |
| 864 | + int status; | |
| 865 | + | |
| 866 | + status = Py_ReprEnter((PyObject*)mp); | |
| 867 | + if (status != 0) { | |
| 868 | + if (status < 0) | |
| 869 | + return status; | |
| 870 | + fprintf(fp, "{...}"); | |
| 871 | + return 0; | |
| 872 | + } | |
| 873 | + | |
| 874 | + fprintf(fp, "{"); | |
| 875 | + any = 0; | |
| 876 | + for (i = 0; i <= mp->ma_mask; i++) { | |
| 877 | + dictentry *ep = mp->ma_table + i; | |
| 878 | + PyObject *pvalue = ep->me_value; | |
| 879 | + if (pvalue != NULL) { | |
| 880 | + /* Prevent PyObject_Repr from deleting value during | |
| 881 | + key format */ | |
| 882 | + Py_INCREF(pvalue); | |
| 883 | + if (any++ > 0) | |
| 884 | + fprintf(fp, ", "); | |
| 885 | + if (PyObject_Print((PyObject *)ep->me_key, fp, 0)!=0) { | |
| 886 | + Py_DECREF(pvalue); | |
| 887 | + Py_ReprLeave((PyObject*)mp); | |
| 888 | + return -1; | |
| 889 | + } | |
| 890 | + fprintf(fp, ": "); | |
| 891 | + if (PyObject_Print(pvalue, fp, 0) != 0) { | |
| 892 | + Py_DECREF(pvalue); | |
| 893 | + Py_ReprLeave((PyObject*)mp); | |
| 894 | + return -1; | |
| 895 | + } | |
| 896 | + Py_DECREF(pvalue); | |
| 897 | + } | |
| 898 | + } | |
| 899 | + fprintf(fp, "}"); | |
| 900 | + Py_ReprLeave((PyObject*)mp); | |
| 901 | + return 0; | |
| 902 | +} | |
| 903 | + | |
| 904 | +static PyObject * | |
| 905 | +dict_repr(dictobject *mp) | |
| 906 | +{ | |
| 907 | + Py_ssize_t i; | |
| 908 | + PyObject *s, *temp, *colon = NULL; | |
| 909 | + PyObject *pieces = NULL, *result = NULL; | |
| 910 | + PyObject *key, *value; | |
| 911 | + | |
| 912 | + i = Py_ReprEnter((PyObject *)mp); | |
| 913 | + if (i != 0) { | |
| 914 | + return i > 0 ? PyString_FromString("{...}") : NULL; | |
| 915 | + } | |
| 916 | + | |
| 917 | + if (mp->ma_used == 0) { | |
| 918 | + result = PyString_FromString("{}"); | |
| 919 | + goto Done; | |
| 920 | + } | |
| 921 | + | |
| 922 | + pieces = PyList_New(0); | |
| 923 | + if (pieces == NULL) | |
| 924 | + goto Done; | |
| 925 | + | |
| 926 | + colon = PyString_FromString(": "); | |
| 927 | + if (colon == NULL) | |
| 928 | + goto Done; | |
| 929 | + | |
| 930 | + /* Do repr() on each key+value pair, and insert ": " between them. | |
| 931 | + Note that repr may mutate the dict. */ | |
| 932 | + i = 0; | |
| 933 | + while (PyDict_Next((PyObject *)mp, &i, &key, &value)) { | |
| 934 | + int status; | |
| 935 | + /* Prevent repr from deleting value during key format. */ | |
| 936 | + Py_INCREF(value); | |
| 937 | + s = PyObject_Repr(key); | |
| 938 | + PyString_Concat(&s, colon); | |
| 939 | + PyString_ConcatAndDel(&s, PyObject_Repr(value)); | |
| 940 | + Py_DECREF(value); | |
| 941 | + if (s == NULL) | |
| 942 | + goto Done; | |
| 943 | + status = PyList_Append(pieces, s); | |
| 944 | + Py_DECREF(s); /* append created a new ref */ | |
| 945 | + if (status < 0) | |
| 946 | + goto Done; | |
| 947 | + } | |
| 948 | + | |
| 949 | + /* Add "{}" decorations to the first and last items. */ | |
| 950 | + assert(PyList_GET_SIZE(pieces) > 0); | |
| 951 | + s = PyString_FromString("{"); | |
| 952 | + if (s == NULL) | |
| 953 | + goto Done; | |
| 954 | + temp = PyList_GET_ITEM(pieces, 0); | |
| 955 | + PyString_ConcatAndDel(&s, temp); | |
| 956 | + PyList_SET_ITEM(pieces, 0, s); | |
| 957 | + if (s == NULL) | |
| 958 | + goto Done; | |
| 959 | + | |
| 960 | + s = PyString_FromString("}"); | |
| 961 | + if (s == NULL) | |
| 962 | + goto Done; | |
| 963 | + temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); | |
| 964 | + PyString_ConcatAndDel(&temp, s); | |
| 965 | + PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); | |
| 966 | + if (temp == NULL) | |
| 967 | + goto Done; | |
| 968 | + | |
| 969 | + /* Paste them all together with ", " between. */ | |
| 970 | + s = PyString_FromString(", "); | |
| 971 | + if (s == NULL) | |
| 972 | + goto Done; | |
| 973 | + result = _PyString_Join(s, pieces); | |
| 974 | + Py_DECREF(s); | |
| 975 | + | |
| 976 | +Done: | |
| 977 | + Py_XDECREF(pieces); | |
| 978 | + Py_XDECREF(colon); | |
| 979 | + Py_ReprLeave((PyObject *)mp); | |
| 980 | + return result; | |
| 981 | +} | |
| 982 | + | |
| 983 | +static Py_ssize_t | |
| 984 | +dict_length(dictobject *mp) | |
| 985 | +{ | |
| 986 | + return mp->ma_used; | |
| 987 | +} | |
| 988 | + | |
| 989 | +static PyObject * | |
| 990 | +dict_subscript(dictobject *mp, register PyObject *key) | |
| 991 | +{ | |
| 992 | + PyObject *v; | |
| 993 | + long hash; | |
| 994 | + dictentry *ep; | |
| 995 | + assert(mp->ma_table != NULL); | |
| 996 | + if (!PyString_CheckExact(key) || | |
| 997 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | |
| 998 | + hash = PyObject_Hash(key); | |
| 999 | + if (hash == -1) | |
| 1000 | + return NULL; | |
| 1001 | + } | |
| 1002 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 1003 | + if (ep == NULL) | |
| 1004 | + return NULL; | |
| 1005 | + v = ep->me_value; | |
| 1006 | + if (v == NULL) { | |
| 1007 | + if (!PyDict_CheckExact(mp)) { | |
| 1008 | + /* Look up __missing__ method if we're a subclass. */ | |
| 1009 | + PyObject *missing; | |
| 1010 | + static PyObject *missing_str = NULL; | |
| 1011 | + if (missing_str == NULL) | |
| 1012 | + missing_str = | |
| 1013 | + PyString_InternFromString("__missing__"); | |
| 1014 | + missing = _PyType_Lookup(mp->ob_type, missing_str); | |
| 1015 | + if (missing != NULL) | |
| 1016 | + return PyObject_CallFunctionObjArgs(missing, | |
| 1017 | + (PyObject *)mp, key, NULL); | |
| 1018 | + } | |
| 1019 | + set_key_error(key); | |
| 1020 | + return NULL; | |
| 1021 | + } | |
| 1022 | + else | |
| 1023 | + Py_INCREF(v); | |
| 1024 | + return v; | |
| 1025 | +} | |
| 1026 | + | |
| 1027 | +static int | |
| 1028 | +dict_ass_sub(dictobject *mp, PyObject *v, PyObject *w) | |
| 1029 | +{ | |
| 1030 | + if (w == NULL) | |
| 1031 | + return PyDict_DelItem((PyObject *)mp, v); | |
| 1032 | + else | |
| 1033 | + return PyDict_SetItem((PyObject *)mp, v, w); | |
| 1034 | +} | |
| 1035 | + | |
| 1036 | +static PyMappingMethods dict_as_mapping = { | |
| 1037 | + (lenfunc)dict_length, /*mp_length*/ | |
| 1038 | + (binaryfunc)dict_subscript, /*mp_subscript*/ | |
| 1039 | + (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/ | |
| 1040 | +}; | |
| 1041 | + | |
| 1042 | +static PyObject * | |
| 1043 | +dict_keys(register dictobject *mp) | |
| 1044 | +{ | |
| 1045 | + register PyObject *v; | |
| 1046 | + register Py_ssize_t i, j; | |
| 1047 | + dictentry *ep; | |
| 1048 | + Py_ssize_t mask, n; | |
| 1049 | + | |
| 1050 | + again: | |
| 1051 | + n = mp->ma_used; | |
| 1052 | + v = PyList_New(n); | |
| 1053 | + if (v == NULL) | |
| 1054 | + return NULL; | |
| 1055 | + if (n != mp->ma_used) { | |
| 1056 | + /* Durnit. The allocations caused the dict to resize. | |
| 1057 | + * Just start over, this shouldn't normally happen. | |
| 1058 | + */ | |
| 1059 | + Py_DECREF(v); | |
| 1060 | + goto again; | |
| 1061 | + } | |
| 1062 | + ep = mp->ma_table; | |
| 1063 | + mask = mp->ma_mask; | |
| 1064 | + for (i = 0, j = 0; i <= mask; i++) { | |
| 1065 | + if (ep[i].me_value != NULL) { | |
| 1066 | + PyObject *key = ep[i].me_key; | |
| 1067 | + Py_INCREF(key); | |
| 1068 | + PyList_SET_ITEM(v, j, key); | |
| 1069 | + j++; | |
| 1070 | + } | |
| 1071 | + } | |
| 1072 | + assert(j == n); | |
| 1073 | + return v; | |
| 1074 | +} | |
| 1075 | + | |
| 1076 | +static PyObject * | |
| 1077 | +dict_values(register dictobject *mp) | |
| 1078 | +{ | |
| 1079 | + register PyObject *v; | |
| 1080 | + register Py_ssize_t i, j; | |
| 1081 | + dictentry *ep; | |
| 1082 | + Py_ssize_t mask, n; | |
| 1083 | + | |
| 1084 | + again: | |
| 1085 | + n = mp->ma_used; | |
| 1086 | + v = PyList_New(n); | |
| 1087 | + if (v == NULL) | |
| 1088 | + return NULL; | |
| 1089 | + if (n != mp->ma_used) { | |
| 1090 | + /* Durnit. The allocations caused the dict to resize. | |
| 1091 | + * Just start over, this shouldn't normally happen. | |
| 1092 | + */ | |
| 1093 | + Py_DECREF(v); | |
| 1094 | + goto again; | |
| 1095 | + } | |
| 1096 | + ep = mp->ma_table; | |
| 1097 | + mask = mp->ma_mask; | |
| 1098 | + for (i = 0, j = 0; i <= mask; i++) { | |
| 1099 | + if (ep[i].me_value != NULL) { | |
| 1100 | + PyObject *value = ep[i].me_value; | |
| 1101 | + Py_INCREF(value); | |
| 1102 | + PyList_SET_ITEM(v, j, value); | |
| 1103 | + j++; | |
| 1104 | + } | |
| 1105 | + } | |
| 1106 | + assert(j == n); | |
| 1107 | + return v; | |
| 1108 | +} | |
| 1109 | + | |
| 1110 | +static PyObject * | |
| 1111 | +dict_items(register dictobject *mp) | |
| 1112 | +{ | |
| 1113 | + register PyObject *v; | |
| 1114 | + register Py_ssize_t i, j, n; | |
| 1115 | + Py_ssize_t mask; | |
| 1116 | + PyObject *item, *key, *value; | |
| 1117 | + dictentry *ep; | |
| 1118 | + | |
| 1119 | + /* Preallocate the list of tuples, to avoid allocations during | |
| 1120 | + * the loop over the items, which could trigger GC, which | |
| 1121 | + * could resize the dict. :-( | |
| 1122 | + */ | |
| 1123 | + again: | |
| 1124 | + n = mp->ma_used; | |
| 1125 | + v = PyList_New(n); | |
| 1126 | + if (v == NULL) | |
| 1127 | + return NULL; | |
| 1128 | + for (i = 0; i < n; i++) { | |
| 1129 | + item = PyTuple_New(2); | |
| 1130 | + if (item == NULL) { | |
| 1131 | + Py_DECREF(v); | |
| 1132 | + return NULL; | |
| 1133 | + } | |
| 1134 | + PyList_SET_ITEM(v, i, item); | |
| 1135 | + } | |
| 1136 | + if (n != mp->ma_used) { | |
| 1137 | + /* Durnit. The allocations caused the dict to resize. | |
| 1138 | + * Just start over, this shouldn't normally happen. | |
| 1139 | + */ | |
| 1140 | + Py_DECREF(v); | |
| 1141 | + goto again; | |
| 1142 | + } | |
| 1143 | + /* Nothing we do below makes any function calls. */ | |
| 1144 | + ep = mp->ma_table; | |
| 1145 | + mask = mp->ma_mask; | |
| 1146 | + for (i = 0, j = 0; i <= mask; i++) { | |
| 1147 | + if ((value=ep[i].me_value) != NULL) { | |
| 1148 | + key = ep[i].me_key; | |
| 1149 | + item = PyList_GET_ITEM(v, j); | |
| 1150 | + Py_INCREF(key); | |
| 1151 | + PyTuple_SET_ITEM(item, 0, key); | |
| 1152 | + Py_INCREF(value); | |
| 1153 | + PyTuple_SET_ITEM(item, 1, value); | |
| 1154 | + j++; | |
| 1155 | + } | |
| 1156 | + } | |
| 1157 | + assert(j == n); | |
| 1158 | + return v; | |
| 1159 | +} | |
| 1160 | + | |
| 1161 | +static PyObject * | |
| 1162 | +dict_fromkeys(PyObject *cls, PyObject *args) | |
| 1163 | +{ | |
| 1164 | + PyObject *seq; | |
| 1165 | + PyObject *value = Py_None; | |
| 1166 | + PyObject *it; /* iter(seq) */ | |
| 1167 | + PyObject *key; | |
| 1168 | + PyObject *d; | |
| 1169 | + int status; | |
| 1170 | + | |
| 1171 | + if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value)) | |
| 1172 | + return NULL; | |
| 1173 | + | |
| 1174 | + d = PyObject_CallObject(cls, NULL); | |
| 1175 | + if (d == NULL) | |
| 1176 | + return NULL; | |
| 1177 | + | |
| 1178 | + if (PyDict_CheckExact(d) && PyAnySet_CheckExact(seq)) { | |
| 1179 | + dictobject *mp = (dictobject *)d; | |
| 1180 | + Py_ssize_t pos = 0; | |
| 1181 | + PyObject *key; | |
| 1182 | + long hash; | |
| 1183 | + | |
| 1184 | + if (dictresize(mp, PySet_GET_SIZE(seq))) | |
| 1185 | + return NULL; | |
| 1186 | + | |
| 1187 | + while (_PySet_NextEntry(seq, &pos, &key, &hash)) { | |
| 1188 | + Py_INCREF(key); | |
| 1189 | + Py_INCREF(value); | |
| 1190 | + if (insertdict(mp, key, hash, value)) | |
| 1191 | + return NULL; | |
| 1192 | + } | |
| 1193 | + return d; | |
| 1194 | + } | |
| 1195 | + | |
| 1196 | + it = PyObject_GetIter(seq); | |
| 1197 | + if (it == NULL){ | |
| 1198 | + Py_DECREF(d); | |
| 1199 | + return NULL; | |
| 1200 | + } | |
| 1201 | + | |
| 1202 | + for (;;) { | |
| 1203 | + key = PyIter_Next(it); | |
| 1204 | + if (key == NULL) { | |
| 1205 | + if (PyErr_Occurred()) | |
| 1206 | + goto Fail; | |
| 1207 | + break; | |
| 1208 | + } | |
| 1209 | + status = PyObject_SetItem(d, key, value); | |
| 1210 | + Py_DECREF(key); | |
| 1211 | + if (status < 0) | |
| 1212 | + goto Fail; | |
| 1213 | + } | |
| 1214 | + | |
| 1215 | + Py_DECREF(it); | |
| 1216 | + return d; | |
| 1217 | + | |
| 1218 | +Fail: | |
| 1219 | + Py_DECREF(it); | |
| 1220 | + Py_DECREF(d); | |
| 1221 | + return NULL; | |
| 1222 | +} | |
| 1223 | + | |
| 1224 | +static int | |
| 1225 | +dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, char *methname) | |
| 1226 | +{ | |
| 1227 | + PyObject *arg = NULL; | |
| 1228 | + int result = 0; | |
| 1229 | + | |
| 1230 | + if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) | |
| 1231 | + result = -1; | |
| 1232 | + | |
| 1233 | + else if (arg != NULL) { | |
| 1234 | + if (PyObject_HasAttrString(arg, "keys")) | |
| 1235 | + result = PyDict_Merge(self, arg, 1); | |
| 1236 | + else | |
| 1237 | + result = PyDict_MergeFromSeq2(self, arg, 1); | |
| 1238 | + } | |
| 1239 | + if (result == 0 && kwds != NULL) | |
| 1240 | + result = PyDict_Merge(self, kwds, 1); | |
| 1241 | + return result; | |
| 1242 | +} | |
| 1243 | + | |
| 1244 | +static PyObject * | |
| 1245 | +dict_update(PyObject *self, PyObject *args, PyObject *kwds) | |
| 1246 | +{ | |
| 1247 | + if (dict_update_common(self, args, kwds, "update") != -1) | |
| 1248 | + Py_RETURN_NONE; | |
| 1249 | + return NULL; | |
| 1250 | +} | |
| 1251 | + | |
| 1252 | +/* Update unconditionally replaces existing items. | |
| 1253 | + Merge has a 3rd argument 'override'; if set, it acts like Update, | |
| 1254 | + otherwise it leaves existing items unchanged. | |
| 1255 | + | |
| 1256 | + PyDict_{Update,Merge} update/merge from a mapping object. | |
| 1257 | + | |
| 1258 | + PyDict_MergeFromSeq2 updates/merges from any iterable object | |
| 1259 | + producing iterable objects of length 2. | |
| 1260 | +*/ | |
| 1261 | + | |
| 1262 | +int | |
| 1263 | +PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) | |
| 1264 | +{ | |
| 1265 | + PyObject *it; /* iter(seq2) */ | |
| 1266 | + Py_ssize_t i; /* index into seq2 of current element */ | |
| 1267 | + PyObject *item; /* seq2[i] */ | |
| 1268 | + PyObject *fast; /* item as a 2-tuple or 2-list */ | |
| 1269 | + | |
| 1270 | + assert(d != NULL); | |
| 1271 | + assert(PyDict_Check(d)); | |
| 1272 | + assert(seq2 != NULL); | |
| 1273 | + | |
| 1274 | + it = PyObject_GetIter(seq2); | |
| 1275 | + if (it == NULL) | |
| 1276 | + return -1; | |
| 1277 | + | |
| 1278 | + for (i = 0; ; ++i) { | |
| 1279 | + PyObject *key, *value; | |
| 1280 | + Py_ssize_t n; | |
| 1281 | + | |
| 1282 | + fast = NULL; | |
| 1283 | + item = PyIter_Next(it); | |
| 1284 | + if (item == NULL) { | |
| 1285 | + if (PyErr_Occurred()) | |
| 1286 | + goto Fail; | |
| 1287 | + break; | |
| 1288 | + } | |
| 1289 | + | |
| 1290 | + /* Convert item to sequence, and verify length 2. */ | |
| 1291 | + fast = PySequence_Fast(item, ""); | |
| 1292 | + if (fast == NULL) { | |
| 1293 | + if (PyErr_ExceptionMatches(PyExc_TypeError)) | |
| 1294 | + PyErr_Format(PyExc_TypeError, | |
| 1295 | + "cannot convert dictionary update " | |
| 1296 | + "sequence element #%zd to a sequence", | |
| 1297 | + i); | |
| 1298 | + goto Fail; | |
| 1299 | + } | |
| 1300 | + n = PySequence_Fast_GET_SIZE(fast); | |
| 1301 | + if (n != 2) { | |
| 1302 | + PyErr_Format(PyExc_ValueError, | |
| 1303 | + "dictionary update sequence element #%zd " | |
| 1304 | + "has length %zd; 2 is required", | |
| 1305 | + i, n); | |
| 1306 | + goto Fail; | |
| 1307 | + } | |
| 1308 | + | |
| 1309 | + /* Update/merge with this (key, value) pair. */ | |
| 1310 | + key = PySequence_Fast_GET_ITEM(fast, 0); | |
| 1311 | + value = PySequence_Fast_GET_ITEM(fast, 1); | |
| 1312 | + if (override || PyDict_GetItem(d, key) == NULL) { | |
| 1313 | + int status = PyDict_SetItem(d, key, value); | |
| 1314 | + if (status < 0) | |
| 1315 | + goto Fail; | |
| 1316 | + } | |
| 1317 | + Py_DECREF(fast); | |
| 1318 | + Py_DECREF(item); | |
| 1319 | + } | |
| 1320 | + | |
| 1321 | + i = 0; | |
| 1322 | + goto Return; | |
| 1323 | +Fail: | |
| 1324 | + Py_XDECREF(item); | |
| 1325 | + Py_XDECREF(fast); | |
| 1326 | + i = -1; | |
| 1327 | +Return: | |
| 1328 | + Py_DECREF(it); | |
| 1329 | + return Py_SAFE_DOWNCAST(i, Py_ssize_t, int); | |
| 1330 | +} | |
| 1331 | + | |
| 1332 | +int | |
| 1333 | +PyDict_Update(PyObject *a, PyObject *b) | |
| 1334 | +{ | |
| 1335 | + return PyDict_Merge(a, b, 1); | |
| 1336 | +} | |
| 1337 | + | |
| 1338 | +int | |
| 1339 | +PyDict_Merge(PyObject *a, PyObject *b, int override) | |
| 1340 | +{ | |
| 1341 | + register PyDictObject *mp, *other; | |
| 1342 | + register Py_ssize_t i; | |
| 1343 | + dictentry *entry; | |
| 1344 | + | |
| 1345 | + /* We accept for the argument either a concrete dictionary object, | |
| 1346 | + * or an abstract "mapping" object. For the former, we can do | |
| 1347 | + * things quite efficiently. For the latter, we only require that | |
| 1348 | + * PyMapping_Keys() and PyObject_GetItem() be supported. | |
| 1349 | + */ | |
| 1350 | + if (a == NULL || !PyDict_Check(a) || b == NULL) { | |
| 1351 | + PyErr_BadInternalCall(); | |
| 1352 | + return -1; | |
| 1353 | + } | |
| 1354 | + mp = (dictobject*)a; | |
| 1355 | + if (PyDict_Check(b)) { | |
| 1356 | + other = (dictobject*)b; | |
| 1357 | + if (other == mp || other->ma_used == 0) | |
| 1358 | + /* a.update(a) or a.update({}); nothing to do */ | |
| 1359 | + return 0; | |
| 1360 | + if (mp->ma_used == 0) | |
| 1361 | + /* Since the target dict is empty, PyDict_GetItem() | |
| 1362 | + * always returns NULL. Setting override to 1 | |
| 1363 | + * skips the unnecessary test. | |
| 1364 | + */ | |
| 1365 | + override = 1; | |
| 1366 | + /* Do one big resize at the start, rather than | |
| 1367 | + * incrementally resizing as we insert new items. Expect | |
| 1368 | + * that there will be no (or few) overlapping keys. | |
| 1369 | + */ | |
| 1370 | + if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) { | |
| 1371 | + if (dictresize(mp, (mp->ma_used + other->ma_used)*2) != 0) | |
| 1372 | + return -1; | |
| 1373 | + } | |
| 1374 | + for (i = 0; i <= other->ma_mask; i++) { | |
| 1375 | + entry = &other->ma_table[i]; | |
| 1376 | + if (entry->me_value != NULL && | |
| 1377 | + (override || | |
| 1378 | + PyDict_GetItem(a, entry->me_key) == NULL)) { | |
| 1379 | + Py_INCREF(entry->me_key); | |
| 1380 | + Py_INCREF(entry->me_value); | |
| 1381 | + if (insertdict(mp, entry->me_key, | |
| 1382 | + (long)entry->me_hash, | |
| 1383 | + entry->me_value) != 0) | |
| 1384 | + return -1; | |
| 1385 | + } | |
| 1386 | + } | |
| 1387 | + } | |
| 1388 | + else { | |
| 1389 | + /* Do it the generic, slower way */ | |
| 1390 | + PyObject *keys = PyMapping_Keys(b); | |
| 1391 | + PyObject *iter; | |
| 1392 | + PyObject *key, *value; | |
| 1393 | + int status; | |
| 1394 | + | |
| 1395 | + if (keys == NULL) | |
| 1396 | + /* Docstring says this is equivalent to E.keys() so | |
| 1397 | + * if E doesn't have a .keys() method we want | |
| 1398 | + * AttributeError to percolate up. Might as well | |
| 1399 | + * do the same for any other error. | |
| 1400 | + */ | |
| 1401 | + return -1; | |
| 1402 | + | |
| 1403 | + iter = PyObject_GetIter(keys); | |
| 1404 | + Py_DECREF(keys); | |
| 1405 | + if (iter == NULL) | |
| 1406 | + return -1; | |
| 1407 | + | |
| 1408 | + for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) { | |
| 1409 | + if (!override && PyDict_GetItem(a, key) != NULL) { | |
| 1410 | + Py_DECREF(key); | |
| 1411 | + continue; | |
| 1412 | + } | |
| 1413 | + value = PyObject_GetItem(b, key); | |
| 1414 | + if (value == NULL) { | |
| 1415 | + Py_DECREF(iter); | |
| 1416 | + Py_DECREF(key); | |
| 1417 | + return -1; | |
| 1418 | + } | |
| 1419 | + status = PyDict_SetItem(a, key, value); | |
| 1420 | + Py_DECREF(key); | |
| 1421 | + Py_DECREF(value); | |
| 1422 | + if (status < 0) { | |
| 1423 | + Py_DECREF(iter); | |
| 1424 | + return -1; | |
| 1425 | + } | |
| 1426 | + } | |
| 1427 | + Py_DECREF(iter); | |
| 1428 | + if (PyErr_Occurred()) | |
| 1429 | + /* Iterator completed, via error */ | |
| 1430 | + return -1; | |
| 1431 | + } | |
| 1432 | + return 0; | |
| 1433 | +} | |
| 1434 | + | |
| 1435 | +static PyObject * | |
| 1436 | +dict_copy(register dictobject *mp) | |
| 1437 | +{ | |
| 1438 | + return PyDict_Copy((PyObject*)mp); | |
| 1439 | +} | |
| 1440 | + | |
| 1441 | +PyObject * | |
| 1442 | +PyDict_Copy(PyObject *o) | |
| 1443 | +{ | |
| 1444 | + PyObject *copy; | |
| 1445 | + | |
| 1446 | + if (o == NULL || !PyDict_Check(o)) { | |
| 1447 | + PyErr_BadInternalCall(); | |
| 1448 | + return NULL; | |
| 1449 | + } | |
| 1450 | + copy = PyDict_New(); | |
| 1451 | + if (copy == NULL) | |
| 1452 | + return NULL; | |
| 1453 | + if (PyDict_Merge(copy, o, 1) == 0) | |
| 1454 | + return copy; | |
| 1455 | + Py_DECREF(copy); | |
| 1456 | + return NULL; | |
| 1457 | +} | |
| 1458 | + | |
| 1459 | +Py_ssize_t | |
| 1460 | +PyDict_Size(PyObject *mp) | |
| 1461 | +{ | |
| 1462 | + if (mp == NULL || !PyDict_Check(mp)) { | |
| 1463 | + PyErr_BadInternalCall(); | |
| 1464 | + return -1; | |
| 1465 | + } | |
| 1466 | + return ((dictobject *)mp)->ma_used; | |
| 1467 | +} | |
| 1468 | + | |
| 1469 | +PyObject * | |
| 1470 | +PyDict_Keys(PyObject *mp) | |
| 1471 | +{ | |
| 1472 | + if (mp == NULL || !PyDict_Check(mp)) { | |
| 1473 | + PyErr_BadInternalCall(); | |
| 1474 | + return NULL; | |
| 1475 | + } | |
| 1476 | + return dict_keys((dictobject *)mp); | |
| 1477 | +} | |
| 1478 | + | |
| 1479 | +PyObject * | |
| 1480 | +PyDict_Values(PyObject *mp) | |
| 1481 | +{ | |
| 1482 | + if (mp == NULL || !PyDict_Check(mp)) { | |
| 1483 | + PyErr_BadInternalCall(); | |
| 1484 | + return NULL; | |
| 1485 | + } | |
| 1486 | + return dict_values((dictobject *)mp); | |
| 1487 | +} | |
| 1488 | + | |
| 1489 | +PyObject * | |
| 1490 | +PyDict_Items(PyObject *mp) | |
| 1491 | +{ | |
| 1492 | + if (mp == NULL || !PyDict_Check(mp)) { | |
| 1493 | + PyErr_BadInternalCall(); | |
| 1494 | + return NULL; | |
| 1495 | + } | |
| 1496 | + return dict_items((dictobject *)mp); | |
| 1497 | +} | |
| 1498 | + | |
| 1499 | +/* Subroutine which returns the smallest key in a for which b's value | |
| 1500 | + is different or absent. The value is returned too, through the | |
| 1501 | + pval argument. Both are NULL if no key in a is found for which b's status | |
| 1502 | + differs. The refcounts on (and only on) non-NULL *pval and function return | |
| 1503 | + values must be decremented by the caller (characterize() increments them | |
| 1504 | + to ensure that mutating comparison and PyDict_GetItem calls can't delete | |
| 1505 | + them before the caller is done looking at them). */ | |
| 1506 | + | |
| 1507 | +static PyObject * | |
| 1508 | +characterize(dictobject *a, dictobject *b, PyObject **pval) | |
| 1509 | +{ | |
| 1510 | + PyObject *akey = NULL; /* smallest key in a s.t. a[akey] != b[akey] */ | |
| 1511 | + PyObject *aval = NULL; /* a[akey] */ | |
| 1512 | + Py_ssize_t i; | |
| 1513 | + int cmp; | |
| 1514 | + | |
| 1515 | + for (i = 0; i <= a->ma_mask; i++) { | |
| 1516 | + PyObject *thiskey, *thisaval, *thisbval; | |
| 1517 | + if (a->ma_table[i].me_value == NULL) | |
| 1518 | + continue; | |
| 1519 | + thiskey = a->ma_table[i].me_key; | |
| 1520 | + Py_INCREF(thiskey); /* keep alive across compares */ | |
| 1521 | + if (akey != NULL) { | |
| 1522 | + cmp = PyObject_RichCompareBool(akey, thiskey, Py_LT); | |
| 1523 | + if (cmp < 0) { | |
| 1524 | + Py_DECREF(thiskey); | |
| 1525 | + goto Fail; | |
| 1526 | + } | |
| 1527 | + if (cmp > 0 || | |
| 1528 | + i > a->ma_mask || | |
| 1529 | + a->ma_table[i].me_value == NULL) | |
| 1530 | + { | |
| 1531 | + /* Not the *smallest* a key; or maybe it is | |
| 1532 | + * but the compare shrunk the dict so we can't | |
| 1533 | + * find its associated value anymore; or | |
| 1534 | + * maybe it is but the compare deleted the | |
| 1535 | + * a[thiskey] entry. | |
| 1536 | + */ | |
| 1537 | + Py_DECREF(thiskey); | |
| 1538 | + continue; | |
| 1539 | + } | |
| 1540 | + } | |
| 1541 | + | |
| 1542 | + /* Compare a[thiskey] to b[thiskey]; cmp <- true iff equal. */ | |
| 1543 | + thisaval = a->ma_table[i].me_value; | |
| 1544 | + assert(thisaval); | |
| 1545 | + Py_INCREF(thisaval); /* keep alive */ | |
| 1546 | + thisbval = PyDict_GetItem((PyObject *)b, thiskey); | |
| 1547 | + if (thisbval == NULL) | |
| 1548 | + cmp = 0; | |
| 1549 | + else { | |
| 1550 | + /* both dicts have thiskey: same values? */ | |
| 1551 | + cmp = PyObject_RichCompareBool( | |
| 1552 | + thisaval, thisbval, Py_EQ); | |
| 1553 | + if (cmp < 0) { | |
| 1554 | + Py_DECREF(thiskey); | |
| 1555 | + Py_DECREF(thisaval); | |
| 1556 | + goto Fail; | |
| 1557 | + } | |
| 1558 | + } | |
| 1559 | + if (cmp == 0) { | |
| 1560 | + /* New winner. */ | |
| 1561 | + Py_XDECREF(akey); | |
| 1562 | + Py_XDECREF(aval); | |
| 1563 | + akey = thiskey; | |
| 1564 | + aval = thisaval; | |
| 1565 | + } | |
| 1566 | + else { | |
| 1567 | + Py_DECREF(thiskey); | |
| 1568 | + Py_DECREF(thisaval); | |
| 1569 | + } | |
| 1570 | + } | |
| 1571 | + *pval = aval; | |
| 1572 | + return akey; | |
| 1573 | + | |
| 1574 | +Fail: | |
| 1575 | + Py_XDECREF(akey); | |
| 1576 | + Py_XDECREF(aval); | |
| 1577 | + *pval = NULL; | |
| 1578 | + return NULL; | |
| 1579 | +} | |
| 1580 | + | |
| 1581 | +static int | |
| 1582 | +dict_compare(dictobject *a, dictobject *b) | |
| 1583 | +{ | |
| 1584 | + PyObject *adiff, *bdiff, *aval, *bval; | |
| 1585 | + int res; | |
| 1586 | + | |
| 1587 | + /* Compare lengths first */ | |
| 1588 | + if (a->ma_used < b->ma_used) | |
| 1589 | + return -1; /* a is shorter */ | |
| 1590 | + else if (a->ma_used > b->ma_used) | |
| 1591 | + return 1; /* b is shorter */ | |
| 1592 | + | |
| 1593 | + /* Same length -- check all keys */ | |
| 1594 | + bdiff = bval = NULL; | |
| 1595 | + adiff = characterize(a, b, &aval); | |
| 1596 | + if (adiff == NULL) { | |
| 1597 | + assert(!aval); | |
| 1598 | + /* Either an error, or a is a subset with the same length so | |
| 1599 | + * must be equal. | |
| 1600 | + */ | |
| 1601 | + res = PyErr_Occurred() ? -1 : 0; | |
| 1602 | + goto Finished; | |
| 1603 | + } | |
| 1604 | + bdiff = characterize(b, a, &bval); | |
| 1605 | + if (bdiff == NULL && PyErr_Occurred()) { | |
| 1606 | + assert(!bval); | |
| 1607 | + res = -1; | |
| 1608 | + goto Finished; | |
| 1609 | + } | |
| 1610 | + res = 0; | |
| 1611 | + if (bdiff) { | |
| 1612 | + /* bdiff == NULL "should be" impossible now, but perhaps | |
| 1613 | + * the last comparison done by the characterize() on a had | |
| 1614 | + * the side effect of making the dicts equal! | |
| 1615 | + */ | |
| 1616 | + res = PyObject_Compare(adiff, bdiff); | |
| 1617 | + } | |
| 1618 | + if (res == 0 && bval != NULL) | |
| 1619 | + res = PyObject_Compare(aval, bval); | |
| 1620 | + | |
| 1621 | +Finished: | |
| 1622 | + Py_XDECREF(adiff); | |
| 1623 | + Py_XDECREF(bdiff); | |
| 1624 | + Py_XDECREF(aval); | |
| 1625 | + Py_XDECREF(bval); | |
| 1626 | + return res; | |
| 1627 | +} | |
| 1628 | + | |
| 1629 | +/* Return 1 if dicts equal, 0 if not, -1 if error. | |
| 1630 | + * Gets out as soon as any difference is detected. | |
| 1631 | + * Uses only Py_EQ comparison. | |
| 1632 | + */ | |
| 1633 | +static int | |
| 1634 | +dict_equal(dictobject *a, dictobject *b) | |
| 1635 | +{ | |
| 1636 | + Py_ssize_t i; | |
| 1637 | + | |
| 1638 | + if (a->ma_used != b->ma_used) | |
| 1639 | + /* can't be equal if # of entries differ */ | |
| 1640 | + return 0; | |
| 1641 | + | |
| 1642 | + /* Same # of entries -- check all of 'em. Exit early on any diff. */ | |
| 1643 | + for (i = 0; i <= a->ma_mask; i++) { | |
| 1644 | + PyObject *aval = a->ma_table[i].me_value; | |
| 1645 | + if (aval != NULL) { | |
| 1646 | + int cmp; | |
| 1647 | + PyObject *bval; | |
| 1648 | + PyObject *key = a->ma_table[i].me_key; | |
| 1649 | + /* temporarily bump aval's refcount to ensure it stays | |
| 1650 | + alive until we're done with it */ | |
| 1651 | + Py_INCREF(aval); | |
| 1652 | + /* ditto for key */ | |
| 1653 | + Py_INCREF(key); | |
| 1654 | + bval = PyDict_GetItem((PyObject *)b, key); | |
| 1655 | + Py_DECREF(key); | |
| 1656 | + if (bval == NULL) { | |
| 1657 | + Py_DECREF(aval); | |
| 1658 | + return 0; | |
| 1659 | + } | |
| 1660 | + cmp = PyObject_RichCompareBool(aval, bval, Py_EQ); | |
| 1661 | + Py_DECREF(aval); | |
| 1662 | + if (cmp <= 0) /* error or not equal */ | |
| 1663 | + return cmp; | |
| 1664 | + } | |
| 1665 | + } | |
| 1666 | + return 1; | |
| 1667 | + } | |
| 1668 | + | |
| 1669 | +static PyObject * | |
| 1670 | +dict_richcompare(PyObject *v, PyObject *w, int op) | |
| 1671 | +{ | |
| 1672 | + int cmp; | |
| 1673 | + PyObject *res; | |
| 1674 | + | |
| 1675 | + if (!PyDict_Check(v) || !PyDict_Check(w)) { | |
| 1676 | + res = Py_NotImplemented; | |
| 1677 | + } | |
| 1678 | + else if (op == Py_EQ || op == Py_NE) { | |
| 1679 | + cmp = dict_equal((dictobject *)v, (dictobject *)w); | |
| 1680 | + if (cmp < 0) | |
| 1681 | + return NULL; | |
| 1682 | + res = (cmp == (op == Py_EQ)) ? Py_True : Py_False; | |
| 1683 | + } | |
| 1684 | + else | |
| 1685 | + res = Py_NotImplemented; | |
| 1686 | + Py_INCREF(res); | |
| 1687 | + return res; | |
| 1688 | + } | |
| 1689 | + | |
| 1690 | +static PyObject * | |
| 1691 | +dict_has_key(register dictobject *mp, PyObject *key) | |
| 1692 | +{ | |
| 1693 | + long hash; | |
| 1694 | + dictentry *ep; | |
| 1695 | + | |
| 1696 | + if (!PyString_CheckExact(key) || | |
| 1697 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | |
| 1698 | + hash = PyObject_Hash(key); | |
| 1699 | + if (hash == -1) | |
| 1700 | + return NULL; | |
| 1701 | + } | |
| 1702 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 1703 | + if (ep == NULL) | |
| 1704 | + return NULL; | |
| 1705 | + return PyBool_FromLong(ep->me_value != NULL); | |
| 1706 | +} | |
| 1707 | + | |
| 1708 | +static PyObject * | |
| 1709 | +dict_get(register dictobject *mp, PyObject *args) | |
| 1710 | +{ | |
| 1711 | + PyObject *key; | |
| 1712 | + PyObject *failobj = Py_None; | |
| 1713 | + PyObject *val = NULL; | |
| 1714 | + long hash; | |
| 1715 | + dictentry *ep; | |
| 1716 | + | |
| 1717 | + if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj)) | |
| 1718 | + return NULL; | |
| 1719 | + | |
| 1720 | + if (!PyString_CheckExact(key) || | |
| 1721 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | |
| 1722 | + hash = PyObject_Hash(key); | |
| 1723 | + if (hash == -1) | |
| 1724 | + return NULL; | |
| 1725 | + } | |
| 1726 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 1727 | + if (ep == NULL) | |
| 1728 | + return NULL; | |
| 1729 | + val = ep->me_value; | |
| 1730 | + if (val == NULL) | |
| 1731 | + val = failobj; | |
| 1732 | + Py_INCREF(val); | |
| 1733 | + return val; | |
| 1734 | +} | |
| 1735 | + | |
| 1736 | + | |
| 1737 | +static PyObject * | |
| 1738 | +dict_setdefault(register dictobject *mp, PyObject *args) | |
| 1739 | +{ | |
| 1740 | + PyObject *key; | |
| 1741 | + PyObject *failobj = Py_None; | |
| 1742 | + PyObject *val = NULL; | |
| 1743 | + long hash; | |
| 1744 | + dictentry *ep; | |
| 1745 | + | |
| 1746 | + if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj)) | |
| 1747 | + return NULL; | |
| 1748 | + | |
| 1749 | + if (!PyString_CheckExact(key) || | |
| 1750 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | |
| 1751 | + hash = PyObject_Hash(key); | |
| 1752 | + if (hash == -1) | |
| 1753 | + return NULL; | |
| 1754 | + } | |
| 1755 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 1756 | + if (ep == NULL) | |
| 1757 | + return NULL; | |
| 1758 | + val = ep->me_value; | |
| 1759 | + if (val == NULL) { | |
| 1760 | + val = failobj; | |
| 1761 | + if (PyDict_SetItem((PyObject*)mp, key, failobj)) | |
| 1762 | + val = NULL; | |
| 1763 | + } | |
| 1764 | + Py_XINCREF(val); | |
| 1765 | + return val; | |
| 1766 | +} | |
| 1767 | + | |
| 1768 | + | |
| 1769 | +static PyObject * | |
| 1770 | +dict_clear(register dictobject *mp) | |
| 1771 | +{ | |
| 1772 | + PyDict_Clear((PyObject *)mp); | |
| 1773 | + Py_RETURN_NONE; | |
| 1774 | +} | |
| 1775 | + | |
| 1776 | +static PyObject * | |
| 1777 | +dict_pop(dictobject *mp, PyObject *args) | |
| 1778 | +{ | |
| 1779 | + long hash; | |
| 1780 | + dictentry *ep; | |
| 1781 | + PyObject *old_value, *old_key; | |
| 1782 | + PyObject *key, *deflt = NULL; | |
| 1783 | + | |
| 1784 | + if(!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &deflt)) | |
| 1785 | + return NULL; | |
| 1786 | + if (mp->ma_used == 0) { | |
| 1787 | + if (deflt) { | |
| 1788 | + Py_INCREF(deflt); | |
| 1789 | + return deflt; | |
| 1790 | + } | |
| 1791 | + PyErr_SetString(PyExc_KeyError, | |
| 1792 | + "pop(): dictionary is empty"); | |
| 1793 | + return NULL; | |
| 1794 | + } | |
| 1795 | + if (!PyString_CheckExact(key) || | |
| 1796 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | |
| 1797 | + hash = PyObject_Hash(key); | |
| 1798 | + if (hash == -1) | |
| 1799 | + return NULL; | |
| 1800 | + } | |
| 1801 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 1802 | + if (ep == NULL) | |
| 1803 | + return NULL; | |
| 1804 | + if (ep->me_value == NULL) { | |
| 1805 | + if (deflt) { | |
| 1806 | + Py_INCREF(deflt); | |
| 1807 | + return deflt; | |
| 1808 | + } | |
| 1809 | + set_key_error(key); | |
| 1810 | + return NULL; | |
| 1811 | + } | |
| 1812 | + old_key = ep->me_key; | |
| 1813 | + Py_INCREF(dummy); | |
| 1814 | + ep->me_key = dummy; | |
| 1815 | + old_value = ep->me_value; | |
| 1816 | + ep->me_value = NULL; | |
| 1817 | + mp->ma_used--; | |
| 1818 | + Py_DECREF(old_key); | |
| 1819 | + return old_value; | |
| 1820 | +} | |
| 1821 | + | |
| 1822 | +static PyObject * | |
| 1823 | +dict_popitem(dictobject *mp) | |
| 1824 | +{ | |
| 1825 | + Py_ssize_t i = 0; | |
| 1826 | + dictentry *ep; | |
| 1827 | + PyObject *res; | |
| 1828 | + | |
| 1829 | + /* Allocate the result tuple before checking the size. Believe it | |
| 1830 | + * or not, this allocation could trigger a garbage collection which | |
| 1831 | + * could empty the dict, so if we checked the size first and that | |
| 1832 | + * happened, the result would be an infinite loop (searching for an | |
| 1833 | + * entry that no longer exists). Note that the usual popitem() | |
| 1834 | + * idiom is "while d: k, v = d.popitem()". so needing to throw the | |
| 1835 | + * tuple away if the dict *is* empty isn't a significant | |
| 1836 | + * inefficiency -- possible, but unlikely in practice. | |
| 1837 | + */ | |
| 1838 | + res = PyTuple_New(2); | |
| 1839 | + if (res == NULL) | |
| 1840 | + return NULL; | |
| 1841 | + if (mp->ma_used == 0) { | |
| 1842 | + Py_DECREF(res); | |
| 1843 | + PyErr_SetString(PyExc_KeyError, | |
| 1844 | + "popitem(): dictionary is empty"); | |
| 1845 | + return NULL; | |
| 1846 | + } | |
| 1847 | + /* Set ep to "the first" dict entry with a value. We abuse the hash | |
| 1848 | + * field of slot 0 to hold a search finger: | |
| 1849 | + * If slot 0 has a value, use slot 0. | |
| 1850 | + * Else slot 0 is being used to hold a search finger, | |
| 1851 | + * and we use its hash value as the first index to look. | |
| 1852 | + */ | |
| 1853 | + ep = &mp->ma_table[0]; | |
| 1854 | + if (ep->me_value == NULL) { | |
| 1855 | + i = ep->me_hash; | |
| 1856 | + /* The hash field may be a real hash value, or it may be a | |
| 1857 | + * legit search finger, or it may be a once-legit search | |
| 1858 | + * finger that's out of bounds now because it wrapped around | |
| 1859 | + * or the table shrunk -- simply make sure it's in bounds now. | |
| 1860 | + */ | |
| 1861 | + if (i > mp->ma_mask || i < 1) | |
| 1862 | + i = 1; /* skip slot 0 */ | |
| 1863 | + while ((ep = &mp->ma_table[i])->me_value == NULL) { | |
| 1864 | + i++; | |
| 1865 | + if (i > mp->ma_mask) | |
| 1866 | + i = 1; | |
| 1867 | + } | |
| 1868 | + } | |
| 1869 | + PyTuple_SET_ITEM(res, 0, ep->me_key); | |
| 1870 | + PyTuple_SET_ITEM(res, 1, ep->me_value); | |
| 1871 | + Py_INCREF(dummy); | |
| 1872 | + ep->me_key = dummy; | |
| 1873 | + ep->me_value = NULL; | |
| 1874 | + mp->ma_used--; | |
| 1875 | + assert(mp->ma_table[0].me_value == NULL); | |
| 1876 | + mp->ma_table[0].me_hash = i + 1; /* next place to start */ | |
| 1877 | + return res; | |
| 1878 | +} | |
| 1879 | + | |
| 1880 | +static int | |
| 1881 | +dict_traverse(PyObject *op, visitproc visit, void *arg) | |
| 1882 | +{ | |
| 1883 | + Py_ssize_t i = 0; | |
| 1884 | + PyObject *pk; | |
| 1885 | + PyObject *pv; | |
| 1886 | + | |
| 1887 | + while (PyDict_Next(op, &i, &pk, &pv)) { | |
| 1888 | + Py_VISIT(pk); | |
| 1889 | + Py_VISIT(pv); | |
| 1890 | + } | |
| 1891 | + return 0; | |
| 1892 | +} | |
| 1893 | + | |
| 1894 | +static int | |
| 1895 | +dict_tp_clear(PyObject *op) | |
| 1896 | +{ | |
| 1897 | + PyDict_Clear(op); | |
| 1898 | + return 0; | |
| 1899 | +} | |
| 1900 | + | |
| 1901 | + | |
| 1902 | +extern PyTypeObject PyDictIterKey_Type; /* Forward */ | |
| 1903 | +extern PyTypeObject PyDictIterValue_Type; /* Forward */ | |
| 1904 | +extern PyTypeObject PyDictIterItem_Type; /* Forward */ | |
| 1905 | +static PyObject *dictiter_new(dictobject *, PyTypeObject *); | |
| 1906 | + | |
| 1907 | +static PyObject * | |
| 1908 | +dict_iterkeys(dictobject *dict) | |
| 1909 | +{ | |
| 1910 | + return dictiter_new(dict, &PyDictIterKey_Type); | |
| 1911 | +} | |
| 1912 | + | |
| 1913 | +static PyObject * | |
| 1914 | +dict_itervalues(dictobject *dict) | |
| 1915 | +{ | |
| 1916 | + return dictiter_new(dict, &PyDictIterValue_Type); | |
| 1917 | +} | |
| 1918 | + | |
| 1919 | +static PyObject * | |
| 1920 | +dict_iteritems(dictobject *dict) | |
| 1921 | +{ | |
| 1922 | + return dictiter_new(dict, &PyDictIterItem_Type); | |
| 1923 | +} | |
| 1924 | + | |
| 1925 | + | |
| 1926 | +PyDoc_STRVAR(has_key__doc__, | |
| 1927 | +"D.has_key(k) -> True if D has a key k, else False"); | |
| 1928 | + | |
| 1929 | +PyDoc_STRVAR(contains__doc__, | |
| 1930 | +"D.__contains__(k) -> True if D has a key k, else False"); | |
| 1931 | + | |
| 1932 | +PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); | |
| 1933 | + | |
| 1934 | +PyDoc_STRVAR(get__doc__, | |
| 1935 | +"D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None."); | |
| 1936 | + | |
| 1937 | +PyDoc_STRVAR(setdefault_doc__, | |
| 1938 | +"D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D"); | |
| 1939 | + | |
| 1940 | +PyDoc_STRVAR(pop__doc__, | |
| 1941 | +"D.pop(k[,d]) -> v, remove specified key and return the corresponding value\n\ | |
| 1942 | +If key is not found, d is returned if given, otherwise KeyError is raised"); | |
| 1943 | + | |
| 1944 | +PyDoc_STRVAR(popitem__doc__, | |
| 1945 | +"D.popitem() -> (k, v), remove and return some (key, value) pair as a\n\ | |
| 1946 | +2-tuple; but raise KeyError if D is empty"); | |
| 1947 | + | |
| 1948 | +PyDoc_STRVAR(keys__doc__, | |
| 1949 | +"D.keys() -> list of D's keys"); | |
| 1950 | + | |
| 1951 | +PyDoc_STRVAR(items__doc__, | |
| 1952 | +"D.items() -> list of D's (key, value) pairs, as 2-tuples"); | |
| 1953 | + | |
| 1954 | +PyDoc_STRVAR(values__doc__, | |
| 1955 | +"D.values() -> list of D's values"); | |
| 1956 | + | |
| 1957 | +PyDoc_STRVAR(update__doc__, | |
| 1958 | +"D.update(E, **F) -> None. Update D from E and F: for k in E: D[k] = E[k]\n\ | |
| 1959 | +(if E has keys else: for (k, v) in E: D[k] = v) then: for k in F: D[k] = F[k]"); | |
| 1960 | + | |
| 1961 | +PyDoc_STRVAR(fromkeys__doc__, | |
| 1962 | +"dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\ | |
| 1963 | +v defaults to None."); | |
| 1964 | + | |
| 1965 | +PyDoc_STRVAR(clear__doc__, | |
| 1966 | +"D.clear() -> None. Remove all items from D."); | |
| 1967 | + | |
| 1968 | +PyDoc_STRVAR(copy__doc__, | |
| 1969 | +"D.copy() -> a shallow copy of D"); | |
| 1970 | + | |
| 1971 | +PyDoc_STRVAR(iterkeys__doc__, | |
| 1972 | +"D.iterkeys() -> an iterator over the keys of D"); | |
| 1973 | + | |
| 1974 | +PyDoc_STRVAR(itervalues__doc__, | |
| 1975 | +"D.itervalues() -> an iterator over the values of D"); | |
| 1976 | + | |
| 1977 | +PyDoc_STRVAR(iteritems__doc__, | |
| 1978 | +"D.iteritems() -> an iterator over the (key, value) items of D"); | |
| 1979 | + | |
| 1980 | +static PyMethodDef mapp_methods[] = { | |
| 1981 | + {"__contains__",(PyCFunction)dict_has_key, METH_O | METH_COEXIST, | |
| 1982 | + contains__doc__}, | |
| 1983 | + {"__getitem__", (PyCFunction)dict_subscript, METH_O | METH_COEXIST, | |
| 1984 | + getitem__doc__}, | |
| 1985 | + {"has_key", (PyCFunction)dict_has_key, METH_O, | |
| 1986 | + has_key__doc__}, | |
| 1987 | + {"get", (PyCFunction)dict_get, METH_VARARGS, | |
| 1988 | + get__doc__}, | |
| 1989 | + {"setdefault", (PyCFunction)dict_setdefault, METH_VARARGS, | |
| 1990 | + setdefault_doc__}, | |
| 1991 | + {"pop", (PyCFunction)dict_pop, METH_VARARGS, | |
| 1992 | + pop__doc__}, | |
| 1993 | + {"popitem", (PyCFunction)dict_popitem, METH_NOARGS, | |
| 1994 | + popitem__doc__}, | |
| 1995 | + {"keys", (PyCFunction)dict_keys, METH_NOARGS, | |
| 1996 | + keys__doc__}, | |
| 1997 | + {"items", (PyCFunction)dict_items, METH_NOARGS, | |
| 1998 | + items__doc__}, | |
| 1999 | + {"values", (PyCFunction)dict_values, METH_NOARGS, | |
| 2000 | + values__doc__}, | |
| 2001 | + {"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS, | |
| 2002 | + update__doc__}, | |
| 2003 | + {"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS | METH_CLASS, | |
| 2004 | + fromkeys__doc__}, | |
| 2005 | + {"clear", (PyCFunction)dict_clear, METH_NOARGS, | |
| 2006 | + clear__doc__}, | |
| 2007 | + {"copy", (PyCFunction)dict_copy, METH_NOARGS, | |
| 2008 | + copy__doc__}, | |
| 2009 | + {"iterkeys", (PyCFunction)dict_iterkeys, METH_NOARGS, | |
| 2010 | + iterkeys__doc__}, | |
| 2011 | + {"itervalues", (PyCFunction)dict_itervalues, METH_NOARGS, | |
| 2012 | + itervalues__doc__}, | |
| 2013 | + {"iteritems", (PyCFunction)dict_iteritems, METH_NOARGS, | |
| 2014 | + iteritems__doc__}, | |
| 2015 | + {NULL, NULL} /* sentinel */ | |
| 2016 | +}; | |
| 2017 | + | |
| 2018 | +/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */ | |
| 2019 | +int | |
| 2020 | +PyDict_Contains(PyObject *op, PyObject *key) | |
| 2021 | +{ | |
| 2022 | + long hash; | |
| 2023 | + dictobject *mp = (dictobject *)op; | |
| 2024 | + dictentry *ep; | |
| 2025 | + | |
| 2026 | + if (!PyString_CheckExact(key) || | |
| 2027 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | |
| 2028 | + hash = PyObject_Hash(key); | |
| 2029 | + if (hash == -1) | |
| 2030 | + return -1; | |
| 2031 | + } | |
| 2032 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 2033 | + return ep == NULL ? -1 : (ep->me_value != NULL); | |
| 2034 | +} | |
| 2035 | + | |
| 2036 | +/* Internal version of PyDict_Contains used when the hash value is already known */ | |
| 2037 | +int | |
| 2038 | +_PyDict_Contains(PyObject *op, PyObject *key, long hash) | |
| 2039 | +{ | |
| 2040 | + dictobject *mp = (dictobject *)op; | |
| 2041 | + dictentry *ep; | |
| 2042 | + | |
| 2043 | + ep = (mp->ma_lookup)(mp, key, hash); | |
| 2044 | + return ep == NULL ? -1 : (ep->me_value != NULL); | |
| 2045 | +} | |
| 2046 | + | |
| 2047 | +/* Hack to implement "key in dict" */ | |
| 2048 | +static PySequenceMethods dict_as_sequence = { | |
| 2049 | + 0, /* sq_length */ | |
| 2050 | + 0, /* sq_concat */ | |
| 2051 | + 0, /* sq_repeat */ | |
| 2052 | + 0, /* sq_item */ | |
| 2053 | + 0, /* sq_slice */ | |
| 2054 | + 0, /* sq_ass_item */ | |
| 2055 | + 0, /* sq_ass_slice */ | |
| 2056 | + PyDict_Contains, /* sq_contains */ | |
| 2057 | + 0, /* sq_inplace_concat */ | |
| 2058 | + 0, /* sq_inplace_repeat */ | |
| 2059 | +}; | |
| 2060 | + | |
| 2061 | +static PyObject * | |
| 2062 | +dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 2063 | +{ | |
| 2064 | + PyObject *self; | |
| 2065 | + | |
| 2066 | + assert(type != NULL && type->tp_alloc != NULL); | |
| 2067 | + self = type->tp_alloc(type, 0); | |
| 2068 | + if (self != NULL) { | |
| 2069 | + PyDictObject *d = (PyDictObject *)self; | |
| 2070 | + /* It's guaranteed that tp->alloc zeroed out the struct. */ | |
| 2071 | + assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0); | |
| 2072 | + INIT_NONZERO_DICT_SLOTS(d); | |
| 2073 | + d->ma_lookup = lookdict_string; | |
| 2074 | +#ifdef SHOW_CONVERSION_COUNTS | |
| 2075 | + ++created; | |
| 2076 | +#endif | |
| 2077 | + } | |
| 2078 | + return self; | |
| 2079 | +} | |
| 2080 | + | |
| 2081 | +static int | |
| 2082 | +dict_init(PyObject *self, PyObject *args, PyObject *kwds) | |
| 2083 | +{ | |
| 2084 | + return dict_update_common(self, args, kwds, "dict"); | |
| 2085 | +} | |
| 2086 | + | |
| 2087 | +static long | |
| 2088 | +dict_nohash(PyObject *self) | |
| 2089 | +{ | |
| 2090 | + PyErr_SetString(PyExc_TypeError, "dict objects are unhashable"); | |
| 2091 | + return -1; | |
| 2092 | +} | |
| 2093 | + | |
| 2094 | +static PyObject * | |
| 2095 | +dict_iter(dictobject *dict) | |
| 2096 | +{ | |
| 2097 | + return dictiter_new(dict, &PyDictIterKey_Type); | |
| 2098 | +} | |
| 2099 | + | |
| 2100 | +PyDoc_STRVAR(dictionary_doc, | |
| 2101 | +"dict() -> new empty dictionary.\n" | |
| 2102 | +"dict(mapping) -> new dictionary initialized from a mapping object's\n" | |
| 2103 | +" (key, value) pairs.\n" | |
| 2104 | +"dict(seq) -> new dictionary initialized as if via:\n" | |
| 2105 | +" d = {}\n" | |
| 2106 | +" for k, v in seq:\n" | |
| 2107 | +" d[k] = v\n" | |
| 2108 | +"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n" | |
| 2109 | +" in the keyword argument list. For example: dict(one=1, two=2)"); | |
| 2110 | + | |
| 2111 | +PyTypeObject PyDict_Type = { | |
| 2112 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 2113 | + 0, | |
| 2114 | + "dict", | |
| 2115 | + sizeof(dictobject), | |
| 2116 | + 0, | |
| 2117 | + (destructor)dict_dealloc, /* tp_dealloc */ | |
| 2118 | + (printfunc)dict_print, /* tp_print */ | |
| 2119 | + 0, /* tp_getattr */ | |
| 2120 | + 0, /* tp_setattr */ | |
| 2121 | + (cmpfunc)dict_compare, /* tp_compare */ | |
| 2122 | + (reprfunc)dict_repr, /* tp_repr */ | |
| 2123 | + 0, /* tp_as_number */ | |
| 2124 | + &dict_as_sequence, /* tp_as_sequence */ | |
| 2125 | + &dict_as_mapping, /* tp_as_mapping */ | |
| 2126 | + dict_nohash, /* tp_hash */ | |
| 2127 | + 0, /* tp_call */ | |
| 2128 | + 0, /* tp_str */ | |
| 2129 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 2130 | + 0, /* tp_setattro */ | |
| 2131 | + 0, /* tp_as_buffer */ | |
| 2132 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | |
| 2133 | + Py_TPFLAGS_BASETYPE, /* tp_flags */ | |
| 2134 | + dictionary_doc, /* tp_doc */ | |
| 2135 | + dict_traverse, /* tp_traverse */ | |
| 2136 | + dict_tp_clear, /* tp_clear */ | |
| 2137 | + dict_richcompare, /* tp_richcompare */ | |
| 2138 | + 0, /* tp_weaklistoffset */ | |
| 2139 | + (getiterfunc)dict_iter, /* tp_iter */ | |
| 2140 | + 0, /* tp_iternext */ | |
| 2141 | + mapp_methods, /* tp_methods */ | |
| 2142 | + 0, /* tp_members */ | |
| 2143 | + 0, /* tp_getset */ | |
| 2144 | + 0, /* tp_base */ | |
| 2145 | + 0, /* tp_dict */ | |
| 2146 | + 0, /* tp_descr_get */ | |
| 2147 | + 0, /* tp_descr_set */ | |
| 2148 | + 0, /* tp_dictoffset */ | |
| 2149 | + dict_init, /* tp_init */ | |
| 2150 | + PyType_GenericAlloc, /* tp_alloc */ | |
| 2151 | + dict_new, /* tp_new */ | |
| 2152 | + PyObject_GC_Del, /* tp_free */ | |
| 2153 | +}; | |
| 2154 | + | |
| 2155 | +/* For backward compatibility with old dictionary interface */ | |
| 2156 | + | |
| 2157 | +PyObject * | |
| 2158 | +PyDict_GetItemString(PyObject *v, const char *key) | |
| 2159 | +{ | |
| 2160 | + PyObject *kv, *rv; | |
| 2161 | + kv = PyString_FromString(key); | |
| 2162 | + if (kv == NULL) | |
| 2163 | + return NULL; | |
| 2164 | + rv = PyDict_GetItem(v, kv); | |
| 2165 | + Py_DECREF(kv); | |
| 2166 | + return rv; | |
| 2167 | +} | |
| 2168 | + | |
| 2169 | +int | |
| 2170 | +PyDict_SetItemString(PyObject *v, const char *key, PyObject *item) | |
| 2171 | +{ | |
| 2172 | + PyObject *kv; | |
| 2173 | + int err; | |
| 2174 | + kv = PyString_FromString(key); | |
| 2175 | + if (kv == NULL) | |
| 2176 | + return -1; | |
| 2177 | + PyString_InternInPlace(&kv); /* XXX Should we really? */ | |
| 2178 | + err = PyDict_SetItem(v, kv, item); | |
| 2179 | + Py_DECREF(kv); | |
| 2180 | + return err; | |
| 2181 | +} | |
| 2182 | + | |
| 2183 | +int | |
| 2184 | +PyDict_DelItemString(PyObject *v, const char *key) | |
| 2185 | +{ | |
| 2186 | + PyObject *kv; | |
| 2187 | + int err; | |
| 2188 | + kv = PyString_FromString(key); | |
| 2189 | + if (kv == NULL) | |
| 2190 | + return -1; | |
| 2191 | + err = PyDict_DelItem(v, kv); | |
| 2192 | + Py_DECREF(kv); | |
| 2193 | + return err; | |
| 2194 | +} | |
| 2195 | + | |
| 2196 | +/* Dictionary iterator types */ | |
| 2197 | + | |
| 2198 | +typedef struct { | |
| 2199 | + PyObject_HEAD | |
| 2200 | + dictobject *di_dict; /* Set to NULL when iterator is exhausted */ | |
| 2201 | + Py_ssize_t di_used; | |
| 2202 | + Py_ssize_t di_pos; | |
| 2203 | + PyObject* di_result; /* reusable result tuple for iteritems */ | |
| 2204 | + Py_ssize_t len; | |
| 2205 | +} dictiterobject; | |
| 2206 | + | |
| 2207 | +static PyObject * | |
| 2208 | +dictiter_new(dictobject *dict, PyTypeObject *itertype) | |
| 2209 | +{ | |
| 2210 | + dictiterobject *di; | |
| 2211 | + di = PyObject_New(dictiterobject, itertype); | |
| 2212 | + if (di == NULL) | |
| 2213 | + return NULL; | |
| 2214 | + Py_INCREF(dict); | |
| 2215 | + di->di_dict = dict; | |
| 2216 | + di->di_used = dict->ma_used; | |
| 2217 | + di->di_pos = 0; | |
| 2218 | + di->len = dict->ma_used; | |
| 2219 | + if (itertype == &PyDictIterItem_Type) { | |
| 2220 | + di->di_result = PyTuple_Pack(2, Py_None, Py_None); | |
| 2221 | + if (di->di_result == NULL) { | |
| 2222 | + Py_DECREF(di); | |
| 2223 | + return NULL; | |
| 2224 | + } | |
| 2225 | + } | |
| 2226 | + else | |
| 2227 | + di->di_result = NULL; | |
| 2228 | + return (PyObject *)di; | |
| 2229 | +} | |
| 2230 | + | |
| 2231 | +static void | |
| 2232 | +dictiter_dealloc(dictiterobject *di) | |
| 2233 | +{ | |
| 2234 | + Py_XDECREF(di->di_dict); | |
| 2235 | + Py_XDECREF(di->di_result); | |
| 2236 | + PyObject_Del(di); | |
| 2237 | +} | |
| 2238 | + | |
| 2239 | +static PyObject * | |
| 2240 | +dictiter_len(dictiterobject *di) | |
| 2241 | +{ | |
| 2242 | + Py_ssize_t len = 0; | |
| 2243 | + if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used) | |
| 2244 | + len = di->len; | |
| 2245 | + return PyInt_FromSize_t(len); | |
| 2246 | +} | |
| 2247 | + | |
| 2248 | +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); | |
| 2249 | + | |
| 2250 | +static PyMethodDef dictiter_methods[] = { | |
| 2251 | + {"__length_hint__", (PyCFunction)dictiter_len, METH_NOARGS, length_hint_doc}, | |
| 2252 | + {NULL, NULL} /* sentinel */ | |
| 2253 | +}; | |
| 2254 | + | |
| 2255 | +static PyObject *dictiter_iternextkey(dictiterobject *di) | |
| 2256 | +{ | |
| 2257 | + PyObject *key; | |
| 2258 | + register Py_ssize_t i, mask; | |
| 2259 | + register dictentry *ep; | |
| 2260 | + dictobject *d = di->di_dict; | |
| 2261 | + | |
| 2262 | + if (d == NULL) | |
| 2263 | + return NULL; | |
| 2264 | + assert (PyDict_Check(d)); | |
| 2265 | + | |
| 2266 | + if (di->di_used != d->ma_used) { | |
| 2267 | + PyErr_SetString(PyExc_RuntimeError, | |
| 2268 | + "dictionary changed size during iteration"); | |
| 2269 | + di->di_used = -1; /* Make this state sticky */ | |
| 2270 | + return NULL; | |
| 2271 | + } | |
| 2272 | + | |
| 2273 | + i = di->di_pos; | |
| 2274 | + if (i < 0) | |
| 2275 | + goto fail; | |
| 2276 | + ep = d->ma_table; | |
| 2277 | + mask = d->ma_mask; | |
| 2278 | + while (i <= mask && ep[i].me_value == NULL) | |
| 2279 | + i++; | |
| 2280 | + di->di_pos = i+1; | |
| 2281 | + if (i > mask) | |
| 2282 | + goto fail; | |
| 2283 | + di->len--; | |
| 2284 | + key = ep[i].me_key; | |
| 2285 | + Py_INCREF(key); | |
| 2286 | + return key; | |
| 2287 | + | |
| 2288 | +fail: | |
| 2289 | + Py_DECREF(d); | |
| 2290 | + di->di_dict = NULL; | |
| 2291 | + return NULL; | |
| 2292 | +} | |
| 2293 | + | |
| 2294 | +PyTypeObject PyDictIterKey_Type = { | |
| 2295 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 2296 | + 0, /* ob_size */ | |
| 2297 | + "dictionary-keyiterator", /* tp_name */ | |
| 2298 | + sizeof(dictiterobject), /* tp_basicsize */ | |
| 2299 | + 0, /* tp_itemsize */ | |
| 2300 | + /* methods */ | |
| 2301 | + (destructor)dictiter_dealloc, /* tp_dealloc */ | |
| 2302 | + 0, /* tp_print */ | |
| 2303 | + 0, /* tp_getattr */ | |
| 2304 | + 0, /* tp_setattr */ | |
| 2305 | + 0, /* tp_compare */ | |
| 2306 | + 0, /* tp_repr */ | |
| 2307 | + 0, /* tp_as_number */ | |
| 2308 | + 0, /* tp_as_sequence */ | |
| 2309 | + 0, /* tp_as_mapping */ | |
| 2310 | + 0, /* tp_hash */ | |
| 2311 | + 0, /* tp_call */ | |
| 2312 | + 0, /* tp_str */ | |
| 2313 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 2314 | + 0, /* tp_setattro */ | |
| 2315 | + 0, /* tp_as_buffer */ | |
| 2316 | + Py_TPFLAGS_DEFAULT, /* tp_flags */ | |
| 2317 | + 0, /* tp_doc */ | |
| 2318 | + 0, /* tp_traverse */ | |
| 2319 | + 0, /* tp_clear */ | |
| 2320 | + 0, /* tp_richcompare */ | |
| 2321 | + 0, /* tp_weaklistoffset */ | |
| 2322 | + PyObject_SelfIter, /* tp_iter */ | |
| 2323 | + (iternextfunc)dictiter_iternextkey, /* tp_iternext */ | |
| 2324 | + dictiter_methods, /* tp_methods */ | |
| 2325 | + 0, | |
| 2326 | +}; | |
| 2327 | + | |
| 2328 | +static PyObject *dictiter_iternextvalue(dictiterobject *di) | |
| 2329 | +{ | |
| 2330 | + PyObject *value; | |
| 2331 | + register Py_ssize_t i, mask; | |
| 2332 | + register dictentry *ep; | |
| 2333 | + dictobject *d = di->di_dict; | |
| 2334 | + | |
| 2335 | + if (d == NULL) | |
| 2336 | + return NULL; | |
| 2337 | + assert (PyDict_Check(d)); | |
| 2338 | + | |
| 2339 | + if (di->di_used != d->ma_used) { | |
| 2340 | + PyErr_SetString(PyExc_RuntimeError, | |
| 2341 | + "dictionary changed size during iteration"); | |
| 2342 | + di->di_used = -1; /* Make this state sticky */ | |
| 2343 | + return NULL; | |
| 2344 | + } | |
| 2345 | + | |
| 2346 | + i = di->di_pos; | |
| 2347 | + mask = d->ma_mask; | |
| 2348 | + if (i < 0 || i > mask) | |
| 2349 | + goto fail; | |
| 2350 | + ep = d->ma_table; | |
| 2351 | + while ((value=ep[i].me_value) == NULL) { | |
| 2352 | + i++; | |
| 2353 | + if (i > mask) | |
| 2354 | + goto fail; | |
| 2355 | + } | |
| 2356 | + di->di_pos = i+1; | |
| 2357 | + di->len--; | |
| 2358 | + Py_INCREF(value); | |
| 2359 | + return value; | |
| 2360 | + | |
| 2361 | +fail: | |
| 2362 | + Py_DECREF(d); | |
| 2363 | + di->di_dict = NULL; | |
| 2364 | + return NULL; | |
| 2365 | +} | |
| 2366 | + | |
| 2367 | +PyTypeObject PyDictIterValue_Type = { | |
| 2368 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 2369 | + 0, /* ob_size */ | |
| 2370 | + "dictionary-valueiterator", /* tp_name */ | |
| 2371 | + sizeof(dictiterobject), /* tp_basicsize */ | |
| 2372 | + 0, /* tp_itemsize */ | |
| 2373 | + /* methods */ | |
| 2374 | + (destructor)dictiter_dealloc, /* tp_dealloc */ | |
| 2375 | + 0, /* tp_print */ | |
| 2376 | + 0, /* tp_getattr */ | |
| 2377 | + 0, /* tp_setattr */ | |
| 2378 | + 0, /* tp_compare */ | |
| 2379 | + 0, /* tp_repr */ | |
| 2380 | + 0, /* tp_as_number */ | |
| 2381 | + 0, /* tp_as_sequence */ | |
| 2382 | + 0, /* tp_as_mapping */ | |
| 2383 | + 0, /* tp_hash */ | |
| 2384 | + 0, /* tp_call */ | |
| 2385 | + 0, /* tp_str */ | |
| 2386 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 2387 | + 0, /* tp_setattro */ | |
| 2388 | + 0, /* tp_as_buffer */ | |
| 2389 | + Py_TPFLAGS_DEFAULT, /* tp_flags */ | |
| 2390 | + 0, /* tp_doc */ | |
| 2391 | + 0, /* tp_traverse */ | |
| 2392 | + 0, /* tp_clear */ | |
| 2393 | + 0, /* tp_richcompare */ | |
| 2394 | + 0, /* tp_weaklistoffset */ | |
| 2395 | + PyObject_SelfIter, /* tp_iter */ | |
| 2396 | + (iternextfunc)dictiter_iternextvalue, /* tp_iternext */ | |
| 2397 | + dictiter_methods, /* tp_methods */ | |
| 2398 | + 0, | |
| 2399 | +}; | |
| 2400 | + | |
| 2401 | +static PyObject *dictiter_iternextitem(dictiterobject *di) | |
| 2402 | +{ | |
| 2403 | + PyObject *key, *value, *result = di->di_result; | |
| 2404 | + register Py_ssize_t i, mask; | |
| 2405 | + register dictentry *ep; | |
| 2406 | + dictobject *d = di->di_dict; | |
| 2407 | + | |
| 2408 | + if (d == NULL) | |
| 2409 | + return NULL; | |
| 2410 | + assert (PyDict_Check(d)); | |
| 2411 | + | |
| 2412 | + if (di->di_used != d->ma_used) { | |
| 2413 | + PyErr_SetString(PyExc_RuntimeError, | |
| 2414 | + "dictionary changed size during iteration"); | |
| 2415 | + di->di_used = -1; /* Make this state sticky */ | |
| 2416 | + return NULL; | |
| 2417 | + } | |
| 2418 | + | |
| 2419 | + i = di->di_pos; | |
| 2420 | + if (i < 0) | |
| 2421 | + goto fail; | |
| 2422 | + ep = d->ma_table; | |
| 2423 | + mask = d->ma_mask; | |
| 2424 | + while (i <= mask && ep[i].me_value == NULL) | |
| 2425 | + i++; | |
| 2426 | + di->di_pos = i+1; | |
| 2427 | + if (i > mask) | |
| 2428 | + goto fail; | |
| 2429 | + | |
| 2430 | + if (result->ob_refcnt == 1) { | |
| 2431 | + Py_INCREF(result); | |
| 2432 | + Py_DECREF(PyTuple_GET_ITEM(result, 0)); | |
| 2433 | + Py_DECREF(PyTuple_GET_ITEM(result, 1)); | |
| 2434 | + } else { | |
| 2435 | + result = PyTuple_New(2); | |
| 2436 | + if (result == NULL) | |
| 2437 | + return NULL; | |
| 2438 | + } | |
| 2439 | + di->len--; | |
| 2440 | + key = ep[i].me_key; | |
| 2441 | + value = ep[i].me_value; | |
| 2442 | + Py_INCREF(key); | |
| 2443 | + Py_INCREF(value); | |
| 2444 | + PyTuple_SET_ITEM(result, 0, key); | |
| 2445 | + PyTuple_SET_ITEM(result, 1, value); | |
| 2446 | + return result; | |
| 2447 | + | |
| 2448 | +fail: | |
| 2449 | + Py_DECREF(d); | |
| 2450 | + di->di_dict = NULL; | |
| 2451 | + return NULL; | |
| 2452 | +} | |
| 2453 | + | |
| 2454 | +PyTypeObject PyDictIterItem_Type = { | |
| 2455 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 2456 | + 0, /* ob_size */ | |
| 2457 | + "dictionary-itemiterator", /* tp_name */ | |
| 2458 | + sizeof(dictiterobject), /* tp_basicsize */ | |
| 2459 | + 0, /* tp_itemsize */ | |
| 2460 | + /* methods */ | |
| 2461 | + (destructor)dictiter_dealloc, /* tp_dealloc */ | |
| 2462 | + 0, /* tp_print */ | |
| 2463 | + 0, /* tp_getattr */ | |
| 2464 | + 0, /* tp_setattr */ | |
| 2465 | + 0, /* tp_compare */ | |
| 2466 | + 0, /* tp_repr */ | |
| 2467 | + 0, /* tp_as_number */ | |
| 2468 | + 0, /* tp_as_sequence */ | |
| 2469 | + 0, /* tp_as_mapping */ | |
| 2470 | + 0, /* tp_hash */ | |
| 2471 | + 0, /* tp_call */ | |
| 2472 | + 0, /* tp_str */ | |
| 2473 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 2474 | + 0, /* tp_setattro */ | |
| 2475 | + 0, /* tp_as_buffer */ | |
| 2476 | + Py_TPFLAGS_DEFAULT, /* tp_flags */ | |
| 2477 | + 0, /* tp_doc */ | |
| 2478 | + 0, /* tp_traverse */ | |
| 2479 | + 0, /* tp_clear */ | |
| 2480 | + 0, /* tp_richcompare */ | |
| 2481 | + 0, /* tp_weaklistoffset */ | |
| 2482 | + PyObject_SelfIter, /* tp_iter */ | |
| 2483 | + (iternextfunc)dictiter_iternextitem, /* tp_iternext */ | |
| 2484 | + dictiter_methods, /* tp_methods */ | |
| 2485 | + 0, | |
| 2486 | +}; | |
| @@ -0,0 +1,298 @@ | ||
| 1 | +/* enumerate object */ | |
| 2 | + | |
| 3 | +#include "Python.h" | |
| 4 | + | |
| 5 | +typedef struct { | |
| 6 | + PyObject_HEAD | |
| 7 | + long en_index; /* current index of enumeration */ | |
| 8 | + PyObject* en_sit; /* secondary iterator of enumeration */ | |
| 9 | + PyObject* en_result; /* result tuple */ | |
| 10 | +} enumobject; | |
| 11 | + | |
| 12 | +static PyObject * | |
| 13 | +enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 14 | +{ | |
| 15 | + enumobject *en; | |
| 16 | + PyObject *seq = NULL; | |
| 17 | + static char *kwlist[] = {"sequence", 0}; | |
| 18 | + | |
| 19 | + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:enumerate", kwlist, | |
| 20 | + &seq)) | |
| 21 | + return NULL; | |
| 22 | + | |
| 23 | + en = (enumobject *)type->tp_alloc(type, 0); | |
| 24 | + if (en == NULL) | |
| 25 | + return NULL; | |
| 26 | + en->en_index = 0; | |
| 27 | + en->en_sit = PyObject_GetIter(seq); | |
| 28 | + if (en->en_sit == NULL) { | |
| 29 | + Py_DECREF(en); | |
| 30 | + return NULL; | |
| 31 | + } | |
| 32 | + en->en_result = PyTuple_Pack(2, Py_None, Py_None); | |
| 33 | + if (en->en_result == NULL) { | |
| 34 | + Py_DECREF(en); | |
| 35 | + return NULL; | |
| 36 | + } | |
| 37 | + return (PyObject *)en; | |
| 38 | +} | |
| 39 | + | |
| 40 | +static void | |
| 41 | +enum_dealloc(enumobject *en) | |
| 42 | +{ | |
| 43 | + PyObject_GC_UnTrack(en); | |
| 44 | + Py_XDECREF(en->en_sit); | |
| 45 | + Py_XDECREF(en->en_result); | |
| 46 | + en->ob_type->tp_free(en); | |
| 47 | +} | |
| 48 | + | |
| 49 | +static int | |
| 50 | +enum_traverse(enumobject *en, visitproc visit, void *arg) | |
| 51 | +{ | |
| 52 | + Py_VISIT(en->en_sit); | |
| 53 | + Py_VISIT(en->en_result); | |
| 54 | + return 0; | |
| 55 | +} | |
| 56 | + | |
| 57 | +static PyObject * | |
| 58 | +enum_next(enumobject *en) | |
| 59 | +{ | |
| 60 | + PyObject *next_index; | |
| 61 | + PyObject *next_item; | |
| 62 | + PyObject *result = en->en_result; | |
| 63 | + PyObject *it = en->en_sit; | |
| 64 | + | |
| 65 | + if (en->en_index == LONG_MAX) { | |
| 66 | + PyErr_SetString(PyExc_OverflowError, | |
| 67 | + "enumerate() is limited to LONG_MAX items"); | |
| 68 | + return NULL; | |
| 69 | + } | |
| 70 | + | |
| 71 | + next_item = (*it->ob_type->tp_iternext)(it); | |
| 72 | + if (next_item == NULL) | |
| 73 | + return NULL; | |
| 74 | + | |
| 75 | + next_index = PyInt_FromLong(en->en_index); | |
| 76 | + if (next_index == NULL) { | |
| 77 | + Py_DECREF(next_item); | |
| 78 | + return NULL; | |
| 79 | + } | |
| 80 | + en->en_index++; | |
| 81 | + | |
| 82 | + if (result->ob_refcnt == 1) { | |
| 83 | + Py_INCREF(result); | |
| 84 | + Py_DECREF(PyTuple_GET_ITEM(result, 0)); | |
| 85 | + Py_DECREF(PyTuple_GET_ITEM(result, 1)); | |
| 86 | + } else { | |
| 87 | + result = PyTuple_New(2); | |
| 88 | + if (result == NULL) { | |
| 89 | + Py_DECREF(next_index); | |
| 90 | + Py_DECREF(next_item); | |
| 91 | + return NULL; | |
| 92 | + } | |
| 93 | + } | |
| 94 | + PyTuple_SET_ITEM(result, 0, next_index); | |
| 95 | + PyTuple_SET_ITEM(result, 1, next_item); | |
| 96 | + return result; | |
| 97 | +} | |
| 98 | + | |
| 99 | +PyDoc_STRVAR(enum_doc, | |
| 100 | +"enumerate(iterable) -> iterator for index, value of iterable\n" | |
| 101 | +"\n" | |
| 102 | +"Return an enumerate object. iterable must be an other object that supports\n" | |
| 103 | +"iteration. The enumerate object yields pairs containing a count (from\n" | |
| 104 | +"zero) and a value yielded by the iterable argument. enumerate is useful\n" | |
| 105 | +"for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ..."); | |
| 106 | + | |
| 107 | +PyTypeObject PyEnum_Type = { | |
| 108 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 109 | + 0, /* ob_size */ | |
| 110 | + "enumerate", /* tp_name */ | |
| 111 | + sizeof(enumobject), /* tp_basicsize */ | |
| 112 | + 0, /* tp_itemsize */ | |
| 113 | + /* methods */ | |
| 114 | + (destructor)enum_dealloc, /* tp_dealloc */ | |
| 115 | + 0, /* tp_print */ | |
| 116 | + 0, /* tp_getattr */ | |
| 117 | + 0, /* tp_setattr */ | |
| 118 | + 0, /* tp_compare */ | |
| 119 | + 0, /* tp_repr */ | |
| 120 | + 0, /* tp_as_number */ | |
| 121 | + 0, /* tp_as_sequence */ | |
| 122 | + 0, /* tp_as_mapping */ | |
| 123 | + 0, /* tp_hash */ | |
| 124 | + 0, /* tp_call */ | |
| 125 | + 0, /* tp_str */ | |
| 126 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 127 | + 0, /* tp_setattro */ | |
| 128 | + 0, /* tp_as_buffer */ | |
| 129 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | |
| 130 | + Py_TPFLAGS_BASETYPE, /* tp_flags */ | |
| 131 | + enum_doc, /* tp_doc */ | |
| 132 | + (traverseproc)enum_traverse, /* tp_traverse */ | |
| 133 | + 0, /* tp_clear */ | |
| 134 | + 0, /* tp_richcompare */ | |
| 135 | + 0, /* tp_weaklistoffset */ | |
| 136 | + PyObject_SelfIter, /* tp_iter */ | |
| 137 | + (iternextfunc)enum_next, /* tp_iternext */ | |
| 138 | + 0, /* tp_methods */ | |
| 139 | + 0, /* tp_members */ | |
| 140 | + 0, /* tp_getset */ | |
| 141 | + 0, /* tp_base */ | |
| 142 | + 0, /* tp_dict */ | |
| 143 | + 0, /* tp_descr_get */ | |
| 144 | + 0, /* tp_descr_set */ | |
| 145 | + 0, /* tp_dictoffset */ | |
| 146 | + 0, /* tp_init */ | |
| 147 | + PyType_GenericAlloc, /* tp_alloc */ | |
| 148 | + enum_new, /* tp_new */ | |
| 149 | + PyObject_GC_Del, /* tp_free */ | |
| 150 | +}; | |
| 151 | + | |
| 152 | +/* Reversed Object ***************************************************************/ | |
| 153 | + | |
| 154 | +typedef struct { | |
| 155 | + PyObject_HEAD | |
| 156 | + Py_ssize_t index; | |
| 157 | + PyObject* seq; | |
| 158 | +} reversedobject; | |
| 159 | + | |
| 160 | +static PyObject * | |
| 161 | +reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 162 | +{ | |
| 163 | + Py_ssize_t n; | |
| 164 | + PyObject *seq; | |
| 165 | + reversedobject *ro; | |
| 166 | + | |
| 167 | + if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq)) | |
| 168 | + return NULL; | |
| 169 | + | |
| 170 | + if (PyObject_HasAttrString(seq, "__reversed__")) | |
| 171 | + return PyObject_CallMethod(seq, "__reversed__", NULL); | |
| 172 | + | |
| 173 | + if (!PySequence_Check(seq)) { | |
| 174 | + PyErr_SetString(PyExc_TypeError, | |
| 175 | + "argument to reversed() must be a sequence"); | |
| 176 | + return NULL; | |
| 177 | + } | |
| 178 | + | |
| 179 | + n = PySequence_Size(seq); | |
| 180 | + if (n == -1) | |
| 181 | + return NULL; | |
| 182 | + | |
| 183 | + ro = (reversedobject *)type->tp_alloc(type, 0); | |
| 184 | + if (ro == NULL) | |
| 185 | + return NULL; | |
| 186 | + | |
| 187 | + ro->index = n-1; | |
| 188 | + Py_INCREF(seq); | |
| 189 | + ro->seq = seq; | |
| 190 | + return (PyObject *)ro; | |
| 191 | +} | |
| 192 | + | |
| 193 | +static void | |
| 194 | +reversed_dealloc(reversedobject *ro) | |
| 195 | +{ | |
| 196 | + PyObject_GC_UnTrack(ro); | |
| 197 | + Py_XDECREF(ro->seq); | |
| 198 | + ro->ob_type->tp_free(ro); | |
| 199 | +} | |
| 200 | + | |
| 201 | +static int | |
| 202 | +reversed_traverse(reversedobject *ro, visitproc visit, void *arg) | |
| 203 | +{ | |
| 204 | + Py_VISIT(ro->seq); | |
| 205 | + return 0; | |
| 206 | +} | |
| 207 | + | |
| 208 | +static PyObject * | |
| 209 | +reversed_next(reversedobject *ro) | |
| 210 | +{ | |
| 211 | + PyObject *item; | |
| 212 | + Py_ssize_t index = ro->index; | |
| 213 | + | |
| 214 | + if (index >= 0) { | |
| 215 | + item = PySequence_GetItem(ro->seq, index); | |
| 216 | + if (item != NULL) { | |
| 217 | + ro->index--; | |
| 218 | + return item; | |
| 219 | + } | |
| 220 | + if (PyErr_ExceptionMatches(PyExc_IndexError) || | |
| 221 | + PyErr_ExceptionMatches(PyExc_StopIteration)) | |
| 222 | + PyErr_Clear(); | |
| 223 | + } | |
| 224 | + ro->index = -1; | |
| 225 | + Py_CLEAR(ro->seq); | |
| 226 | + return NULL; | |
| 227 | +} | |
| 228 | + | |
| 229 | +PyDoc_STRVAR(reversed_doc, | |
| 230 | +"reversed(sequence) -> reverse iterator over values of the sequence\n" | |
| 231 | +"\n" | |
| 232 | +"Return a reverse iterator"); | |
| 233 | + | |
| 234 | +static PyObject * | |
| 235 | +reversed_len(reversedobject *ro) | |
| 236 | +{ | |
| 237 | + Py_ssize_t position, seqsize; | |
| 238 | + | |
| 239 | + if (ro->seq == NULL) | |
| 240 | + return PyInt_FromLong(0); | |
| 241 | + seqsize = PySequence_Size(ro->seq); | |
| 242 | + if (seqsize == -1) | |
| 243 | + return NULL; | |
| 244 | + position = ro->index + 1; | |
| 245 | + return PyInt_FromSsize_t((seqsize < position) ? 0 : position); | |
| 246 | +} | |
| 247 | + | |
| 248 | +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); | |
| 249 | + | |
| 250 | +static PyMethodDef reversediter_methods[] = { | |
| 251 | + {"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc}, | |
| 252 | + {NULL, NULL} /* sentinel */ | |
| 253 | +}; | |
| 254 | + | |
| 255 | +PyTypeObject PyReversed_Type = { | |
| 256 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 257 | + 0, /* ob_size */ | |
| 258 | + "reversed", /* tp_name */ | |
| 259 | + sizeof(reversedobject), /* tp_basicsize */ | |
| 260 | + 0, /* tp_itemsize */ | |
| 261 | + /* methods */ | |
| 262 | + (destructor)reversed_dealloc, /* tp_dealloc */ | |
| 263 | + 0, /* tp_print */ | |
| 264 | + 0, /* tp_getattr */ | |
| 265 | + 0, /* tp_setattr */ | |
| 266 | + 0, /* tp_compare */ | |
| 267 | + 0, /* tp_repr */ | |
| 268 | + 0, /* tp_as_number */ | |
| 269 | + 0, /* tp_as_sequence */ | |
| 270 | + 0, /* tp_as_mapping */ | |
| 271 | + 0, /* tp_hash */ | |
| 272 | + 0, /* tp_call */ | |
| 273 | + 0, /* tp_str */ | |
| 274 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 275 | + 0, /* tp_setattro */ | |
| 276 | + 0, /* tp_as_buffer */ | |
| 277 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | |
| 278 | + Py_TPFLAGS_BASETYPE, /* tp_flags */ | |
| 279 | + reversed_doc, /* tp_doc */ | |
| 280 | + (traverseproc)reversed_traverse,/* tp_traverse */ | |
| 281 | + 0, /* tp_clear */ | |
| 282 | + 0, /* tp_richcompare */ | |
| 283 | + 0, /* tp_weaklistoffset */ | |
| 284 | + PyObject_SelfIter, /* tp_iter */ | |
| 285 | + (iternextfunc)reversed_next, /* tp_iternext */ | |
| 286 | + reversediter_methods, /* tp_methods */ | |
| 287 | + 0, /* tp_members */ | |
| 288 | + 0, /* tp_getset */ | |
| 289 | + 0, /* tp_base */ | |
| 290 | + 0, /* tp_dict */ | |
| 291 | + 0, /* tp_descr_get */ | |
| 292 | + 0, /* tp_descr_set */ | |
| 293 | + 0, /* tp_dictoffset */ | |
| 294 | + 0, /* tp_init */ | |
| 295 | + PyType_GenericAlloc, /* tp_alloc */ | |
| 296 | + reversed_new, /* tp_new */ | |
| 297 | + PyObject_GC_Del, /* tp_free */ | |
| 298 | +}; | |
| @@ -0,0 +1,2147 @@ | ||
| 1 | +/* | |
| 2 | + * New exceptions.c written in Iceland by Richard Jones and Georg Brandl. | |
| 3 | + * | |
| 4 | + * Thanks go to Tim Peters and Michael Hudson for debugging. | |
| 5 | + */ | |
| 6 | + | |
| 7 | +#define PY_SSIZE_T_CLEAN | |
| 8 | +#include <Python.h> | |
| 9 | +#include "structmember.h" | |
| 10 | +#include "osdefs.h" | |
| 11 | + | |
| 12 | +#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None); | |
| 13 | +#define EXC_MODULE_NAME "exceptions." | |
| 14 | + | |
| 15 | +/* NOTE: If the exception class hierarchy changes, don't forget to update | |
| 16 | + * Lib/test/exception_hierarchy.txt | |
| 17 | + */ | |
| 18 | + | |
| 19 | +PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\ | |
| 20 | +\n\ | |
| 21 | +Exceptions found here are defined both in the exceptions module and the\n\ | |
| 22 | +built-in namespace. It is recommended that user-defined exceptions\n\ | |
| 23 | +inherit from Exception. See the documentation for the exception\n\ | |
| 24 | +inheritance hierarchy.\n\ | |
| 25 | +"); | |
| 26 | + | |
| 27 | +/* | |
| 28 | + * BaseException | |
| 29 | + */ | |
| 30 | +static PyObject * | |
| 31 | +BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 32 | +{ | |
| 33 | + PyBaseExceptionObject *self; | |
| 34 | + | |
| 35 | + self = (PyBaseExceptionObject *)type->tp_alloc(type, 0); | |
| 36 | + /* the dict is created on the fly in PyObject_GenericSetAttr */ | |
| 37 | + self->message = self->dict = NULL; | |
| 38 | + | |
| 39 | + self->args = PyTuple_New(0); | |
| 40 | + if (!self->args) { | |
| 41 | + Py_DECREF(self); | |
| 42 | + return NULL; | |
| 43 | + } | |
| 44 | + | |
| 45 | + self->message = PyString_FromString(""); | |
| 46 | + if (!self->message) { | |
| 47 | + Py_DECREF(self); | |
| 48 | + return NULL; | |
| 49 | + } | |
| 50 | + | |
| 51 | + return (PyObject *)self; | |
| 52 | +} | |
| 53 | + | |
| 54 | +static int | |
| 55 | +BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds) | |
| 56 | +{ | |
| 57 | + if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds)) | |
| 58 | + return -1; | |
| 59 | + | |
| 60 | + Py_DECREF(self->args); | |
| 61 | + self->args = args; | |
| 62 | + Py_INCREF(self->args); | |
| 63 | + | |
| 64 | + if (PyTuple_GET_SIZE(self->args) == 1) { | |
| 65 | + Py_CLEAR(self->message); | |
| 66 | + self->message = PyTuple_GET_ITEM(self->args, 0); | |
| 67 | + Py_INCREF(self->message); | |
| 68 | + } | |
| 69 | + return 0; | |
| 70 | +} | |
| 71 | + | |
| 72 | +static int | |
| 73 | +BaseException_clear(PyBaseExceptionObject *self) | |
| 74 | +{ | |
| 75 | + Py_CLEAR(self->dict); | |
| 76 | + Py_CLEAR(self->args); | |
| 77 | + Py_CLEAR(self->message); | |
| 78 | + return 0; | |
| 79 | +} | |
| 80 | + | |
| 81 | +static void | |
| 82 | +BaseException_dealloc(PyBaseExceptionObject *self) | |
| 83 | +{ | |
| 84 | + _PyObject_GC_UNTRACK(self); | |
| 85 | + BaseException_clear(self); | |
| 86 | + self->ob_type->tp_free((PyObject *)self); | |
| 87 | +} | |
| 88 | + | |
| 89 | +static int | |
| 90 | +BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg) | |
| 91 | +{ | |
| 92 | + Py_VISIT(self->dict); | |
| 93 | + Py_VISIT(self->args); | |
| 94 | + Py_VISIT(self->message); | |
| 95 | + return 0; | |
| 96 | +} | |
| 97 | + | |
| 98 | +static PyObject * | |
| 99 | +BaseException_str(PyBaseExceptionObject *self) | |
| 100 | +{ | |
| 101 | + PyObject *out; | |
| 102 | + | |
| 103 | + switch (PyTuple_GET_SIZE(self->args)) { | |
| 104 | + case 0: | |
| 105 | + out = PyString_FromString(""); | |
| 106 | + break; | |
| 107 | + case 1: | |
| 108 | + out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0)); | |
| 109 | + break; | |
| 110 | + default: | |
| 111 | + out = PyObject_Str(self->args); | |
| 112 | + break; | |
| 113 | + } | |
| 114 | + | |
| 115 | + return out; | |
| 116 | +} | |
| 117 | + | |
| 118 | +static PyObject * | |
| 119 | +BaseException_repr(PyBaseExceptionObject *self) | |
| 120 | +{ | |
| 121 | + PyObject *repr_suffix; | |
| 122 | + PyObject *repr; | |
| 123 | + char *name; | |
| 124 | + char *dot; | |
| 125 | + | |
| 126 | + repr_suffix = PyObject_Repr(self->args); | |
| 127 | + if (!repr_suffix) | |
| 128 | + return NULL; | |
| 129 | + | |
| 130 | + name = (char *)self->ob_type->tp_name; | |
| 131 | + dot = strrchr(name, '.'); | |
| 132 | + if (dot != NULL) name = dot+1; | |
| 133 | + | |
| 134 | + repr = PyString_FromString(name); | |
| 135 | + if (!repr) { | |
| 136 | + Py_DECREF(repr_suffix); | |
| 137 | + return NULL; | |
| 138 | + } | |
| 139 | + | |
| 140 | + PyString_ConcatAndDel(&repr, repr_suffix); | |
| 141 | + return repr; | |
| 142 | +} | |
| 143 | + | |
| 144 | +/* Pickling support */ | |
| 145 | +static PyObject * | |
| 146 | +BaseException_reduce(PyBaseExceptionObject *self) | |
| 147 | +{ | |
| 148 | + if (self->args && self->dict) | |
| 149 | + return PyTuple_Pack(3, self->ob_type, self->args, self->dict); | |
| 150 | + else | |
| 151 | + return PyTuple_Pack(2, self->ob_type, self->args); | |
| 152 | +} | |
| 153 | + | |
| 154 | +/* | |
| 155 | + * Needed for backward compatibility, since exceptions used to store | |
| 156 | + * all their attributes in the __dict__. Code is taken from cPickle's | |
| 157 | + * load_build function. | |
| 158 | + */ | |
| 159 | +static PyObject * | |
| 160 | +BaseException_setstate(PyObject *self, PyObject *state) | |
| 161 | +{ | |
| 162 | + PyObject *d_key, *d_value; | |
| 163 | + Py_ssize_t i = 0; | |
| 164 | + | |
| 165 | + if (state != Py_None) { | |
| 166 | + if (!PyDict_Check(state)) { | |
| 167 | + PyErr_SetString(PyExc_TypeError, "state is not a dictionary"); | |
| 168 | + return NULL; | |
| 169 | + } | |
| 170 | + while (PyDict_Next(state, &i, &d_key, &d_value)) { | |
| 171 | + if (PyObject_SetAttr(self, d_key, d_value) < 0) | |
| 172 | + return NULL; | |
| 173 | + } | |
| 174 | + } | |
| 175 | + Py_RETURN_NONE; | |
| 176 | +} | |
| 177 | + | |
| 178 | + | |
| 179 | +static PyMethodDef BaseException_methods[] = { | |
| 180 | + {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS }, | |
| 181 | + {"__setstate__", (PyCFunction)BaseException_setstate, METH_O }, | |
| 182 | + {NULL, NULL, 0, NULL}, | |
| 183 | +}; | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | +static PyObject * | |
| 188 | +BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index) | |
| 189 | +{ | |
| 190 | + return PySequence_GetItem(self->args, index); | |
| 191 | +} | |
| 192 | + | |
| 193 | +static PyObject * | |
| 194 | +BaseException_getslice(PyBaseExceptionObject *self, | |
| 195 | + Py_ssize_t start, Py_ssize_t stop) | |
| 196 | +{ | |
| 197 | + return PySequence_GetSlice(self->args, start, stop); | |
| 198 | +} | |
| 199 | + | |
| 200 | +static PySequenceMethods BaseException_as_sequence = { | |
| 201 | + 0, /* sq_length; */ | |
| 202 | + 0, /* sq_concat; */ | |
| 203 | + 0, /* sq_repeat; */ | |
| 204 | + (ssizeargfunc)BaseException_getitem, /* sq_item; */ | |
| 205 | + (ssizessizeargfunc)BaseException_getslice, /* sq_slice; */ | |
| 206 | + 0, /* sq_ass_item; */ | |
| 207 | + 0, /* sq_ass_slice; */ | |
| 208 | + 0, /* sq_contains; */ | |
| 209 | + 0, /* sq_inplace_concat; */ | |
| 210 | + 0 /* sq_inplace_repeat; */ | |
| 211 | +}; | |
| 212 | + | |
| 213 | +static PyMemberDef BaseException_members[] = { | |
| 214 | + {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0, | |
| 215 | + PyDoc_STR("exception message")}, | |
| 216 | + {NULL} /* Sentinel */ | |
| 217 | +}; | |
| 218 | + | |
| 219 | + | |
| 220 | +static PyObject * | |
| 221 | +BaseException_get_dict(PyBaseExceptionObject *self) | |
| 222 | +{ | |
| 223 | + if (self->dict == NULL) { | |
| 224 | + self->dict = PyDict_New(); | |
| 225 | + if (!self->dict) | |
| 226 | + return NULL; | |
| 227 | + } | |
| 228 | + Py_INCREF(self->dict); | |
| 229 | + return self->dict; | |
| 230 | +} | |
| 231 | + | |
| 232 | +static int | |
| 233 | +BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val) | |
| 234 | +{ | |
| 235 | + if (val == NULL) { | |
| 236 | + PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted"); | |
| 237 | + return -1; | |
| 238 | + } | |
| 239 | + if (!PyDict_Check(val)) { | |
| 240 | + PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary"); | |
| 241 | + return -1; | |
| 242 | + } | |
| 243 | + Py_CLEAR(self->dict); | |
| 244 | + Py_INCREF(val); | |
| 245 | + self->dict = val; | |
| 246 | + return 0; | |
| 247 | +} | |
| 248 | + | |
| 249 | +static PyObject * | |
| 250 | +BaseException_get_args(PyBaseExceptionObject *self) | |
| 251 | +{ | |
| 252 | + if (self->args == NULL) { | |
| 253 | + Py_INCREF(Py_None); | |
| 254 | + return Py_None; | |
| 255 | + } | |
| 256 | + Py_INCREF(self->args); | |
| 257 | + return self->args; | |
| 258 | +} | |
| 259 | + | |
| 260 | +static int | |
| 261 | +BaseException_set_args(PyBaseExceptionObject *self, PyObject *val) | |
| 262 | +{ | |
| 263 | + PyObject *seq; | |
| 264 | + if (val == NULL) { | |
| 265 | + PyErr_SetString(PyExc_TypeError, "args may not be deleted"); | |
| 266 | + return -1; | |
| 267 | + } | |
| 268 | + seq = PySequence_Tuple(val); | |
| 269 | + if (!seq) return -1; | |
| 270 | + Py_CLEAR(self->args); | |
| 271 | + self->args = seq; | |
| 272 | + return 0; | |
| 273 | +} | |
| 274 | + | |
| 275 | +static PyGetSetDef BaseException_getset[] = { | |
| 276 | + {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict}, | |
| 277 | + {"args", (getter)BaseException_get_args, (setter)BaseException_set_args}, | |
| 278 | + {NULL}, | |
| 279 | +}; | |
| 280 | + | |
| 281 | + | |
| 282 | +static PyTypeObject _PyExc_BaseException = { | |
| 283 | + PyObject_HEAD_INIT(NULL) | |
| 284 | + 0, /*ob_size*/ | |
| 285 | + EXC_MODULE_NAME "BaseException", /*tp_name*/ | |
| 286 | + sizeof(PyBaseExceptionObject), /*tp_basicsize*/ | |
| 287 | + 0, /*tp_itemsize*/ | |
| 288 | + (destructor)BaseException_dealloc, /*tp_dealloc*/ | |
| 289 | + 0, /*tp_print*/ | |
| 290 | + 0, /*tp_getattr*/ | |
| 291 | + 0, /*tp_setattr*/ | |
| 292 | + 0, /* tp_compare; */ | |
| 293 | + (reprfunc)BaseException_repr, /*tp_repr*/ | |
| 294 | + 0, /*tp_as_number*/ | |
| 295 | + &BaseException_as_sequence, /*tp_as_sequence*/ | |
| 296 | + 0, /*tp_as_mapping*/ | |
| 297 | + 0, /*tp_hash */ | |
| 298 | + 0, /*tp_call*/ | |
| 299 | + (reprfunc)BaseException_str, /*tp_str*/ | |
| 300 | + PyObject_GenericGetAttr, /*tp_getattro*/ | |
| 301 | + PyObject_GenericSetAttr, /*tp_setattro*/ | |
| 302 | + 0, /*tp_as_buffer*/ | |
| 303 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ | |
| 304 | + PyDoc_STR("Common base class for all exceptions"), /* tp_doc */ | |
| 305 | + (traverseproc)BaseException_traverse, /* tp_traverse */ | |
| 306 | + (inquiry)BaseException_clear, /* tp_clear */ | |
| 307 | + 0, /* tp_richcompare */ | |
| 308 | + 0, /* tp_weaklistoffset */ | |
| 309 | + 0, /* tp_iter */ | |
| 310 | + 0, /* tp_iternext */ | |
| 311 | + BaseException_methods, /* tp_methods */ | |
| 312 | + BaseException_members, /* tp_members */ | |
| 313 | + BaseException_getset, /* tp_getset */ | |
| 314 | + 0, /* tp_base */ | |
| 315 | + 0, /* tp_dict */ | |
| 316 | + 0, /* tp_descr_get */ | |
| 317 | + 0, /* tp_descr_set */ | |
| 318 | + offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */ | |
| 319 | + (initproc)BaseException_init, /* tp_init */ | |
| 320 | + 0, /* tp_alloc */ | |
| 321 | + BaseException_new, /* tp_new */ | |
| 322 | +}; | |
| 323 | +/* the CPython API expects exceptions to be (PyObject *) - both a hold-over | |
| 324 | +from the previous implmentation and also allowing Python objects to be used | |
| 325 | +in the API */ | |
| 326 | +PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException; | |
| 327 | + | |
| 328 | +/* note these macros omit the last semicolon so the macro invocation may | |
| 329 | + * include it and not look strange. | |
| 330 | + */ | |
| 331 | +#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \ | |
| 332 | +static PyTypeObject _PyExc_ ## EXCNAME = { \ | |
| 333 | + PyObject_HEAD_INIT(NULL) \ | |
| 334 | + 0, \ | |
| 335 | + EXC_MODULE_NAME # EXCNAME, \ | |
| 336 | + sizeof(PyBaseExceptionObject), \ | |
| 337 | + 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \ | |
| 338 | + 0, 0, 0, 0, 0, 0, 0, \ | |
| 339 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ | |
| 340 | + PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \ | |
| 341 | + (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \ | |
| 342 | + 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \ | |
| 343 | + (initproc)BaseException_init, 0, BaseException_new,\ | |
| 344 | +}; \ | |
| 345 | +PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME | |
| 346 | + | |
| 347 | +#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \ | |
| 348 | +static PyTypeObject _PyExc_ ## EXCNAME = { \ | |
| 349 | + PyObject_HEAD_INIT(NULL) \ | |
| 350 | + 0, \ | |
| 351 | + EXC_MODULE_NAME # EXCNAME, \ | |
| 352 | + sizeof(Py ## EXCSTORE ## Object), \ | |
| 353 | + 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | |
| 354 | + 0, 0, 0, 0, 0, \ | |
| 355 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ | |
| 356 | + PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \ | |
| 357 | + (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \ | |
| 358 | + 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \ | |
| 359 | + (initproc)EXCSTORE ## _init, 0, BaseException_new,\ | |
| 360 | +}; \ | |
| 361 | +PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME | |
| 362 | + | |
| 363 | +#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \ | |
| 364 | +static PyTypeObject _PyExc_ ## EXCNAME = { \ | |
| 365 | + PyObject_HEAD_INIT(NULL) \ | |
| 366 | + 0, \ | |
| 367 | + EXC_MODULE_NAME # EXCNAME, \ | |
| 368 | + sizeof(Py ## EXCSTORE ## Object), 0, \ | |
| 369 | + (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | |
| 370 | + (reprfunc)EXCSTR, 0, 0, 0, \ | |
| 371 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ | |
| 372 | + PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \ | |
| 373 | + (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \ | |
| 374 | + EXCMEMBERS, 0, &_ ## EXCBASE, \ | |
| 375 | + 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \ | |
| 376 | + (initproc)EXCSTORE ## _init, 0, BaseException_new,\ | |
| 377 | +}; \ | |
| 378 | +PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME | |
| 379 | + | |
| 380 | + | |
| 381 | +/* | |
| 382 | + * Exception extends BaseException | |
| 383 | + */ | |
| 384 | +SimpleExtendsException(PyExc_BaseException, Exception, | |
| 385 | + "Common base class for all non-exit exceptions."); | |
| 386 | + | |
| 387 | + | |
| 388 | +/* | |
| 389 | + * StandardError extends Exception | |
| 390 | + */ | |
| 391 | +SimpleExtendsException(PyExc_Exception, StandardError, | |
| 392 | + "Base class for all standard Python exceptions that do not represent\n" | |
| 393 | + "interpreter exiting."); | |
| 394 | + | |
| 395 | + | |
| 396 | +/* | |
| 397 | + * TypeError extends StandardError | |
| 398 | + */ | |
| 399 | +SimpleExtendsException(PyExc_StandardError, TypeError, | |
| 400 | + "Inappropriate argument type."); | |
| 401 | + | |
| 402 | + | |
| 403 | +/* | |
| 404 | + * StopIteration extends Exception | |
| 405 | + */ | |
| 406 | +SimpleExtendsException(PyExc_Exception, StopIteration, | |
| 407 | + "Signal the end from iterator.next()."); | |
| 408 | + | |
| 409 | + | |
| 410 | +/* | |
| 411 | + * GeneratorExit extends Exception | |
| 412 | + */ | |
| 413 | +SimpleExtendsException(PyExc_Exception, GeneratorExit, | |
| 414 | + "Request that a generator exit."); | |
| 415 | + | |
| 416 | + | |
| 417 | +/* | |
| 418 | + * SystemExit extends BaseException | |
| 419 | + */ | |
| 420 | + | |
| 421 | +static int | |
| 422 | +SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds) | |
| 423 | +{ | |
| 424 | + Py_ssize_t size = PyTuple_GET_SIZE(args); | |
| 425 | + | |
| 426 | + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) | |
| 427 | + return -1; | |
| 428 | + | |
| 429 | + if (size == 0) | |
| 430 | + return 0; | |
| 431 | + Py_CLEAR(self->code); | |
| 432 | + if (size == 1) | |
| 433 | + self->code = PyTuple_GET_ITEM(args, 0); | |
| 434 | + else if (size > 1) | |
| 435 | + self->code = args; | |
| 436 | + Py_INCREF(self->code); | |
| 437 | + return 0; | |
| 438 | +} | |
| 439 | + | |
| 440 | +static int | |
| 441 | +SystemExit_clear(PySystemExitObject *self) | |
| 442 | +{ | |
| 443 | + Py_CLEAR(self->code); | |
| 444 | + return BaseException_clear((PyBaseExceptionObject *)self); | |
| 445 | +} | |
| 446 | + | |
| 447 | +static void | |
| 448 | +SystemExit_dealloc(PySystemExitObject *self) | |
| 449 | +{ | |
| 450 | + _PyObject_GC_UNTRACK(self); | |
| 451 | + SystemExit_clear(self); | |
| 452 | + self->ob_type->tp_free((PyObject *)self); | |
| 453 | +} | |
| 454 | + | |
| 455 | +static int | |
| 456 | +SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg) | |
| 457 | +{ | |
| 458 | + Py_VISIT(self->code); | |
| 459 | + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); | |
| 460 | +} | |
| 461 | + | |
| 462 | +static PyMemberDef SystemExit_members[] = { | |
| 463 | + {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0, | |
| 464 | + PyDoc_STR("exception message")}, | |
| 465 | + {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0, | |
| 466 | + PyDoc_STR("exception code")}, | |
| 467 | + {NULL} /* Sentinel */ | |
| 468 | +}; | |
| 469 | + | |
| 470 | +ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit, | |
| 471 | + SystemExit_dealloc, 0, SystemExit_members, 0, | |
| 472 | + "Request to exit from the interpreter."); | |
| 473 | + | |
| 474 | +/* | |
| 475 | + * KeyboardInterrupt extends BaseException | |
| 476 | + */ | |
| 477 | +SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt, | |
| 478 | + "Program interrupted by user."); | |
| 479 | + | |
| 480 | + | |
| 481 | +/* | |
| 482 | + * ImportError extends StandardError | |
| 483 | + */ | |
| 484 | +SimpleExtendsException(PyExc_StandardError, ImportError, | |
| 485 | + "Import can't find module, or can't find name in module."); | |
| 486 | + | |
| 487 | + | |
| 488 | +/* | |
| 489 | + * EnvironmentError extends StandardError | |
| 490 | + */ | |
| 491 | + | |
| 492 | +/* Where a function has a single filename, such as open() or some | |
| 493 | + * of the os module functions, PyErr_SetFromErrnoWithFilename() is | |
| 494 | + * called, giving a third argument which is the filename. But, so | |
| 495 | + * that old code using in-place unpacking doesn't break, e.g.: | |
| 496 | + * | |
| 497 | + * except IOError, (errno, strerror): | |
| 498 | + * | |
| 499 | + * we hack args so that it only contains two items. This also | |
| 500 | + * means we need our own __str__() which prints out the filename | |
| 501 | + * when it was supplied. | |
| 502 | + */ | |
| 503 | +static int | |
| 504 | +EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args, | |
| 505 | + PyObject *kwds) | |
| 506 | +{ | |
| 507 | + PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL; | |
| 508 | + PyObject *subslice = NULL; | |
| 509 | + | |
| 510 | + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) | |
| 511 | + return -1; | |
| 512 | + | |
| 513 | + if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) { | |
| 514 | + return 0; | |
| 515 | + } | |
| 516 | + | |
| 517 | + if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3, | |
| 518 | + &myerrno, &strerror, &filename)) { | |
| 519 | + return -1; | |
| 520 | + } | |
| 521 | + Py_CLEAR(self->myerrno); /* replacing */ | |
| 522 | + self->myerrno = myerrno; | |
| 523 | + Py_INCREF(self->myerrno); | |
| 524 | + | |
| 525 | + Py_CLEAR(self->strerror); /* replacing */ | |
| 526 | + self->strerror = strerror; | |
| 527 | + Py_INCREF(self->strerror); | |
| 528 | + | |
| 529 | + /* self->filename will remain Py_None otherwise */ | |
| 530 | + if (filename != NULL) { | |
| 531 | + Py_CLEAR(self->filename); /* replacing */ | |
| 532 | + self->filename = filename; | |
| 533 | + Py_INCREF(self->filename); | |
| 534 | + | |
| 535 | + subslice = PyTuple_GetSlice(args, 0, 2); | |
| 536 | + if (!subslice) | |
| 537 | + return -1; | |
| 538 | + | |
| 539 | + Py_DECREF(self->args); /* replacing args */ | |
| 540 | + self->args = subslice; | |
| 541 | + } | |
| 542 | + return 0; | |
| 543 | +} | |
| 544 | + | |
| 545 | +static int | |
| 546 | +EnvironmentError_clear(PyEnvironmentErrorObject *self) | |
| 547 | +{ | |
| 548 | + Py_CLEAR(self->myerrno); | |
| 549 | + Py_CLEAR(self->strerror); | |
| 550 | + Py_CLEAR(self->filename); | |
| 551 | + return BaseException_clear((PyBaseExceptionObject *)self); | |
| 552 | +} | |
| 553 | + | |
| 554 | +static void | |
| 555 | +EnvironmentError_dealloc(PyEnvironmentErrorObject *self) | |
| 556 | +{ | |
| 557 | + _PyObject_GC_UNTRACK(self); | |
| 558 | + EnvironmentError_clear(self); | |
| 559 | + self->ob_type->tp_free((PyObject *)self); | |
| 560 | +} | |
| 561 | + | |
| 562 | +static int | |
| 563 | +EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit, | |
| 564 | + void *arg) | |
| 565 | +{ | |
| 566 | + Py_VISIT(self->myerrno); | |
| 567 | + Py_VISIT(self->strerror); | |
| 568 | + Py_VISIT(self->filename); | |
| 569 | + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); | |
| 570 | +} | |
| 571 | + | |
| 572 | +static PyObject * | |
| 573 | +EnvironmentError_str(PyEnvironmentErrorObject *self) | |
| 574 | +{ | |
| 575 | + PyObject *rtnval = NULL; | |
| 576 | + | |
| 577 | + if (self->filename) { | |
| 578 | + PyObject *fmt; | |
| 579 | + PyObject *repr; | |
| 580 | + PyObject *tuple; | |
| 581 | + | |
| 582 | + fmt = PyString_FromString("[Errno %s] %s: %s"); | |
| 583 | + if (!fmt) | |
| 584 | + return NULL; | |
| 585 | + | |
| 586 | + repr = PyObject_Repr(self->filename); | |
| 587 | + if (!repr) { | |
| 588 | + Py_DECREF(fmt); | |
| 589 | + return NULL; | |
| 590 | + } | |
| 591 | + tuple = PyTuple_New(3); | |
| 592 | + if (!tuple) { | |
| 593 | + Py_DECREF(repr); | |
| 594 | + Py_DECREF(fmt); | |
| 595 | + return NULL; | |
| 596 | + } | |
| 597 | + | |
| 598 | + if (self->myerrno) { | |
| 599 | + Py_INCREF(self->myerrno); | |
| 600 | + PyTuple_SET_ITEM(tuple, 0, self->myerrno); | |
| 601 | + } | |
| 602 | + else { | |
| 603 | + Py_INCREF(Py_None); | |
| 604 | + PyTuple_SET_ITEM(tuple, 0, Py_None); | |
| 605 | + } | |
| 606 | + if (self->strerror) { | |
| 607 | + Py_INCREF(self->strerror); | |
| 608 | + PyTuple_SET_ITEM(tuple, 1, self->strerror); | |
| 609 | + } | |
| 610 | + else { | |
| 611 | + Py_INCREF(Py_None); | |
| 612 | + PyTuple_SET_ITEM(tuple, 1, Py_None); | |
| 613 | + } | |
| 614 | + | |
| 615 | + PyTuple_SET_ITEM(tuple, 2, repr); | |
| 616 | + | |
| 617 | + rtnval = PyString_Format(fmt, tuple); | |
| 618 | + | |
| 619 | + Py_DECREF(fmt); | |
| 620 | + Py_DECREF(tuple); | |
| 621 | + } | |
| 622 | + else if (self->myerrno && self->strerror) { | |
| 623 | + PyObject *fmt; | |
| 624 | + PyObject *tuple; | |
| 625 | + | |
| 626 | + fmt = PyString_FromString("[Errno %s] %s"); | |
| 627 | + if (!fmt) | |
| 628 | + return NULL; | |
| 629 | + | |
| 630 | + tuple = PyTuple_New(2); | |
| 631 | + if (!tuple) { | |
| 632 | + Py_DECREF(fmt); | |
| 633 | + return NULL; | |
| 634 | + } | |
| 635 | + | |
| 636 | + if (self->myerrno) { | |
| 637 | + Py_INCREF(self->myerrno); | |
| 638 | + PyTuple_SET_ITEM(tuple, 0, self->myerrno); | |
| 639 | + } | |
| 640 | + else { | |
| 641 | + Py_INCREF(Py_None); | |
| 642 | + PyTuple_SET_ITEM(tuple, 0, Py_None); | |
| 643 | + } | |
| 644 | + if (self->strerror) { | |
| 645 | + Py_INCREF(self->strerror); | |
| 646 | + PyTuple_SET_ITEM(tuple, 1, self->strerror); | |
| 647 | + } | |
| 648 | + else { | |
| 649 | + Py_INCREF(Py_None); | |
| 650 | + PyTuple_SET_ITEM(tuple, 1, Py_None); | |
| 651 | + } | |
| 652 | + | |
| 653 | + rtnval = PyString_Format(fmt, tuple); | |
| 654 | + | |
| 655 | + Py_DECREF(fmt); | |
| 656 | + Py_DECREF(tuple); | |
| 657 | + } | |
| 658 | + else | |
| 659 | + rtnval = BaseException_str((PyBaseExceptionObject *)self); | |
| 660 | + | |
| 661 | + return rtnval; | |
| 662 | +} | |
| 663 | + | |
| 664 | +static PyMemberDef EnvironmentError_members[] = { | |
| 665 | + {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0, | |
| 666 | + PyDoc_STR("exception message")}, | |
| 667 | + {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0, | |
| 668 | + PyDoc_STR("exception errno")}, | |
| 669 | + {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0, | |
| 670 | + PyDoc_STR("exception strerror")}, | |
| 671 | + {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0, | |
| 672 | + PyDoc_STR("exception filename")}, | |
| 673 | + {NULL} /* Sentinel */ | |
| 674 | +}; | |
| 675 | + | |
| 676 | + | |
| 677 | +static PyObject * | |
| 678 | +EnvironmentError_reduce(PyEnvironmentErrorObject *self) | |
| 679 | +{ | |
| 680 | + PyObject *args = self->args; | |
| 681 | + PyObject *res = NULL, *tmp; | |
| 682 | + | |
| 683 | + /* self->args is only the first two real arguments if there was a | |
| 684 | + * file name given to EnvironmentError. */ | |
| 685 | + if (PyTuple_GET_SIZE(args) == 2 && self->filename) { | |
| 686 | + args = PyTuple_New(3); | |
| 687 | + if (!args) return NULL; | |
| 688 | + | |
| 689 | + tmp = PyTuple_GET_ITEM(self->args, 0); | |
| 690 | + Py_INCREF(tmp); | |
| 691 | + PyTuple_SET_ITEM(args, 0, tmp); | |
| 692 | + | |
| 693 | + tmp = PyTuple_GET_ITEM(self->args, 1); | |
| 694 | + Py_INCREF(tmp); | |
| 695 | + PyTuple_SET_ITEM(args, 1, tmp); | |
| 696 | + | |
| 697 | + Py_INCREF(self->filename); | |
| 698 | + PyTuple_SET_ITEM(args, 2, self->filename); | |
| 699 | + } else | |
| 700 | + Py_INCREF(args); | |
| 701 | + | |
| 702 | + if (self->dict) | |
| 703 | + res = PyTuple_Pack(3, self->ob_type, args, self->dict); | |
| 704 | + else | |
| 705 | + res = PyTuple_Pack(2, self->ob_type, args); | |
| 706 | + Py_DECREF(args); | |
| 707 | + return res; | |
| 708 | +} | |
| 709 | + | |
| 710 | + | |
| 711 | +static PyMethodDef EnvironmentError_methods[] = { | |
| 712 | + {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS}, | |
| 713 | + {NULL} | |
| 714 | +}; | |
| 715 | + | |
| 716 | +ComplexExtendsException(PyExc_StandardError, EnvironmentError, | |
| 717 | + EnvironmentError, EnvironmentError_dealloc, | |
| 718 | + EnvironmentError_methods, EnvironmentError_members, | |
| 719 | + EnvironmentError_str, | |
| 720 | + "Base class for I/O related errors."); | |
| 721 | + | |
| 722 | + | |
| 723 | +/* | |
| 724 | + * IOError extends EnvironmentError | |
| 725 | + */ | |
| 726 | +MiddlingExtendsException(PyExc_EnvironmentError, IOError, | |
| 727 | + EnvironmentError, "I/O operation failed."); | |
| 728 | + | |
| 729 | + | |
| 730 | +/* | |
| 731 | + * OSError extends EnvironmentError | |
| 732 | + */ | |
| 733 | +MiddlingExtendsException(PyExc_EnvironmentError, OSError, | |
| 734 | + EnvironmentError, "OS system call failed."); | |
| 735 | + | |
| 736 | + | |
| 737 | +/* | |
| 738 | + * WindowsError extends OSError | |
| 739 | + */ | |
| 740 | +#ifdef MS_WINDOWS | |
| 741 | +#include "errmap.h" | |
| 742 | + | |
| 743 | +static int | |
| 744 | +WindowsError_clear(PyWindowsErrorObject *self) | |
| 745 | +{ | |
| 746 | + Py_CLEAR(self->myerrno); | |
| 747 | + Py_CLEAR(self->strerror); | |
| 748 | + Py_CLEAR(self->filename); | |
| 749 | + Py_CLEAR(self->winerror); | |
| 750 | + return BaseException_clear((PyBaseExceptionObject *)self); | |
| 751 | +} | |
| 752 | + | |
| 753 | +static void | |
| 754 | +WindowsError_dealloc(PyWindowsErrorObject *self) | |
| 755 | +{ | |
| 756 | + _PyObject_GC_UNTRACK(self); | |
| 757 | + WindowsError_clear(self); | |
| 758 | + self->ob_type->tp_free((PyObject *)self); | |
| 759 | +} | |
| 760 | + | |
| 761 | +static int | |
| 762 | +WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg) | |
| 763 | +{ | |
| 764 | + Py_VISIT(self->myerrno); | |
| 765 | + Py_VISIT(self->strerror); | |
| 766 | + Py_VISIT(self->filename); | |
| 767 | + Py_VISIT(self->winerror); | |
| 768 | + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); | |
| 769 | +} | |
| 770 | + | |
| 771 | +static int | |
| 772 | +WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds) | |
| 773 | +{ | |
| 774 | + PyObject *o_errcode = NULL; | |
| 775 | + long errcode; | |
| 776 | + long posix_errno; | |
| 777 | + | |
| 778 | + if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds) | |
| 779 | + == -1) | |
| 780 | + return -1; | |
| 781 | + | |
| 782 | + if (self->myerrno == NULL) | |
| 783 | + return 0; | |
| 784 | + | |
| 785 | + /* Set errno to the POSIX errno, and winerror to the Win32 | |
| 786 | + error code. */ | |
| 787 | + errcode = PyInt_AsLong(self->myerrno); | |
| 788 | + if (errcode == -1 && PyErr_Occurred()) | |
| 789 | + return -1; | |
| 790 | + posix_errno = winerror_to_errno(errcode); | |
| 791 | + | |
| 792 | + Py_CLEAR(self->winerror); | |
| 793 | + self->winerror = self->myerrno; | |
| 794 | + | |
| 795 | + o_errcode = PyInt_FromLong(posix_errno); | |
| 796 | + if (!o_errcode) | |
| 797 | + return -1; | |
| 798 | + | |
| 799 | + self->myerrno = o_errcode; | |
| 800 | + | |
| 801 | + return 0; | |
| 802 | +} | |
| 803 | + | |
| 804 | + | |
| 805 | +static PyObject * | |
| 806 | +WindowsError_str(PyWindowsErrorObject *self) | |
| 807 | +{ | |
| 808 | + PyObject *rtnval = NULL; | |
| 809 | + | |
| 810 | + if (self->filename) { | |
| 811 | + PyObject *fmt; | |
| 812 | + PyObject *repr; | |
| 813 | + PyObject *tuple; | |
| 814 | + | |
| 815 | + fmt = PyString_FromString("[Error %s] %s: %s"); | |
| 816 | + if (!fmt) | |
| 817 | + return NULL; | |
| 818 | + | |
| 819 | + repr = PyObject_Repr(self->filename); | |
| 820 | + if (!repr) { | |
| 821 | + Py_DECREF(fmt); | |
| 822 | + return NULL; | |
| 823 | + } | |
| 824 | + tuple = PyTuple_New(3); | |
| 825 | + if (!tuple) { | |
| 826 | + Py_DECREF(repr); | |
| 827 | + Py_DECREF(fmt); | |
| 828 | + return NULL; | |
| 829 | + } | |
| 830 | + | |
| 831 | + if (self->winerror) { | |
| 832 | + Py_INCREF(self->winerror); | |
| 833 | + PyTuple_SET_ITEM(tuple, 0, self->winerror); | |
| 834 | + } | |
| 835 | + else { | |
| 836 | + Py_INCREF(Py_None); | |
| 837 | + PyTuple_SET_ITEM(tuple, 0, Py_None); | |
| 838 | + } | |
| 839 | + if (self->strerror) { | |
| 840 | + Py_INCREF(self->strerror); | |
| 841 | + PyTuple_SET_ITEM(tuple, 1, self->strerror); | |
| 842 | + } | |
| 843 | + else { | |
| 844 | + Py_INCREF(Py_None); | |
| 845 | + PyTuple_SET_ITEM(tuple, 1, Py_None); | |
| 846 | + } | |
| 847 | + | |
| 848 | + PyTuple_SET_ITEM(tuple, 2, repr); | |
| 849 | + | |
| 850 | + rtnval = PyString_Format(fmt, tuple); | |
| 851 | + | |
| 852 | + Py_DECREF(fmt); | |
| 853 | + Py_DECREF(tuple); | |
| 854 | + } | |
| 855 | + else if (self->winerror && self->strerror) { | |
| 856 | + PyObject *fmt; | |
| 857 | + PyObject *tuple; | |
| 858 | + | |
| 859 | + fmt = PyString_FromString("[Error %s] %s"); | |
| 860 | + if (!fmt) | |
| 861 | + return NULL; | |
| 862 | + | |
| 863 | + tuple = PyTuple_New(2); | |
| 864 | + if (!tuple) { | |
| 865 | + Py_DECREF(fmt); | |
| 866 | + return NULL; | |
| 867 | + } | |
| 868 | + | |
| 869 | + if (self->winerror) { | |
| 870 | + Py_INCREF(self->winerror); | |
| 871 | + PyTuple_SET_ITEM(tuple, 0, self->winerror); | |
| 872 | + } | |
| 873 | + else { | |
| 874 | + Py_INCREF(Py_None); | |
| 875 | + PyTuple_SET_ITEM(tuple, 0, Py_None); | |
| 876 | + } | |
| 877 | + if (self->strerror) { | |
| 878 | + Py_INCREF(self->strerror); | |
| 879 | + PyTuple_SET_ITEM(tuple, 1, self->strerror); | |
| 880 | + } | |
| 881 | + else { | |
| 882 | + Py_INCREF(Py_None); | |
| 883 | + PyTuple_SET_ITEM(tuple, 1, Py_None); | |
| 884 | + } | |
| 885 | + | |
| 886 | + rtnval = PyString_Format(fmt, tuple); | |
| 887 | + | |
| 888 | + Py_DECREF(fmt); | |
| 889 | + Py_DECREF(tuple); | |
| 890 | + } | |
| 891 | + else | |
| 892 | + rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self); | |
| 893 | + | |
| 894 | + return rtnval; | |
| 895 | +} | |
| 896 | + | |
| 897 | +static PyMemberDef WindowsError_members[] = { | |
| 898 | + {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0, | |
| 899 | + PyDoc_STR("exception message")}, | |
| 900 | + {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0, | |
| 901 | + PyDoc_STR("POSIX exception code")}, | |
| 902 | + {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0, | |
| 903 | + PyDoc_STR("exception strerror")}, | |
| 904 | + {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0, | |
| 905 | + PyDoc_STR("exception filename")}, | |
| 906 | + {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0, | |
| 907 | + PyDoc_STR("Win32 exception code")}, | |
| 908 | + {NULL} /* Sentinel */ | |
| 909 | +}; | |
| 910 | + | |
| 911 | +ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError, | |
| 912 | + WindowsError_dealloc, 0, WindowsError_members, | |
| 913 | + WindowsError_str, "MS-Windows OS system call failed."); | |
| 914 | + | |
| 915 | +#endif /* MS_WINDOWS */ | |
| 916 | + | |
| 917 | + | |
| 918 | +/* | |
| 919 | + * VMSError extends OSError (I think) | |
| 920 | + */ | |
| 921 | +#ifdef __VMS | |
| 922 | +MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError, | |
| 923 | + "OpenVMS OS system call failed."); | |
| 924 | +#endif | |
| 925 | + | |
| 926 | + | |
| 927 | +/* | |
| 928 | + * EOFError extends StandardError | |
| 929 | + */ | |
| 930 | +SimpleExtendsException(PyExc_StandardError, EOFError, | |
| 931 | + "Read beyond end of file."); | |
| 932 | + | |
| 933 | + | |
| 934 | +/* | |
| 935 | + * RuntimeError extends StandardError | |
| 936 | + */ | |
| 937 | +SimpleExtendsException(PyExc_StandardError, RuntimeError, | |
| 938 | + "Unspecified run-time error."); | |
| 939 | + | |
| 940 | + | |
| 941 | +/* | |
| 942 | + * NotImplementedError extends RuntimeError | |
| 943 | + */ | |
| 944 | +SimpleExtendsException(PyExc_RuntimeError, NotImplementedError, | |
| 945 | + "Method or function hasn't been implemented yet."); | |
| 946 | + | |
| 947 | +/* | |
| 948 | + * NameError extends StandardError | |
| 949 | + */ | |
| 950 | +SimpleExtendsException(PyExc_StandardError, NameError, | |
| 951 | + "Name not found globally."); | |
| 952 | + | |
| 953 | +/* | |
| 954 | + * UnboundLocalError extends NameError | |
| 955 | + */ | |
| 956 | +SimpleExtendsException(PyExc_NameError, UnboundLocalError, | |
| 957 | + "Local name referenced but not bound to a value."); | |
| 958 | + | |
| 959 | +/* | |
| 960 | + * AttributeError extends StandardError | |
| 961 | + */ | |
| 962 | +SimpleExtendsException(PyExc_StandardError, AttributeError, | |
| 963 | + "Attribute not found."); | |
| 964 | + | |
| 965 | + | |
| 966 | +/* | |
| 967 | + * SyntaxError extends StandardError | |
| 968 | + */ | |
| 969 | + | |
| 970 | +static int | |
| 971 | +SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) | |
| 972 | +{ | |
| 973 | + PyObject *info = NULL; | |
| 974 | + Py_ssize_t lenargs = PyTuple_GET_SIZE(args); | |
| 975 | + | |
| 976 | + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) | |
| 977 | + return -1; | |
| 978 | + | |
| 979 | + if (lenargs >= 1) { | |
| 980 | + Py_CLEAR(self->msg); | |
| 981 | + self->msg = PyTuple_GET_ITEM(args, 0); | |
| 982 | + Py_INCREF(self->msg); | |
| 983 | + } | |
| 984 | + if (lenargs == 2) { | |
| 985 | + info = PyTuple_GET_ITEM(args, 1); | |
| 986 | + info = PySequence_Tuple(info); | |
| 987 | + if (!info) return -1; | |
| 988 | + | |
| 989 | + if (PyTuple_GET_SIZE(info) != 4) { | |
| 990 | + /* not a very good error message, but it's what Python 2.4 gives */ | |
| 991 | + PyErr_SetString(PyExc_IndexError, "tuple index out of range"); | |
| 992 | + Py_DECREF(info); | |
| 993 | + return -1; | |
| 994 | + } | |
| 995 | + | |
| 996 | + Py_CLEAR(self->filename); | |
| 997 | + self->filename = PyTuple_GET_ITEM(info, 0); | |
| 998 | + Py_INCREF(self->filename); | |
| 999 | + | |
| 1000 | + Py_CLEAR(self->lineno); | |
| 1001 | + self->lineno = PyTuple_GET_ITEM(info, 1); | |
| 1002 | + Py_INCREF(self->lineno); | |
| 1003 | + | |
| 1004 | + Py_CLEAR(self->offset); | |
| 1005 | + self->offset = PyTuple_GET_ITEM(info, 2); | |
| 1006 | + Py_INCREF(self->offset); | |
| 1007 | + | |
| 1008 | + Py_CLEAR(self->text); | |
| 1009 | + self->text = PyTuple_GET_ITEM(info, 3); | |
| 1010 | + Py_INCREF(self->text); | |
| 1011 | + | |
| 1012 | + Py_DECREF(info); | |
| 1013 | + } | |
| 1014 | + return 0; | |
| 1015 | +} | |
| 1016 | + | |
| 1017 | +static int | |
| 1018 | +SyntaxError_clear(PySyntaxErrorObject *self) | |
| 1019 | +{ | |
| 1020 | + Py_CLEAR(self->msg); | |
| 1021 | + Py_CLEAR(self->filename); | |
| 1022 | + Py_CLEAR(self->lineno); | |
| 1023 | + Py_CLEAR(self->offset); | |
| 1024 | + Py_CLEAR(self->text); | |
| 1025 | + Py_CLEAR(self->print_file_and_line); | |
| 1026 | + return BaseException_clear((PyBaseExceptionObject *)self); | |
| 1027 | +} | |
| 1028 | + | |
| 1029 | +static void | |
| 1030 | +SyntaxError_dealloc(PySyntaxErrorObject *self) | |
| 1031 | +{ | |
| 1032 | + _PyObject_GC_UNTRACK(self); | |
| 1033 | + SyntaxError_clear(self); | |
| 1034 | + self->ob_type->tp_free((PyObject *)self); | |
| 1035 | +} | |
| 1036 | + | |
| 1037 | +static int | |
| 1038 | +SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg) | |
| 1039 | +{ | |
| 1040 | + Py_VISIT(self->msg); | |
| 1041 | + Py_VISIT(self->filename); | |
| 1042 | + Py_VISIT(self->lineno); | |
| 1043 | + Py_VISIT(self->offset); | |
| 1044 | + Py_VISIT(self->text); | |
| 1045 | + Py_VISIT(self->print_file_and_line); | |
| 1046 | + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); | |
| 1047 | +} | |
| 1048 | + | |
| 1049 | +/* This is called "my_basename" instead of just "basename" to avoid name | |
| 1050 | + conflicts with glibc; basename is already prototyped if _GNU_SOURCE is | |
| 1051 | + defined, and Python does define that. */ | |
| 1052 | +static char * | |
| 1053 | +my_basename(char *name) | |
| 1054 | +{ | |
| 1055 | + char *cp = name; | |
| 1056 | + char *result = name; | |
| 1057 | + | |
| 1058 | + if (name == NULL) | |
| 1059 | + return "???"; | |
| 1060 | + while (*cp != '\0') { | |
| 1061 | + if (*cp == SEP) | |
| 1062 | + result = cp + 1; | |
| 1063 | + ++cp; | |
| 1064 | + } | |
| 1065 | + return result; | |
| 1066 | +} | |
| 1067 | + | |
| 1068 | + | |
| 1069 | +static PyObject * | |
| 1070 | +SyntaxError_str(PySyntaxErrorObject *self) | |
| 1071 | +{ | |
| 1072 | + PyObject *str; | |
| 1073 | + PyObject *result; | |
| 1074 | + int have_filename = 0; | |
| 1075 | + int have_lineno = 0; | |
| 1076 | + char *buffer = NULL; | |
| 1077 | + Py_ssize_t bufsize; | |
| 1078 | + | |
| 1079 | + if (self->msg) | |
| 1080 | + str = PyObject_Str(self->msg); | |
| 1081 | + else | |
| 1082 | + str = PyObject_Str(Py_None); | |
| 1083 | + if (!str) return NULL; | |
| 1084 | + /* Don't fiddle with non-string return (shouldn't happen anyway) */ | |
| 1085 | + if (!PyString_Check(str)) return str; | |
| 1086 | + | |
| 1087 | + /* XXX -- do all the additional formatting with filename and | |
| 1088 | + lineno here */ | |
| 1089 | + | |
| 1090 | + have_filename = (self->filename != NULL) && | |
| 1091 | + PyString_Check(self->filename); | |
| 1092 | + have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno); | |
| 1093 | + | |
| 1094 | + if (!have_filename && !have_lineno) | |
| 1095 | + return str; | |
| 1096 | + | |
| 1097 | + bufsize = PyString_GET_SIZE(str) + 64; | |
| 1098 | + if (have_filename) | |
| 1099 | + bufsize += PyString_GET_SIZE(self->filename); | |
| 1100 | + | |
| 1101 | + buffer = PyMem_MALLOC(bufsize); | |
| 1102 | + if (buffer == NULL) | |
| 1103 | + return str; | |
| 1104 | + | |
| 1105 | + if (have_filename && have_lineno) | |
| 1106 | + PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)", | |
| 1107 | + PyString_AS_STRING(str), | |
| 1108 | + my_basename(PyString_AS_STRING(self->filename)), | |
| 1109 | + PyInt_AsLong(self->lineno)); | |
| 1110 | + else if (have_filename) | |
| 1111 | + PyOS_snprintf(buffer, bufsize, "%s (%s)", | |
| 1112 | + PyString_AS_STRING(str), | |
| 1113 | + my_basename(PyString_AS_STRING(self->filename))); | |
| 1114 | + else /* only have_lineno */ | |
| 1115 | + PyOS_snprintf(buffer, bufsize, "%s (line %ld)", | |
| 1116 | + PyString_AS_STRING(str), | |
| 1117 | + PyInt_AsLong(self->lineno)); | |
| 1118 | + | |
| 1119 | + result = PyString_FromString(buffer); | |
| 1120 | + PyMem_FREE(buffer); | |
| 1121 | + | |
| 1122 | + if (result == NULL) | |
| 1123 | + result = str; | |
| 1124 | + else | |
| 1125 | + Py_DECREF(str); | |
| 1126 | + return result; | |
| 1127 | +} | |
| 1128 | + | |
| 1129 | +static PyMemberDef SyntaxError_members[] = { | |
| 1130 | + {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0, | |
| 1131 | + PyDoc_STR("exception message")}, | |
| 1132 | + {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0, | |
| 1133 | + PyDoc_STR("exception msg")}, | |
| 1134 | + {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0, | |
| 1135 | + PyDoc_STR("exception filename")}, | |
| 1136 | + {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0, | |
| 1137 | + PyDoc_STR("exception lineno")}, | |
| 1138 | + {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0, | |
| 1139 | + PyDoc_STR("exception offset")}, | |
| 1140 | + {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0, | |
| 1141 | + PyDoc_STR("exception text")}, | |
| 1142 | + {"print_file_and_line", T_OBJECT, | |
| 1143 | + offsetof(PySyntaxErrorObject, print_file_and_line), 0, | |
| 1144 | + PyDoc_STR("exception print_file_and_line")}, | |
| 1145 | + {NULL} /* Sentinel */ | |
| 1146 | +}; | |
| 1147 | + | |
| 1148 | +ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError, | |
| 1149 | + SyntaxError_dealloc, 0, SyntaxError_members, | |
| 1150 | + SyntaxError_str, "Invalid syntax."); | |
| 1151 | + | |
| 1152 | + | |
| 1153 | +/* | |
| 1154 | + * IndentationError extends SyntaxError | |
| 1155 | + */ | |
| 1156 | +MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError, | |
| 1157 | + "Improper indentation."); | |
| 1158 | + | |
| 1159 | + | |
| 1160 | +/* | |
| 1161 | + * TabError extends IndentationError | |
| 1162 | + */ | |
| 1163 | +MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError, | |
| 1164 | + "Improper mixture of spaces and tabs."); | |
| 1165 | + | |
| 1166 | + | |
| 1167 | +/* | |
| 1168 | + * LookupError extends StandardError | |
| 1169 | + */ | |
| 1170 | +SimpleExtendsException(PyExc_StandardError, LookupError, | |
| 1171 | + "Base class for lookup errors."); | |
| 1172 | + | |
| 1173 | + | |
| 1174 | +/* | |
| 1175 | + * IndexError extends LookupError | |
| 1176 | + */ | |
| 1177 | +SimpleExtendsException(PyExc_LookupError, IndexError, | |
| 1178 | + "Sequence index out of range."); | |
| 1179 | + | |
| 1180 | + | |
| 1181 | +/* | |
| 1182 | + * KeyError extends LookupError | |
| 1183 | + */ | |
| 1184 | +static PyObject * | |
| 1185 | +KeyError_str(PyBaseExceptionObject *self) | |
| 1186 | +{ | |
| 1187 | + /* If args is a tuple of exactly one item, apply repr to args[0]. | |
| 1188 | + This is done so that e.g. the exception raised by {}[''] prints | |
| 1189 | + KeyError: '' | |
| 1190 | + rather than the confusing | |
| 1191 | + KeyError | |
| 1192 | + alone. The downside is that if KeyError is raised with an explanatory | |
| 1193 | + string, that string will be displayed in quotes. Too bad. | |
| 1194 | + If args is anything else, use the default BaseException__str__(). | |
| 1195 | + */ | |
| 1196 | + if (PyTuple_GET_SIZE(self->args) == 1) { | |
| 1197 | + return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0)); | |
| 1198 | + } | |
| 1199 | + return BaseException_str(self); | |
| 1200 | +} | |
| 1201 | + | |
| 1202 | +ComplexExtendsException(PyExc_LookupError, KeyError, BaseException, | |
| 1203 | + 0, 0, 0, KeyError_str, "Mapping key not found."); | |
| 1204 | + | |
| 1205 | + | |
| 1206 | +/* | |
| 1207 | + * ValueError extends StandardError | |
| 1208 | + */ | |
| 1209 | +SimpleExtendsException(PyExc_StandardError, ValueError, | |
| 1210 | + "Inappropriate argument value (of correct type)."); | |
| 1211 | + | |
| 1212 | +/* | |
| 1213 | + * UnicodeError extends ValueError | |
| 1214 | + */ | |
| 1215 | + | |
| 1216 | +SimpleExtendsException(PyExc_ValueError, UnicodeError, | |
| 1217 | + "Unicode related error."); | |
| 1218 | + | |
| 1219 | +#ifdef Py_USING_UNICODE | |
| 1220 | +static int | |
| 1221 | +get_int(PyObject *attr, Py_ssize_t *value, const char *name) | |
| 1222 | +{ | |
| 1223 | + if (!attr) { | |
| 1224 | + PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name); | |
| 1225 | + return -1; | |
| 1226 | + } | |
| 1227 | + | |
| 1228 | + if (PyInt_Check(attr)) { | |
| 1229 | + *value = PyInt_AS_LONG(attr); | |
| 1230 | + } else if (PyLong_Check(attr)) { | |
| 1231 | + *value = _PyLong_AsSsize_t(attr); | |
| 1232 | + if (*value == -1 && PyErr_Occurred()) | |
| 1233 | + return -1; | |
| 1234 | + } else { | |
| 1235 | + PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name); | |
| 1236 | + return -1; | |
| 1237 | + } | |
| 1238 | + return 0; | |
| 1239 | +} | |
| 1240 | + | |
| 1241 | +static int | |
| 1242 | +set_ssize_t(PyObject **attr, Py_ssize_t value) | |
| 1243 | +{ | |
| 1244 | + PyObject *obj = PyInt_FromSsize_t(value); | |
| 1245 | + if (!obj) | |
| 1246 | + return -1; | |
| 1247 | + Py_CLEAR(*attr); | |
| 1248 | + *attr = obj; | |
| 1249 | + return 0; | |
| 1250 | +} | |
| 1251 | + | |
| 1252 | +static PyObject * | |
| 1253 | +get_string(PyObject *attr, const char *name) | |
| 1254 | +{ | |
| 1255 | + if (!attr) { | |
| 1256 | + PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name); | |
| 1257 | + return NULL; | |
| 1258 | + } | |
| 1259 | + | |
| 1260 | + if (!PyString_Check(attr)) { | |
| 1261 | + PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name); | |
| 1262 | + return NULL; | |
| 1263 | + } | |
| 1264 | + Py_INCREF(attr); | |
| 1265 | + return attr; | |
| 1266 | +} | |
| 1267 | + | |
| 1268 | + | |
| 1269 | +static int | |
| 1270 | +set_string(PyObject **attr, const char *value) | |
| 1271 | +{ | |
| 1272 | + PyObject *obj = PyString_FromString(value); | |
| 1273 | + if (!obj) | |
| 1274 | + return -1; | |
| 1275 | + Py_CLEAR(*attr); | |
| 1276 | + *attr = obj; | |
| 1277 | + return 0; | |
| 1278 | +} | |
| 1279 | + | |
| 1280 | + | |
| 1281 | +static PyObject * | |
| 1282 | +get_unicode(PyObject *attr, const char *name) | |
| 1283 | +{ | |
| 1284 | + if (!attr) { | |
| 1285 | + PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name); | |
| 1286 | + return NULL; | |
| 1287 | + } | |
| 1288 | + | |
| 1289 | + if (!PyUnicode_Check(attr)) { | |
| 1290 | + PyErr_Format(PyExc_TypeError, | |
| 1291 | + "%.200s attribute must be unicode", name); | |
| 1292 | + return NULL; | |
| 1293 | + } | |
| 1294 | + Py_INCREF(attr); | |
| 1295 | + return attr; | |
| 1296 | +} | |
| 1297 | + | |
| 1298 | +PyObject * | |
| 1299 | +PyUnicodeEncodeError_GetEncoding(PyObject *exc) | |
| 1300 | +{ | |
| 1301 | + return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding"); | |
| 1302 | +} | |
| 1303 | + | |
| 1304 | +PyObject * | |
| 1305 | +PyUnicodeDecodeError_GetEncoding(PyObject *exc) | |
| 1306 | +{ | |
| 1307 | + return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding"); | |
| 1308 | +} | |
| 1309 | + | |
| 1310 | +PyObject * | |
| 1311 | +PyUnicodeEncodeError_GetObject(PyObject *exc) | |
| 1312 | +{ | |
| 1313 | + return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object"); | |
| 1314 | +} | |
| 1315 | + | |
| 1316 | +PyObject * | |
| 1317 | +PyUnicodeDecodeError_GetObject(PyObject *exc) | |
| 1318 | +{ | |
| 1319 | + return get_string(((PyUnicodeErrorObject *)exc)->object, "object"); | |
| 1320 | +} | |
| 1321 | + | |
| 1322 | +PyObject * | |
| 1323 | +PyUnicodeTranslateError_GetObject(PyObject *exc) | |
| 1324 | +{ | |
| 1325 | + return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object"); | |
| 1326 | +} | |
| 1327 | + | |
| 1328 | +int | |
| 1329 | +PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start) | |
| 1330 | +{ | |
| 1331 | + if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) { | |
| 1332 | + Py_ssize_t size; | |
| 1333 | + PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object, | |
| 1334 | + "object"); | |
| 1335 | + if (!obj) return -1; | |
| 1336 | + size = PyUnicode_GET_SIZE(obj); | |
| 1337 | + if (*start<0) | |
| 1338 | + *start = 0; /*XXX check for values <0*/ | |
| 1339 | + if (*start>=size) | |
| 1340 | + *start = size-1; | |
| 1341 | + Py_DECREF(obj); | |
| 1342 | + return 0; | |
| 1343 | + } | |
| 1344 | + return -1; | |
| 1345 | +} | |
| 1346 | + | |
| 1347 | + | |
| 1348 | +int | |
| 1349 | +PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start) | |
| 1350 | +{ | |
| 1351 | + if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) { | |
| 1352 | + Py_ssize_t size; | |
| 1353 | + PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, | |
| 1354 | + "object"); | |
| 1355 | + if (!obj) return -1; | |
| 1356 | + size = PyString_GET_SIZE(obj); | |
| 1357 | + if (*start<0) | |
| 1358 | + *start = 0; | |
| 1359 | + if (*start>=size) | |
| 1360 | + *start = size-1; | |
| 1361 | + Py_DECREF(obj); | |
| 1362 | + return 0; | |
| 1363 | + } | |
| 1364 | + return -1; | |
| 1365 | +} | |
| 1366 | + | |
| 1367 | + | |
| 1368 | +int | |
| 1369 | +PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start) | |
| 1370 | +{ | |
| 1371 | + return PyUnicodeEncodeError_GetStart(exc, start); | |
| 1372 | +} | |
| 1373 | + | |
| 1374 | + | |
| 1375 | +int | |
| 1376 | +PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start) | |
| 1377 | +{ | |
| 1378 | + return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start); | |
| 1379 | +} | |
| 1380 | + | |
| 1381 | + | |
| 1382 | +int | |
| 1383 | +PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start) | |
| 1384 | +{ | |
| 1385 | + return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start); | |
| 1386 | +} | |
| 1387 | + | |
| 1388 | + | |
| 1389 | +int | |
| 1390 | +PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start) | |
| 1391 | +{ | |
| 1392 | + return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start); | |
| 1393 | +} | |
| 1394 | + | |
| 1395 | + | |
| 1396 | +int | |
| 1397 | +PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end) | |
| 1398 | +{ | |
| 1399 | + if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) { | |
| 1400 | + Py_ssize_t size; | |
| 1401 | + PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object, | |
| 1402 | + "object"); | |
| 1403 | + if (!obj) return -1; | |
| 1404 | + size = PyUnicode_GET_SIZE(obj); | |
| 1405 | + if (*end<1) | |
| 1406 | + *end = 1; | |
| 1407 | + if (*end>size) | |
| 1408 | + *end = size; | |
| 1409 | + Py_DECREF(obj); | |
| 1410 | + return 0; | |
| 1411 | + } | |
| 1412 | + return -1; | |
| 1413 | +} | |
| 1414 | + | |
| 1415 | + | |
| 1416 | +int | |
| 1417 | +PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end) | |
| 1418 | +{ | |
| 1419 | + if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) { | |
| 1420 | + Py_ssize_t size; | |
| 1421 | + PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, | |
| 1422 | + "object"); | |
| 1423 | + if (!obj) return -1; | |
| 1424 | + size = PyString_GET_SIZE(obj); | |
| 1425 | + if (*end<1) | |
| 1426 | + *end = 1; | |
| 1427 | + if (*end>size) | |
| 1428 | + *end = size; | |
| 1429 | + Py_DECREF(obj); | |
| 1430 | + return 0; | |
| 1431 | + } | |
| 1432 | + return -1; | |
| 1433 | +} | |
| 1434 | + | |
| 1435 | + | |
| 1436 | +int | |
| 1437 | +PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start) | |
| 1438 | +{ | |
| 1439 | + return PyUnicodeEncodeError_GetEnd(exc, start); | |
| 1440 | +} | |
| 1441 | + | |
| 1442 | + | |
| 1443 | +int | |
| 1444 | +PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end) | |
| 1445 | +{ | |
| 1446 | + return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end); | |
| 1447 | +} | |
| 1448 | + | |
| 1449 | + | |
| 1450 | +int | |
| 1451 | +PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end) | |
| 1452 | +{ | |
| 1453 | + return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end); | |
| 1454 | +} | |
| 1455 | + | |
| 1456 | + | |
| 1457 | +int | |
| 1458 | +PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end) | |
| 1459 | +{ | |
| 1460 | + return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end); | |
| 1461 | +} | |
| 1462 | + | |
| 1463 | +PyObject * | |
| 1464 | +PyUnicodeEncodeError_GetReason(PyObject *exc) | |
| 1465 | +{ | |
| 1466 | + return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason"); | |
| 1467 | +} | |
| 1468 | + | |
| 1469 | + | |
| 1470 | +PyObject * | |
| 1471 | +PyUnicodeDecodeError_GetReason(PyObject *exc) | |
| 1472 | +{ | |
| 1473 | + return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason"); | |
| 1474 | +} | |
| 1475 | + | |
| 1476 | + | |
| 1477 | +PyObject * | |
| 1478 | +PyUnicodeTranslateError_GetReason(PyObject *exc) | |
| 1479 | +{ | |
| 1480 | + return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason"); | |
| 1481 | +} | |
| 1482 | + | |
| 1483 | + | |
| 1484 | +int | |
| 1485 | +PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason) | |
| 1486 | +{ | |
| 1487 | + return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason); | |
| 1488 | +} | |
| 1489 | + | |
| 1490 | + | |
| 1491 | +int | |
| 1492 | +PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason) | |
| 1493 | +{ | |
| 1494 | + return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason); | |
| 1495 | +} | |
| 1496 | + | |
| 1497 | + | |
| 1498 | +int | |
| 1499 | +PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason) | |
| 1500 | +{ | |
| 1501 | + return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason); | |
| 1502 | +} | |
| 1503 | + | |
| 1504 | + | |
| 1505 | +static int | |
| 1506 | +UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds, | |
| 1507 | + PyTypeObject *objecttype) | |
| 1508 | +{ | |
| 1509 | + Py_CLEAR(self->encoding); | |
| 1510 | + Py_CLEAR(self->object); | |
| 1511 | + Py_CLEAR(self->start); | |
| 1512 | + Py_CLEAR(self->end); | |
| 1513 | + Py_CLEAR(self->reason); | |
| 1514 | + | |
| 1515 | + if (!PyArg_ParseTuple(args, "O!O!O!O!O!", | |
| 1516 | + &PyString_Type, &self->encoding, | |
| 1517 | + objecttype, &self->object, | |
| 1518 | + &PyInt_Type, &self->start, | |
| 1519 | + &PyInt_Type, &self->end, | |
| 1520 | + &PyString_Type, &self->reason)) { | |
| 1521 | + self->encoding = self->object = self->start = self->end = | |
| 1522 | + self->reason = NULL; | |
| 1523 | + return -1; | |
| 1524 | + } | |
| 1525 | + | |
| 1526 | + Py_INCREF(self->encoding); | |
| 1527 | + Py_INCREF(self->object); | |
| 1528 | + Py_INCREF(self->start); | |
| 1529 | + Py_INCREF(self->end); | |
| 1530 | + Py_INCREF(self->reason); | |
| 1531 | + | |
| 1532 | + return 0; | |
| 1533 | +} | |
| 1534 | + | |
| 1535 | +static int | |
| 1536 | +UnicodeError_clear(PyUnicodeErrorObject *self) | |
| 1537 | +{ | |
| 1538 | + Py_CLEAR(self->encoding); | |
| 1539 | + Py_CLEAR(self->object); | |
| 1540 | + Py_CLEAR(self->start); | |
| 1541 | + Py_CLEAR(self->end); | |
| 1542 | + Py_CLEAR(self->reason); | |
| 1543 | + return BaseException_clear((PyBaseExceptionObject *)self); | |
| 1544 | +} | |
| 1545 | + | |
| 1546 | +static void | |
| 1547 | +UnicodeError_dealloc(PyUnicodeErrorObject *self) | |
| 1548 | +{ | |
| 1549 | + _PyObject_GC_UNTRACK(self); | |
| 1550 | + UnicodeError_clear(self); | |
| 1551 | + self->ob_type->tp_free((PyObject *)self); | |
| 1552 | +} | |
| 1553 | + | |
| 1554 | +static int | |
| 1555 | +UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg) | |
| 1556 | +{ | |
| 1557 | + Py_VISIT(self->encoding); | |
| 1558 | + Py_VISIT(self->object); | |
| 1559 | + Py_VISIT(self->start); | |
| 1560 | + Py_VISIT(self->end); | |
| 1561 | + Py_VISIT(self->reason); | |
| 1562 | + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); | |
| 1563 | +} | |
| 1564 | + | |
| 1565 | +static PyMemberDef UnicodeError_members[] = { | |
| 1566 | + {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0, | |
| 1567 | + PyDoc_STR("exception message")}, | |
| 1568 | + {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0, | |
| 1569 | + PyDoc_STR("exception encoding")}, | |
| 1570 | + {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0, | |
| 1571 | + PyDoc_STR("exception object")}, | |
| 1572 | + {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0, | |
| 1573 | + PyDoc_STR("exception start")}, | |
| 1574 | + {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0, | |
| 1575 | + PyDoc_STR("exception end")}, | |
| 1576 | + {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0, | |
| 1577 | + PyDoc_STR("exception reason")}, | |
| 1578 | + {NULL} /* Sentinel */ | |
| 1579 | +}; | |
| 1580 | + | |
| 1581 | + | |
| 1582 | +/* | |
| 1583 | + * UnicodeEncodeError extends UnicodeError | |
| 1584 | + */ | |
| 1585 | + | |
| 1586 | +static int | |
| 1587 | +UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds) | |
| 1588 | +{ | |
| 1589 | + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) | |
| 1590 | + return -1; | |
| 1591 | + return UnicodeError_init((PyUnicodeErrorObject *)self, args, | |
| 1592 | + kwds, &PyUnicode_Type); | |
| 1593 | +} | |
| 1594 | + | |
| 1595 | +static PyObject * | |
| 1596 | +UnicodeEncodeError_str(PyObject *self) | |
| 1597 | +{ | |
| 1598 | + Py_ssize_t start; | |
| 1599 | + Py_ssize_t end; | |
| 1600 | + | |
| 1601 | + if (PyUnicodeEncodeError_GetStart(self, &start)) | |
| 1602 | + return NULL; | |
| 1603 | + | |
| 1604 | + if (PyUnicodeEncodeError_GetEnd(self, &end)) | |
| 1605 | + return NULL; | |
| 1606 | + | |
| 1607 | + if (end==start+1) { | |
| 1608 | + int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start]; | |
| 1609 | + char badchar_str[20]; | |
| 1610 | + if (badchar <= 0xff) | |
| 1611 | + PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar); | |
| 1612 | + else if (badchar <= 0xffff) | |
| 1613 | + PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar); | |
| 1614 | + else | |
| 1615 | + PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar); | |
| 1616 | + return PyString_FromFormat( | |
| 1617 | + "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s", | |
| 1618 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding), | |
| 1619 | + badchar_str, | |
| 1620 | + start, | |
| 1621 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason) | |
| 1622 | + ); | |
| 1623 | + } | |
| 1624 | + return PyString_FromFormat( | |
| 1625 | + "'%.400s' codec can't encode characters in position %zd-%zd: %.400s", | |
| 1626 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding), | |
| 1627 | + start, | |
| 1628 | + (end-1), | |
| 1629 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason) | |
| 1630 | + ); | |
| 1631 | +} | |
| 1632 | + | |
| 1633 | +static PyTypeObject _PyExc_UnicodeEncodeError = { | |
| 1634 | + PyObject_HEAD_INIT(NULL) | |
| 1635 | + 0, | |
| 1636 | + EXC_MODULE_NAME "UnicodeEncodeError", | |
| 1637 | + sizeof(PyUnicodeErrorObject), 0, | |
| 1638 | + (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 1639 | + (reprfunc)UnicodeEncodeError_str, 0, 0, 0, | |
| 1640 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, | |
| 1641 | + PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse, | |
| 1642 | + (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members, | |
| 1643 | + 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict), | |
| 1644 | + (initproc)UnicodeEncodeError_init, 0, BaseException_new, | |
| 1645 | +}; | |
| 1646 | +PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError; | |
| 1647 | + | |
| 1648 | +PyObject * | |
| 1649 | +PyUnicodeEncodeError_Create( | |
| 1650 | + const char *encoding, const Py_UNICODE *object, Py_ssize_t length, | |
| 1651 | + Py_ssize_t start, Py_ssize_t end, const char *reason) | |
| 1652 | +{ | |
| 1653 | + return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns", | |
| 1654 | + encoding, object, length, start, end, reason); | |
| 1655 | +} | |
| 1656 | + | |
| 1657 | + | |
| 1658 | +/* | |
| 1659 | + * UnicodeDecodeError extends UnicodeError | |
| 1660 | + */ | |
| 1661 | + | |
| 1662 | +static int | |
| 1663 | +UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) | |
| 1664 | +{ | |
| 1665 | + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) | |
| 1666 | + return -1; | |
| 1667 | + return UnicodeError_init((PyUnicodeErrorObject *)self, args, | |
| 1668 | + kwds, &PyString_Type); | |
| 1669 | +} | |
| 1670 | + | |
| 1671 | +static PyObject * | |
| 1672 | +UnicodeDecodeError_str(PyObject *self) | |
| 1673 | +{ | |
| 1674 | + Py_ssize_t start = 0; | |
| 1675 | + Py_ssize_t end = 0; | |
| 1676 | + | |
| 1677 | + if (PyUnicodeDecodeError_GetStart(self, &start)) | |
| 1678 | + return NULL; | |
| 1679 | + | |
| 1680 | + if (PyUnicodeDecodeError_GetEnd(self, &end)) | |
| 1681 | + return NULL; | |
| 1682 | + | |
| 1683 | + if (end==start+1) { | |
| 1684 | + /* FromFormat does not support %02x, so format that separately */ | |
| 1685 | + char byte[4]; | |
| 1686 | + PyOS_snprintf(byte, sizeof(byte), "%02x", | |
| 1687 | + ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff); | |
| 1688 | + return PyString_FromFormat( | |
| 1689 | + "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s", | |
| 1690 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding), | |
| 1691 | + byte, | |
| 1692 | + start, | |
| 1693 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason) | |
| 1694 | + ); | |
| 1695 | + } | |
| 1696 | + return PyString_FromFormat( | |
| 1697 | + "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s", | |
| 1698 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding), | |
| 1699 | + start, | |
| 1700 | + (end-1), | |
| 1701 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason) | |
| 1702 | + ); | |
| 1703 | +} | |
| 1704 | + | |
| 1705 | +static PyTypeObject _PyExc_UnicodeDecodeError = { | |
| 1706 | + PyObject_HEAD_INIT(NULL) | |
| 1707 | + 0, | |
| 1708 | + EXC_MODULE_NAME "UnicodeDecodeError", | |
| 1709 | + sizeof(PyUnicodeErrorObject), 0, | |
| 1710 | + (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 1711 | + (reprfunc)UnicodeDecodeError_str, 0, 0, 0, | |
| 1712 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, | |
| 1713 | + PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse, | |
| 1714 | + (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members, | |
| 1715 | + 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict), | |
| 1716 | + (initproc)UnicodeDecodeError_init, 0, BaseException_new, | |
| 1717 | +}; | |
| 1718 | +PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError; | |
| 1719 | + | |
| 1720 | +PyObject * | |
| 1721 | +PyUnicodeDecodeError_Create( | |
| 1722 | + const char *encoding, const char *object, Py_ssize_t length, | |
| 1723 | + Py_ssize_t start, Py_ssize_t end, const char *reason) | |
| 1724 | +{ | |
| 1725 | + assert(length < INT_MAX); | |
| 1726 | + assert(start < INT_MAX); | |
| 1727 | + assert(end < INT_MAX); | |
| 1728 | + return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns", | |
| 1729 | + encoding, object, length, start, end, reason); | |
| 1730 | +} | |
| 1731 | + | |
| 1732 | + | |
| 1733 | +/* | |
| 1734 | + * UnicodeTranslateError extends UnicodeError | |
| 1735 | + */ | |
| 1736 | + | |
| 1737 | +static int | |
| 1738 | +UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args, | |
| 1739 | + PyObject *kwds) | |
| 1740 | +{ | |
| 1741 | + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) | |
| 1742 | + return -1; | |
| 1743 | + | |
| 1744 | + Py_CLEAR(self->object); | |
| 1745 | + Py_CLEAR(self->start); | |
| 1746 | + Py_CLEAR(self->end); | |
| 1747 | + Py_CLEAR(self->reason); | |
| 1748 | + | |
| 1749 | + if (!PyArg_ParseTuple(args, "O!O!O!O!", | |
| 1750 | + &PyUnicode_Type, &self->object, | |
| 1751 | + &PyInt_Type, &self->start, | |
| 1752 | + &PyInt_Type, &self->end, | |
| 1753 | + &PyString_Type, &self->reason)) { | |
| 1754 | + self->object = self->start = self->end = self->reason = NULL; | |
| 1755 | + return -1; | |
| 1756 | + } | |
| 1757 | + | |
| 1758 | + Py_INCREF(self->object); | |
| 1759 | + Py_INCREF(self->start); | |
| 1760 | + Py_INCREF(self->end); | |
| 1761 | + Py_INCREF(self->reason); | |
| 1762 | + | |
| 1763 | + return 0; | |
| 1764 | +} | |
| 1765 | + | |
| 1766 | + | |
| 1767 | +static PyObject * | |
| 1768 | +UnicodeTranslateError_str(PyObject *self) | |
| 1769 | +{ | |
| 1770 | + Py_ssize_t start; | |
| 1771 | + Py_ssize_t end; | |
| 1772 | + | |
| 1773 | + if (PyUnicodeTranslateError_GetStart(self, &start)) | |
| 1774 | + return NULL; | |
| 1775 | + | |
| 1776 | + if (PyUnicodeTranslateError_GetEnd(self, &end)) | |
| 1777 | + return NULL; | |
| 1778 | + | |
| 1779 | + if (end==start+1) { | |
| 1780 | + int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start]; | |
| 1781 | + char badchar_str[20]; | |
| 1782 | + if (badchar <= 0xff) | |
| 1783 | + PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar); | |
| 1784 | + else if (badchar <= 0xffff) | |
| 1785 | + PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar); | |
| 1786 | + else | |
| 1787 | + PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar); | |
| 1788 | + return PyString_FromFormat( | |
| 1789 | + "can't translate character u'\\%s' in position %zd: %.400s", | |
| 1790 | + badchar_str, | |
| 1791 | + start, | |
| 1792 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason) | |
| 1793 | + ); | |
| 1794 | + } | |
| 1795 | + return PyString_FromFormat( | |
| 1796 | + "can't translate characters in position %zd-%zd: %.400s", | |
| 1797 | + start, | |
| 1798 | + (end-1), | |
| 1799 | + PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason) | |
| 1800 | + ); | |
| 1801 | +} | |
| 1802 | + | |
| 1803 | +static PyTypeObject _PyExc_UnicodeTranslateError = { | |
| 1804 | + PyObject_HEAD_INIT(NULL) | |
| 1805 | + 0, | |
| 1806 | + EXC_MODULE_NAME "UnicodeTranslateError", | |
| 1807 | + sizeof(PyUnicodeErrorObject), 0, | |
| 1808 | + (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 1809 | + (reprfunc)UnicodeTranslateError_str, 0, 0, 0, | |
| 1810 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, | |
| 1811 | + PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse, | |
| 1812 | + (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members, | |
| 1813 | + 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict), | |
| 1814 | + (initproc)UnicodeTranslateError_init, 0, BaseException_new, | |
| 1815 | +}; | |
| 1816 | +PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError; | |
| 1817 | + | |
| 1818 | +PyObject * | |
| 1819 | +PyUnicodeTranslateError_Create( | |
| 1820 | + const Py_UNICODE *object, Py_ssize_t length, | |
| 1821 | + Py_ssize_t start, Py_ssize_t end, const char *reason) | |
| 1822 | +{ | |
| 1823 | + return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns", | |
| 1824 | + object, length, start, end, reason); | |
| 1825 | +} | |
| 1826 | +#endif | |
| 1827 | + | |
| 1828 | + | |
| 1829 | +/* | |
| 1830 | + * AssertionError extends StandardError | |
| 1831 | + */ | |
| 1832 | +SimpleExtendsException(PyExc_StandardError, AssertionError, | |
| 1833 | + "Assertion failed."); | |
| 1834 | + | |
| 1835 | + | |
| 1836 | +/* | |
| 1837 | + * ArithmeticError extends StandardError | |
| 1838 | + */ | |
| 1839 | +SimpleExtendsException(PyExc_StandardError, ArithmeticError, | |
| 1840 | + "Base class for arithmetic errors."); | |
| 1841 | + | |
| 1842 | + | |
| 1843 | +/* | |
| 1844 | + * FloatingPointError extends ArithmeticError | |
| 1845 | + */ | |
| 1846 | +SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError, | |
| 1847 | + "Floating point operation failed."); | |
| 1848 | + | |
| 1849 | + | |
| 1850 | +/* | |
| 1851 | + * OverflowError extends ArithmeticError | |
| 1852 | + */ | |
| 1853 | +SimpleExtendsException(PyExc_ArithmeticError, OverflowError, | |
| 1854 | + "Result too large to be represented."); | |
| 1855 | + | |
| 1856 | + | |
| 1857 | +/* | |
| 1858 | + * ZeroDivisionError extends ArithmeticError | |
| 1859 | + */ | |
| 1860 | +SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError, | |
| 1861 | + "Second argument to a division or modulo operation was zero."); | |
| 1862 | + | |
| 1863 | + | |
| 1864 | +/* | |
| 1865 | + * SystemError extends StandardError | |
| 1866 | + */ | |
| 1867 | +SimpleExtendsException(PyExc_StandardError, SystemError, | |
| 1868 | + "Internal error in the Python interpreter.\n" | |
| 1869 | + "\n" | |
| 1870 | + "Please report this to the Python maintainer, along with the traceback,\n" | |
| 1871 | + "the Python version, and the hardware/OS platform and version."); | |
| 1872 | + | |
| 1873 | + | |
| 1874 | +/* | |
| 1875 | + * ReferenceError extends StandardError | |
| 1876 | + */ | |
| 1877 | +SimpleExtendsException(PyExc_StandardError, ReferenceError, | |
| 1878 | + "Weak ref proxy used after referent went away."); | |
| 1879 | + | |
| 1880 | + | |
| 1881 | +/* | |
| 1882 | + * MemoryError extends StandardError | |
| 1883 | + */ | |
| 1884 | +SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory."); | |
| 1885 | + | |
| 1886 | + | |
| 1887 | +/* Warning category docstrings */ | |
| 1888 | + | |
| 1889 | +/* | |
| 1890 | + * Warning extends Exception | |
| 1891 | + */ | |
| 1892 | +SimpleExtendsException(PyExc_Exception, Warning, | |
| 1893 | + "Base class for warning categories."); | |
| 1894 | + | |
| 1895 | + | |
| 1896 | +/* | |
| 1897 | + * UserWarning extends Warning | |
| 1898 | + */ | |
| 1899 | +SimpleExtendsException(PyExc_Warning, UserWarning, | |
| 1900 | + "Base class for warnings generated by user code."); | |
| 1901 | + | |
| 1902 | + | |
| 1903 | +/* | |
| 1904 | + * DeprecationWarning extends Warning | |
| 1905 | + */ | |
| 1906 | +SimpleExtendsException(PyExc_Warning, DeprecationWarning, | |
| 1907 | + "Base class for warnings about deprecated features."); | |
| 1908 | + | |
| 1909 | + | |
| 1910 | +/* | |
| 1911 | + * PendingDeprecationWarning extends Warning | |
| 1912 | + */ | |
| 1913 | +SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning, | |
| 1914 | + "Base class for warnings about features which will be deprecated\n" | |
| 1915 | + "in the future."); | |
| 1916 | + | |
| 1917 | + | |
| 1918 | +/* | |
| 1919 | + * SyntaxWarning extends Warning | |
| 1920 | + */ | |
| 1921 | +SimpleExtendsException(PyExc_Warning, SyntaxWarning, | |
| 1922 | + "Base class for warnings about dubious syntax."); | |
| 1923 | + | |
| 1924 | + | |
| 1925 | +/* | |
| 1926 | + * RuntimeWarning extends Warning | |
| 1927 | + */ | |
| 1928 | +SimpleExtendsException(PyExc_Warning, RuntimeWarning, | |
| 1929 | + "Base class for warnings about dubious runtime behavior."); | |
| 1930 | + | |
| 1931 | + | |
| 1932 | +/* | |
| 1933 | + * FutureWarning extends Warning | |
| 1934 | + */ | |
| 1935 | +SimpleExtendsException(PyExc_Warning, FutureWarning, | |
| 1936 | + "Base class for warnings about constructs that will change semantically\n" | |
| 1937 | + "in the future."); | |
| 1938 | + | |
| 1939 | + | |
| 1940 | +/* | |
| 1941 | + * ImportWarning extends Warning | |
| 1942 | + */ | |
| 1943 | +SimpleExtendsException(PyExc_Warning, ImportWarning, | |
| 1944 | + "Base class for warnings about probable mistakes in module imports"); | |
| 1945 | + | |
| 1946 | + | |
| 1947 | +/* | |
| 1948 | + * UnicodeWarning extends Warning | |
| 1949 | + */ | |
| 1950 | +SimpleExtendsException(PyExc_Warning, UnicodeWarning, | |
| 1951 | + "Base class for warnings about Unicode related problems, mostly\n" | |
| 1952 | + "related to conversion problems."); | |
| 1953 | + | |
| 1954 | + | |
| 1955 | +/* Pre-computed MemoryError instance. Best to create this as early as | |
| 1956 | + * possible and not wait until a MemoryError is actually raised! | |
| 1957 | + */ | |
| 1958 | +PyObject *PyExc_MemoryErrorInst=NULL; | |
| 1959 | + | |
| 1960 | +/* module global functions */ | |
| 1961 | +static PyMethodDef functions[] = { | |
| 1962 | + /* Sentinel */ | |
| 1963 | + {NULL, NULL} | |
| 1964 | +}; | |
| 1965 | + | |
| 1966 | +#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \ | |
| 1967 | + Py_FatalError("exceptions bootstrapping error."); | |
| 1968 | + | |
| 1969 | +#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \ | |
| 1970 | + PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \ | |
| 1971 | + if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \ | |
| 1972 | + Py_FatalError("Module dictionary insertion problem."); | |
| 1973 | + | |
| 1974 | +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) | |
| 1975 | +/* crt variable checking in VisualStudio .NET 2005 */ | |
| 1976 | +#include <crtdbg.h> | |
| 1977 | + | |
| 1978 | +static int prevCrtReportMode; | |
| 1979 | +static _invalid_parameter_handler prevCrtHandler; | |
| 1980 | + | |
| 1981 | +/* Invalid parameter handler. Sets a ValueError exception */ | |
| 1982 | +static void | |
| 1983 | +InvalidParameterHandler( | |
| 1984 | + const wchar_t * expression, | |
| 1985 | + const wchar_t * function, | |
| 1986 | + const wchar_t * file, | |
| 1987 | + unsigned int line, | |
| 1988 | + uintptr_t pReserved) | |
| 1989 | +{ | |
| 1990 | + /* Do nothing, allow execution to continue. Usually this | |
| 1991 | + * means that the CRT will set errno to EINVAL | |
| 1992 | + */ | |
| 1993 | +} | |
| 1994 | +#endif | |
| 1995 | + | |
| 1996 | + | |
| 1997 | +PyMODINIT_FUNC | |
| 1998 | +_PyExc_Init(void) | |
| 1999 | +{ | |
| 2000 | + PyObject *m, *bltinmod, *bdict; | |
| 2001 | + | |
| 2002 | + PRE_INIT(BaseException) | |
| 2003 | + PRE_INIT(Exception) | |
| 2004 | + PRE_INIT(StandardError) | |
| 2005 | + PRE_INIT(TypeError) | |
| 2006 | + PRE_INIT(StopIteration) | |
| 2007 | + PRE_INIT(GeneratorExit) | |
| 2008 | + PRE_INIT(SystemExit) | |
| 2009 | + PRE_INIT(KeyboardInterrupt) | |
| 2010 | + PRE_INIT(ImportError) | |
| 2011 | + PRE_INIT(EnvironmentError) | |
| 2012 | + PRE_INIT(IOError) | |
| 2013 | + PRE_INIT(OSError) | |
| 2014 | +#ifdef MS_WINDOWS | |
| 2015 | + PRE_INIT(WindowsError) | |
| 2016 | +#endif | |
| 2017 | +#ifdef __VMS | |
| 2018 | + PRE_INIT(VMSError) | |
| 2019 | +#endif | |
| 2020 | + PRE_INIT(EOFError) | |
| 2021 | + PRE_INIT(RuntimeError) | |
| 2022 | + PRE_INIT(NotImplementedError) | |
| 2023 | + PRE_INIT(NameError) | |
| 2024 | + PRE_INIT(UnboundLocalError) | |
| 2025 | + PRE_INIT(AttributeError) | |
| 2026 | + PRE_INIT(SyntaxError) | |
| 2027 | + PRE_INIT(IndentationError) | |
| 2028 | + PRE_INIT(TabError) | |
| 2029 | + PRE_INIT(LookupError) | |
| 2030 | + PRE_INIT(IndexError) | |
| 2031 | + PRE_INIT(KeyError) | |
| 2032 | + PRE_INIT(ValueError) | |
| 2033 | + PRE_INIT(UnicodeError) | |
| 2034 | +#ifdef Py_USING_UNICODE | |
| 2035 | + PRE_INIT(UnicodeEncodeError) | |
| 2036 | + PRE_INIT(UnicodeDecodeError) | |
| 2037 | + PRE_INIT(UnicodeTranslateError) | |
| 2038 | +#endif | |
| 2039 | + PRE_INIT(AssertionError) | |
| 2040 | + PRE_INIT(ArithmeticError) | |
| 2041 | + PRE_INIT(FloatingPointError) | |
| 2042 | + PRE_INIT(OverflowError) | |
| 2043 | + PRE_INIT(ZeroDivisionError) | |
| 2044 | + PRE_INIT(SystemError) | |
| 2045 | + PRE_INIT(ReferenceError) | |
| 2046 | + PRE_INIT(MemoryError) | |
| 2047 | + PRE_INIT(Warning) | |
| 2048 | + PRE_INIT(UserWarning) | |
| 2049 | + PRE_INIT(DeprecationWarning) | |
| 2050 | + PRE_INIT(PendingDeprecationWarning) | |
| 2051 | + PRE_INIT(SyntaxWarning) | |
| 2052 | + PRE_INIT(RuntimeWarning) | |
| 2053 | + PRE_INIT(FutureWarning) | |
| 2054 | + PRE_INIT(ImportWarning) | |
| 2055 | + PRE_INIT(UnicodeWarning) | |
| 2056 | + | |
| 2057 | + m = Py_InitModule4("exceptions", functions, exceptions_doc, | |
| 2058 | + (PyObject *)NULL, PYTHON_API_VERSION); | |
| 2059 | + if (m == NULL) return; | |
| 2060 | + | |
| 2061 | + bltinmod = PyImport_ImportModule("__builtin__"); | |
| 2062 | + if (bltinmod == NULL) | |
| 2063 | + Py_FatalError("exceptions bootstrapping error."); | |
| 2064 | + bdict = PyModule_GetDict(bltinmod); | |
| 2065 | + if (bdict == NULL) | |
| 2066 | + Py_FatalError("exceptions bootstrapping error."); | |
| 2067 | + | |
| 2068 | + POST_INIT(BaseException) | |
| 2069 | + POST_INIT(Exception) | |
| 2070 | + POST_INIT(StandardError) | |
| 2071 | + POST_INIT(TypeError) | |
| 2072 | + POST_INIT(StopIteration) | |
| 2073 | + POST_INIT(GeneratorExit) | |
| 2074 | + POST_INIT(SystemExit) | |
| 2075 | + POST_INIT(KeyboardInterrupt) | |
| 2076 | + POST_INIT(ImportError) | |
| 2077 | + POST_INIT(EnvironmentError) | |
| 2078 | + POST_INIT(IOError) | |
| 2079 | + POST_INIT(OSError) | |
| 2080 | +#ifdef MS_WINDOWS | |
| 2081 | + POST_INIT(WindowsError) | |
| 2082 | +#endif | |
| 2083 | +#ifdef __VMS | |
| 2084 | + POST_INIT(VMSError) | |
| 2085 | +#endif | |
| 2086 | + POST_INIT(EOFError) | |
| 2087 | + POST_INIT(RuntimeError) | |
| 2088 | + POST_INIT(NotImplementedError) | |
| 2089 | + POST_INIT(NameError) | |
| 2090 | + POST_INIT(UnboundLocalError) | |
| 2091 | + POST_INIT(AttributeError) | |
| 2092 | + POST_INIT(SyntaxError) | |
| 2093 | + POST_INIT(IndentationError) | |
| 2094 | + POST_INIT(TabError) | |
| 2095 | + POST_INIT(LookupError) | |
| 2096 | + POST_INIT(IndexError) | |
| 2097 | + POST_INIT(KeyError) | |
| 2098 | + POST_INIT(ValueError) | |
| 2099 | + POST_INIT(UnicodeError) | |
| 2100 | +#ifdef Py_USING_UNICODE | |
| 2101 | + POST_INIT(UnicodeEncodeError) | |
| 2102 | + POST_INIT(UnicodeDecodeError) | |
| 2103 | + POST_INIT(UnicodeTranslateError) | |
| 2104 | +#endif | |
| 2105 | + POST_INIT(AssertionError) | |
| 2106 | + POST_INIT(ArithmeticError) | |
| 2107 | + POST_INIT(FloatingPointError) | |
| 2108 | + POST_INIT(OverflowError) | |
| 2109 | + POST_INIT(ZeroDivisionError) | |
| 2110 | + POST_INIT(SystemError) | |
| 2111 | + POST_INIT(ReferenceError) | |
| 2112 | + POST_INIT(MemoryError) | |
| 2113 | + POST_INIT(Warning) | |
| 2114 | + POST_INIT(UserWarning) | |
| 2115 | + POST_INIT(DeprecationWarning) | |
| 2116 | + POST_INIT(PendingDeprecationWarning) | |
| 2117 | + POST_INIT(SyntaxWarning) | |
| 2118 | + POST_INIT(RuntimeWarning) | |
| 2119 | + POST_INIT(FutureWarning) | |
| 2120 | + POST_INIT(ImportWarning) | |
| 2121 | + POST_INIT(UnicodeWarning) | |
| 2122 | + | |
| 2123 | + PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL); | |
| 2124 | + if (!PyExc_MemoryErrorInst) | |
| 2125 | + Py_FatalError("Cannot pre-allocate MemoryError instance\n"); | |
| 2126 | + | |
| 2127 | + Py_DECREF(bltinmod); | |
| 2128 | + | |
| 2129 | +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) | |
| 2130 | + /* Set CRT argument error handler */ | |
| 2131 | + prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler); | |
| 2132 | + /* turn off assertions in debug mode */ | |
| 2133 | + prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0); | |
| 2134 | +#endif | |
| 2135 | +} | |
| 2136 | + | |
| 2137 | +void | |
| 2138 | +_PyExc_Fini(void) | |
| 2139 | +{ | |
| 2140 | + Py_XDECREF(PyExc_MemoryErrorInst); | |
| 2141 | + PyExc_MemoryErrorInst = NULL; | |
| 2142 | +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) | |
| 2143 | + /* reset CRT error handling */ | |
| 2144 | + _set_invalid_parameter_handler(prevCrtHandler); | |
| 2145 | + _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode); | |
| 2146 | +#endif | |
| 2147 | +} | |
| @@ -0,0 +1,2484 @@ | ||
| 1 | +/* File object implementation */ | |
| 2 | + | |
| 3 | +#define PY_SSIZE_T_CLEAN | |
| 4 | +#include "Python.h" | |
| 5 | +#include "structmember.h" | |
| 6 | + | |
| 7 | +#ifdef HAVE_SYS_TYPES_H | |
| 8 | +#include <sys/types.h> | |
| 9 | +#endif /* HAVE_SYS_TYPES_H */ | |
| 10 | + | |
| 11 | +#ifdef MS_WINDOWS | |
| 12 | +#define fileno _fileno | |
| 13 | +/* can simulate truncate with Win32 API functions; see file_truncate */ | |
| 14 | +#define HAVE_FTRUNCATE | |
| 15 | +#define WIN32_LEAN_AND_MEAN | |
| 16 | +#include <windows.h> | |
| 17 | +#endif | |
| 18 | + | |
| 19 | +#ifdef _MSC_VER | |
| 20 | +/* Need GetVersion to see if on NT so safe to use _wfopen */ | |
| 21 | +#define WIN32_LEAN_AND_MEAN | |
| 22 | +#include <windows.h> | |
| 23 | +#endif /* _MSC_VER */ | |
| 24 | + | |
| 25 | +#if defined(PYOS_OS2) && defined(PYCC_GCC) | |
| 26 | +#include <io.h> | |
| 27 | +#endif | |
| 28 | + | |
| 29 | +#define BUF(v) PyString_AS_STRING((PyStringObject *)v) | |
| 30 | + | |
| 31 | +#ifndef DONT_HAVE_ERRNO_H | |
| 32 | +#include <errno.h> | |
| 33 | +#endif | |
| 34 | + | |
| 35 | +#ifdef HAVE_GETC_UNLOCKED | |
| 36 | +#define GETC(f) getc_unlocked(f) | |
| 37 | +#define FLOCKFILE(f) flockfile(f) | |
| 38 | +#define FUNLOCKFILE(f) funlockfile(f) | |
| 39 | +#else | |
| 40 | +#define GETC(f) getc(f) | |
| 41 | +#define FLOCKFILE(f) | |
| 42 | +#define FUNLOCKFILE(f) | |
| 43 | +#endif | |
| 44 | + | |
| 45 | +/* Bits in f_newlinetypes */ | |
| 46 | +#define NEWLINE_UNKNOWN 0 /* No newline seen, yet */ | |
| 47 | +#define NEWLINE_CR 1 /* \r newline seen */ | |
| 48 | +#define NEWLINE_LF 2 /* \n newline seen */ | |
| 49 | +#define NEWLINE_CRLF 4 /* \r\n newline seen */ | |
| 50 | + | |
| 51 | +#ifdef __cplusplus | |
| 52 | +extern "C" { | |
| 53 | +#endif | |
| 54 | + | |
| 55 | +FILE * | |
| 56 | +PyFile_AsFile(PyObject *f) | |
| 57 | +{ | |
| 58 | + if (f == NULL || !PyFile_Check(f)) | |
| 59 | + return NULL; | |
| 60 | + else | |
| 61 | + return ((PyFileObject *)f)->f_fp; | |
| 62 | +} | |
| 63 | + | |
| 64 | +PyObject * | |
| 65 | +PyFile_Name(PyObject *f) | |
| 66 | +{ | |
| 67 | + if (f == NULL || !PyFile_Check(f)) | |
| 68 | + return NULL; | |
| 69 | + else | |
| 70 | + return ((PyFileObject *)f)->f_name; | |
| 71 | +} | |
| 72 | + | |
| 73 | +/* On Unix, fopen will succeed for directories. | |
| 74 | + In Python, there should be no file objects referring to | |
| 75 | + directories, so we need a check. */ | |
| 76 | + | |
| 77 | +static PyFileObject* | |
| 78 | +dircheck(PyFileObject* f) | |
| 79 | +{ | |
| 80 | +#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) | |
| 81 | + struct stat buf; | |
| 82 | + if (f->f_fp == NULL) | |
| 83 | + return f; | |
| 84 | + if (fstat(fileno(f->f_fp), &buf) == 0 && | |
| 85 | + S_ISDIR(buf.st_mode)) { | |
| 86 | +#ifdef HAVE_STRERROR | |
| 87 | + char *msg = strerror(EISDIR); | |
| 88 | +#else | |
| 89 | + char *msg = "Is a directory"; | |
| 90 | +#endif | |
| 91 | + PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(is)", | |
| 92 | + EISDIR, msg); | |
| 93 | + PyErr_SetObject(PyExc_IOError, exc); | |
| 94 | + Py_XDECREF(exc); | |
| 95 | + return NULL; | |
| 96 | + } | |
| 97 | +#endif | |
| 98 | + return f; | |
| 99 | +} | |
| 100 | + | |
| 101 | + | |
| 102 | +static PyObject * | |
| 103 | +fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode, | |
| 104 | + int (*close)(FILE *)) | |
| 105 | +{ | |
| 106 | + assert(name != NULL); | |
| 107 | + assert(f != NULL); | |
| 108 | + assert(PyFile_Check(f)); | |
| 109 | + assert(f->f_fp == NULL); | |
| 110 | + | |
| 111 | + Py_DECREF(f->f_name); | |
| 112 | + Py_DECREF(f->f_mode); | |
| 113 | + Py_DECREF(f->f_encoding); | |
| 114 | + | |
| 115 | + Py_INCREF(name); | |
| 116 | + f->f_name = name; | |
| 117 | + | |
| 118 | + f->f_mode = PyString_FromString(mode); | |
| 119 | + | |
| 120 | + f->f_close = close; | |
| 121 | + f->f_softspace = 0; | |
| 122 | + f->f_binary = strchr(mode,'b') != NULL; | |
| 123 | + f->f_buf = NULL; | |
| 124 | + f->f_univ_newline = (strchr(mode, 'U') != NULL); | |
| 125 | + f->f_newlinetypes = NEWLINE_UNKNOWN; | |
| 126 | + f->f_skipnextlf = 0; | |
| 127 | + Py_INCREF(Py_None); | |
| 128 | + f->f_encoding = Py_None; | |
| 129 | + | |
| 130 | + if (f->f_mode == NULL) | |
| 131 | + return NULL; | |
| 132 | + f->f_fp = fp; | |
| 133 | + f = dircheck(f); | |
| 134 | + return (PyObject *) f; | |
| 135 | +} | |
| 136 | + | |
| 137 | +/* check for known incorrect mode strings - problem is, platforms are | |
| 138 | + free to accept any mode characters they like and are supposed to | |
| 139 | + ignore stuff they don't understand... write or append mode with | |
| 140 | + universal newline support is expressly forbidden by PEP 278. | |
| 141 | + Additionally, remove the 'U' from the mode string as platforms | |
| 142 | + won't know what it is. */ | |
| 143 | +/* zero return is kewl - one is un-kewl */ | |
| 144 | +static int | |
| 145 | +sanitize_the_mode(char *mode) | |
| 146 | +{ | |
| 147 | + char *upos; | |
| 148 | + size_t len = strlen(mode); | |
| 149 | + | |
| 150 | + if (!len) { | |
| 151 | + PyErr_SetString(PyExc_ValueError, "empty mode string"); | |
| 152 | + return 1; | |
| 153 | + } | |
| 154 | + | |
| 155 | + upos = strchr(mode, 'U'); | |
| 156 | + if (upos) { | |
| 157 | + memmove(upos, upos+1, len-(upos-mode)); /* incl null char */ | |
| 158 | + | |
| 159 | + if (mode[0] == 'w' || mode[0] == 'a') { | |
| 160 | + PyErr_Format(PyExc_ValueError, "universal newline " | |
| 161 | + "mode can only be used with modes " | |
| 162 | + "starting with 'r'"); | |
| 163 | + return 1; | |
| 164 | + } | |
| 165 | + | |
| 166 | + if (mode[0] != 'r') { | |
| 167 | + memmove(mode+1, mode, strlen(mode)+1); | |
| 168 | + mode[0] = 'r'; | |
| 169 | + } | |
| 170 | + | |
| 171 | + if (!strchr(mode, 'b')) { | |
| 172 | + memmove(mode+2, mode+1, strlen(mode)); | |
| 173 | + mode[1] = 'b'; | |
| 174 | + } | |
| 175 | + } else if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') { | |
| 176 | + PyErr_Format(PyExc_ValueError, "mode string must begin with " | |
| 177 | + "one of 'r', 'w', 'a' or 'U', not '%.200s'", mode); | |
| 178 | + return 1; | |
| 179 | + } | |
| 180 | + | |
| 181 | + return 0; | |
| 182 | +} | |
| 183 | + | |
| 184 | +static PyObject * | |
| 185 | +open_the_file(PyFileObject *f, char *name, char *mode) | |
| 186 | +{ | |
| 187 | + char *newmode; | |
| 188 | + assert(f != NULL); | |
| 189 | + assert(PyFile_Check(f)); | |
| 190 | +#ifdef MS_WINDOWS | |
| 191 | + /* windows ignores the passed name in order to support Unicode */ | |
| 192 | + assert(f->f_name != NULL); | |
| 193 | +#else | |
| 194 | + assert(name != NULL); | |
| 195 | +#endif | |
| 196 | + assert(mode != NULL); | |
| 197 | + assert(f->f_fp == NULL); | |
| 198 | + | |
| 199 | + /* probably need to replace 'U' by 'rb' */ | |
| 200 | + newmode = PyMem_MALLOC(strlen(mode) + 3); | |
| 201 | + if (!newmode) { | |
| 202 | + PyErr_NoMemory(); | |
| 203 | + return NULL; | |
| 204 | + } | |
| 205 | + strcpy(newmode, mode); | |
| 206 | + | |
| 207 | + if (sanitize_the_mode(newmode)) { | |
| 208 | + f = NULL; | |
| 209 | + goto cleanup; | |
| 210 | + } | |
| 211 | + | |
| 212 | + /* rexec.py can't stop a user from getting the file() constructor -- | |
| 213 | + all they have to do is get *any* file object f, and then do | |
| 214 | + type(f). Here we prevent them from doing damage with it. */ | |
| 215 | + if (PyEval_GetRestricted()) { | |
| 216 | + PyErr_SetString(PyExc_IOError, | |
| 217 | + "file() constructor not accessible in restricted mode"); | |
| 218 | + f = NULL; | |
| 219 | + goto cleanup; | |
| 220 | + } | |
| 221 | + errno = 0; | |
| 222 | + | |
| 223 | +#ifdef MS_WINDOWS | |
| 224 | + if (PyUnicode_Check(f->f_name)) { | |
| 225 | + PyObject *wmode; | |
| 226 | + wmode = PyUnicode_DecodeASCII(newmode, strlen(newmode), NULL); | |
| 227 | + if (f->f_name && wmode) { | |
| 228 | + Py_BEGIN_ALLOW_THREADS | |
| 229 | + /* PyUnicode_AS_UNICODE OK without thread | |
| 230 | + lock as it is a simple dereference. */ | |
| 231 | + f->f_fp = _wfopen(PyUnicode_AS_UNICODE(f->f_name), | |
| 232 | + PyUnicode_AS_UNICODE(wmode)); | |
| 233 | + Py_END_ALLOW_THREADS | |
| 234 | + } | |
| 235 | + Py_XDECREF(wmode); | |
| 236 | + } | |
| 237 | +#endif | |
| 238 | + if (NULL == f->f_fp && NULL != name) { | |
| 239 | + Py_BEGIN_ALLOW_THREADS | |
| 240 | + f->f_fp = fopen(name, newmode); | |
| 241 | + Py_END_ALLOW_THREADS | |
| 242 | + } | |
| 243 | + | |
| 244 | + if (f->f_fp == NULL) { | |
| 245 | +#if defined _MSC_VER && (_MSC_VER < 1400 || !defined(__STDC_SECURE_LIB__)) | |
| 246 | + /* MSVC 6 (Microsoft) leaves errno at 0 for bad mode strings, | |
| 247 | + * across all Windows flavors. When it sets EINVAL varies | |
| 248 | + * across Windows flavors, the exact conditions aren't | |
| 249 | + * documented, and the answer lies in the OS's implementation | |
| 250 | + * of Win32's CreateFile function (whose source is secret). | |
| 251 | + * Seems the best we can do is map EINVAL to ENOENT. | |
| 252 | + * Starting with Visual Studio .NET 2005, EINVAL is correctly | |
| 253 | + * set by our CRT error handler (set in exceptions.c.) | |
| 254 | + */ | |
| 255 | + if (errno == 0) /* bad mode string */ | |
| 256 | + errno = EINVAL; | |
| 257 | + else if (errno == EINVAL) /* unknown, but not a mode string */ | |
| 258 | + errno = ENOENT; | |
| 259 | +#endif | |
| 260 | + if (errno == EINVAL) | |
| 261 | + PyErr_Format(PyExc_IOError, "invalid mode: %s", | |
| 262 | + mode); | |
| 263 | + else | |
| 264 | + PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, f->f_name); | |
| 265 | + f = NULL; | |
| 266 | + } | |
| 267 | + if (f != NULL) | |
| 268 | + f = dircheck(f); | |
| 269 | + | |
| 270 | +cleanup: | |
| 271 | + PyMem_FREE(newmode); | |
| 272 | + | |
| 273 | + return (PyObject *)f; | |
| 274 | +} | |
| 275 | + | |
| 276 | +PyObject * | |
| 277 | +PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *)) | |
| 278 | +{ | |
| 279 | + PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type, | |
| 280 | + NULL, NULL); | |
| 281 | + if (f != NULL) { | |
| 282 | + PyObject *o_name = PyString_FromString(name); | |
| 283 | + if (o_name == NULL) | |
| 284 | + return NULL; | |
| 285 | + if (fill_file_fields(f, fp, o_name, mode, close) == NULL) { | |
| 286 | + Py_DECREF(f); | |
| 287 | + f = NULL; | |
| 288 | + } | |
| 289 | + Py_DECREF(o_name); | |
| 290 | + } | |
| 291 | + return (PyObject *) f; | |
| 292 | +} | |
| 293 | + | |
| 294 | +PyObject * | |
| 295 | +PyFile_FromString(char *name, char *mode) | |
| 296 | +{ | |
| 297 | + extern int fclose(FILE *); | |
| 298 | + PyFileObject *f; | |
| 299 | + | |
| 300 | + f = (PyFileObject *)PyFile_FromFile((FILE *)NULL, name, mode, fclose); | |
| 301 | + if (f != NULL) { | |
| 302 | + if (open_the_file(f, name, mode) == NULL) { | |
| 303 | + Py_DECREF(f); | |
| 304 | + f = NULL; | |
| 305 | + } | |
| 306 | + } | |
| 307 | + return (PyObject *)f; | |
| 308 | +} | |
| 309 | + | |
| 310 | +void | |
| 311 | +PyFile_SetBufSize(PyObject *f, int bufsize) | |
| 312 | +{ | |
| 313 | + PyFileObject *file = (PyFileObject *)f; | |
| 314 | + if (bufsize >= 0) { | |
| 315 | + int type; | |
| 316 | + switch (bufsize) { | |
| 317 | + case 0: | |
| 318 | + type = _IONBF; | |
| 319 | + break; | |
| 320 | +#ifdef HAVE_SETVBUF | |
| 321 | + case 1: | |
| 322 | + type = _IOLBF; | |
| 323 | + bufsize = BUFSIZ; | |
| 324 | + break; | |
| 325 | +#endif | |
| 326 | + default: | |
| 327 | + type = _IOFBF; | |
| 328 | +#ifndef HAVE_SETVBUF | |
| 329 | + bufsize = BUFSIZ; | |
| 330 | +#endif | |
| 331 | + break; | |
| 332 | + } | |
| 333 | + fflush(file->f_fp); | |
| 334 | + if (type == _IONBF) { | |
| 335 | + PyMem_Free(file->f_setbuf); | |
| 336 | + file->f_setbuf = NULL; | |
| 337 | + } else { | |
| 338 | + file->f_setbuf = (char *)PyMem_Realloc(file->f_setbuf, | |
| 339 | + bufsize); | |
| 340 | + } | |
| 341 | +#ifdef HAVE_SETVBUF | |
| 342 | + setvbuf(file->f_fp, file->f_setbuf, type, bufsize); | |
| 343 | +#else /* !HAVE_SETVBUF */ | |
| 344 | + setbuf(file->f_fp, file->f_setbuf); | |
| 345 | +#endif /* !HAVE_SETVBUF */ | |
| 346 | + } | |
| 347 | +} | |
| 348 | + | |
| 349 | +/* Set the encoding used to output Unicode strings. | |
| 350 | + Returh 1 on success, 0 on failure. */ | |
| 351 | + | |
| 352 | +int | |
| 353 | +PyFile_SetEncoding(PyObject *f, const char *enc) | |
| 354 | +{ | |
| 355 | + PyFileObject *file = (PyFileObject*)f; | |
| 356 | + PyObject *str = PyString_FromString(enc); | |
| 357 | + | |
| 358 | + assert(PyFile_Check(f)); | |
| 359 | + if (!str) | |
| 360 | + return 0; | |
| 361 | + Py_DECREF(file->f_encoding); | |
| 362 | + file->f_encoding = str; | |
| 363 | + return 1; | |
| 364 | +} | |
| 365 | + | |
| 366 | +static PyObject * | |
| 367 | +err_closed(void) | |
| 368 | +{ | |
| 369 | + PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); | |
| 370 | + return NULL; | |
| 371 | +} | |
| 372 | + | |
| 373 | +/* Refuse regular file I/O if there's data in the iteration-buffer. | |
| 374 | + * Mixing them would cause data to arrive out of order, as the read* | |
| 375 | + * methods don't use the iteration buffer. */ | |
| 376 | +static PyObject * | |
| 377 | +err_iterbuffered(void) | |
| 378 | +{ | |
| 379 | + PyErr_SetString(PyExc_ValueError, | |
| 380 | + "Mixing iteration and read methods would lose data"); | |
| 381 | + return NULL; | |
| 382 | +} | |
| 383 | + | |
| 384 | +static void drop_readahead(PyFileObject *); | |
| 385 | + | |
| 386 | +/* Methods */ | |
| 387 | + | |
| 388 | +static void | |
| 389 | +file_dealloc(PyFileObject *f) | |
| 390 | +{ | |
| 391 | + int sts = 0; | |
| 392 | + if (f->weakreflist != NULL) | |
| 393 | + PyObject_ClearWeakRefs((PyObject *) f); | |
| 394 | + if (f->f_fp != NULL && f->f_close != NULL) { | |
| 395 | + Py_BEGIN_ALLOW_THREADS | |
| 396 | + sts = (*f->f_close)(f->f_fp); | |
| 397 | + Py_END_ALLOW_THREADS | |
| 398 | + if (sts == EOF) | |
| 399 | +#ifdef HAVE_STRERROR | |
| 400 | + PySys_WriteStderr("close failed: [Errno %d] %s\n", errno, strerror(errno)); | |
| 401 | +#else | |
| 402 | + PySys_WriteStderr("close failed: [Errno %d]\n", errno); | |
| 403 | +#endif | |
| 404 | + } | |
| 405 | + PyMem_Free(f->f_setbuf); | |
| 406 | + Py_XDECREF(f->f_name); | |
| 407 | + Py_XDECREF(f->f_mode); | |
| 408 | + Py_XDECREF(f->f_encoding); | |
| 409 | + drop_readahead(f); | |
| 410 | + f->ob_type->tp_free((PyObject *)f); | |
| 411 | +} | |
| 412 | + | |
| 413 | +static PyObject * | |
| 414 | +file_repr(PyFileObject *f) | |
| 415 | +{ | |
| 416 | + if (PyUnicode_Check(f->f_name)) { | |
| 417 | +#ifdef Py_USING_UNICODE | |
| 418 | + PyObject *ret = NULL; | |
| 419 | + PyObject *name = PyUnicode_AsUnicodeEscapeString(f->f_name); | |
| 420 | + const char *name_str = name ? PyString_AsString(name) : "?"; | |
| 421 | + ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>", | |
| 422 | + f->f_fp == NULL ? "closed" : "open", | |
| 423 | + name_str, | |
| 424 | + PyString_AsString(f->f_mode), | |
| 425 | + f); | |
| 426 | + Py_XDECREF(name); | |
| 427 | + return ret; | |
| 428 | +#endif | |
| 429 | + } else { | |
| 430 | + return PyString_FromFormat("<%s file '%s', mode '%s' at %p>", | |
| 431 | + f->f_fp == NULL ? "closed" : "open", | |
| 432 | + PyString_AsString(f->f_name), | |
| 433 | + PyString_AsString(f->f_mode), | |
| 434 | + f); | |
| 435 | + } | |
| 436 | +} | |
| 437 | + | |
| 438 | +static PyObject * | |
| 439 | +file_close(PyFileObject *f) | |
| 440 | +{ | |
| 441 | + int sts = 0; | |
| 442 | + if (f->f_fp != NULL) { | |
| 443 | + if (f->f_close != NULL) { | |
| 444 | + Py_BEGIN_ALLOW_THREADS | |
| 445 | + errno = 0; | |
| 446 | + sts = (*f->f_close)(f->f_fp); | |
| 447 | + Py_END_ALLOW_THREADS | |
| 448 | + } | |
| 449 | + f->f_fp = NULL; | |
| 450 | + } | |
| 451 | + PyMem_Free(f->f_setbuf); | |
| 452 | + f->f_setbuf = NULL; | |
| 453 | + if (sts == EOF) | |
| 454 | + return PyErr_SetFromErrno(PyExc_IOError); | |
| 455 | + if (sts != 0) | |
| 456 | + return PyInt_FromLong((long)sts); | |
| 457 | + Py_INCREF(Py_None); | |
| 458 | + return Py_None; | |
| 459 | +} | |
| 460 | + | |
| 461 | + | |
| 462 | +/* Our very own off_t-like type, 64-bit if possible */ | |
| 463 | +#if !defined(HAVE_LARGEFILE_SUPPORT) | |
| 464 | +typedef off_t Py_off_t; | |
| 465 | +#elif SIZEOF_OFF_T >= 8 | |
| 466 | +typedef off_t Py_off_t; | |
| 467 | +#elif SIZEOF_FPOS_T >= 8 | |
| 468 | +typedef fpos_t Py_off_t; | |
| 469 | +#else | |
| 470 | +#error "Large file support, but neither off_t nor fpos_t is large enough." | |
| 471 | +#endif | |
| 472 | + | |
| 473 | + | |
| 474 | +/* a portable fseek() function | |
| 475 | + return 0 on success, non-zero on failure (with errno set) */ | |
| 476 | +static int | |
| 477 | +_portable_fseek(FILE *fp, Py_off_t offset, int whence) | |
| 478 | +{ | |
| 479 | +#if !defined(HAVE_LARGEFILE_SUPPORT) | |
| 480 | + return fseek(fp, offset, whence); | |
| 481 | +#elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8 | |
| 482 | + return fseeko(fp, offset, whence); | |
| 483 | +#elif defined(HAVE_FSEEK64) | |
| 484 | + return fseek64(fp, offset, whence); | |
| 485 | +#elif defined(__BEOS__) | |
| 486 | + return _fseek(fp, offset, whence); | |
| 487 | +#elif SIZEOF_FPOS_T >= 8 | |
| 488 | + /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos() | |
| 489 | + and fgetpos() to implement fseek()*/ | |
| 490 | + fpos_t pos; | |
| 491 | + switch (whence) { | |
| 492 | + case SEEK_END: | |
| 493 | +#ifdef MS_WINDOWS | |
| 494 | + fflush(fp); | |
| 495 | + if (_lseeki64(fileno(fp), 0, 2) == -1) | |
| 496 | + return -1; | |
| 497 | +#else | |
| 498 | + if (fseek(fp, 0, SEEK_END) != 0) | |
| 499 | + return -1; | |
| 500 | +#endif | |
| 501 | + /* fall through */ | |
| 502 | + case SEEK_CUR: | |
| 503 | + if (fgetpos(fp, &pos) != 0) | |
| 504 | + return -1; | |
| 505 | + offset += pos; | |
| 506 | + break; | |
| 507 | + /* case SEEK_SET: break; */ | |
| 508 | + } | |
| 509 | + return fsetpos(fp, &offset); | |
| 510 | +#else | |
| 511 | +#error "Large file support, but no way to fseek." | |
| 512 | +#endif | |
| 513 | +} | |
| 514 | + | |
| 515 | + | |
| 516 | +/* a portable ftell() function | |
| 517 | + Return -1 on failure with errno set appropriately, current file | |
| 518 | + position on success */ | |
| 519 | +static Py_off_t | |
| 520 | +_portable_ftell(FILE* fp) | |
| 521 | +{ | |
| 522 | +#if !defined(HAVE_LARGEFILE_SUPPORT) | |
| 523 | + return ftell(fp); | |
| 524 | +#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8 | |
| 525 | + return ftello(fp); | |
| 526 | +#elif defined(HAVE_FTELL64) | |
| 527 | + return ftell64(fp); | |
| 528 | +#elif SIZEOF_FPOS_T >= 8 | |
| 529 | + fpos_t pos; | |
| 530 | + if (fgetpos(fp, &pos) != 0) | |
| 531 | + return -1; | |
| 532 | + return pos; | |
| 533 | +#else | |
| 534 | +#error "Large file support, but no way to ftell." | |
| 535 | +#endif | |
| 536 | +} | |
| 537 | + | |
| 538 | + | |
| 539 | +static PyObject * | |
| 540 | +file_seek(PyFileObject *f, PyObject *args) | |
| 541 | +{ | |
| 542 | + int whence; | |
| 543 | + int ret; | |
| 544 | + Py_off_t offset; | |
| 545 | + PyObject *offobj; | |
| 546 | + | |
| 547 | + if (f->f_fp == NULL) | |
| 548 | + return err_closed(); | |
| 549 | + drop_readahead(f); | |
| 550 | + whence = 0; | |
| 551 | + if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence)) | |
| 552 | + return NULL; | |
| 553 | +#if !defined(HAVE_LARGEFILE_SUPPORT) | |
| 554 | + offset = PyInt_AsLong(offobj); | |
| 555 | +#else | |
| 556 | + offset = PyLong_Check(offobj) ? | |
| 557 | + PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj); | |
| 558 | +#endif | |
| 559 | + if (PyErr_Occurred()) | |
| 560 | + return NULL; | |
| 561 | + | |
| 562 | + Py_BEGIN_ALLOW_THREADS | |
| 563 | + errno = 0; | |
| 564 | + ret = _portable_fseek(f->f_fp, offset, whence); | |
| 565 | + Py_END_ALLOW_THREADS | |
| 566 | + | |
| 567 | + if (ret != 0) { | |
| 568 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 569 | + clearerr(f->f_fp); | |
| 570 | + return NULL; | |
| 571 | + } | |
| 572 | + f->f_skipnextlf = 0; | |
| 573 | + Py_INCREF(Py_None); | |
| 574 | + return Py_None; | |
| 575 | +} | |
| 576 | + | |
| 577 | + | |
| 578 | +#ifdef HAVE_FTRUNCATE | |
| 579 | +static PyObject * | |
| 580 | +file_truncate(PyFileObject *f, PyObject *args) | |
| 581 | +{ | |
| 582 | + Py_off_t newsize; | |
| 583 | + PyObject *newsizeobj = NULL; | |
| 584 | + Py_off_t initialpos; | |
| 585 | + int ret; | |
| 586 | + | |
| 587 | + if (f->f_fp == NULL) | |
| 588 | + return err_closed(); | |
| 589 | + if (!PyArg_UnpackTuple(args, "truncate", 0, 1, &newsizeobj)) | |
| 590 | + return NULL; | |
| 591 | + | |
| 592 | + /* Get current file position. If the file happens to be open for | |
| 593 | + * update and the last operation was an input operation, C doesn't | |
| 594 | + * define what the later fflush() will do, but we promise truncate() | |
| 595 | + * won't change the current position (and fflush() *does* change it | |
| 596 | + * then at least on Windows). The easiest thing is to capture | |
| 597 | + * current pos now and seek back to it at the end. | |
| 598 | + */ | |
| 599 | + Py_BEGIN_ALLOW_THREADS | |
| 600 | + errno = 0; | |
| 601 | + initialpos = _portable_ftell(f->f_fp); | |
| 602 | + Py_END_ALLOW_THREADS | |
| 603 | + if (initialpos == -1) | |
| 604 | + goto onioerror; | |
| 605 | + | |
| 606 | + /* Set newsize to current postion if newsizeobj NULL, else to the | |
| 607 | + * specified value. | |
| 608 | + */ | |
| 609 | + if (newsizeobj != NULL) { | |
| 610 | +#if !defined(HAVE_LARGEFILE_SUPPORT) | |
| 611 | + newsize = PyInt_AsLong(newsizeobj); | |
| 612 | +#else | |
| 613 | + newsize = PyLong_Check(newsizeobj) ? | |
| 614 | + PyLong_AsLongLong(newsizeobj) : | |
| 615 | + PyInt_AsLong(newsizeobj); | |
| 616 | +#endif | |
| 617 | + if (PyErr_Occurred()) | |
| 618 | + return NULL; | |
| 619 | + } | |
| 620 | + else /* default to current position */ | |
| 621 | + newsize = initialpos; | |
| 622 | + | |
| 623 | + /* Flush the stream. We're mixing stream-level I/O with lower-level | |
| 624 | + * I/O, and a flush may be necessary to synch both platform views | |
| 625 | + * of the current file state. | |
| 626 | + */ | |
| 627 | + Py_BEGIN_ALLOW_THREADS | |
| 628 | + errno = 0; | |
| 629 | + ret = fflush(f->f_fp); | |
| 630 | + Py_END_ALLOW_THREADS | |
| 631 | + if (ret != 0) | |
| 632 | + goto onioerror; | |
| 633 | + | |
| 634 | +#ifdef MS_WINDOWS | |
| 635 | + /* MS _chsize doesn't work if newsize doesn't fit in 32 bits, | |
| 636 | + so don't even try using it. */ | |
| 637 | + { | |
| 638 | + HANDLE hFile; | |
| 639 | + | |
| 640 | + /* Have to move current pos to desired endpoint on Windows. */ | |
| 641 | + Py_BEGIN_ALLOW_THREADS | |
| 642 | + errno = 0; | |
| 643 | + ret = _portable_fseek(f->f_fp, newsize, SEEK_SET) != 0; | |
| 644 | + Py_END_ALLOW_THREADS | |
| 645 | + if (ret) | |
| 646 | + goto onioerror; | |
| 647 | + | |
| 648 | + /* Truncate. Note that this may grow the file! */ | |
| 649 | + Py_BEGIN_ALLOW_THREADS | |
| 650 | + errno = 0; | |
| 651 | + hFile = (HANDLE)_get_osfhandle(fileno(f->f_fp)); | |
| 652 | + ret = hFile == (HANDLE)-1; | |
| 653 | + if (ret == 0) { | |
| 654 | + ret = SetEndOfFile(hFile) == 0; | |
| 655 | + if (ret) | |
| 656 | + errno = EACCES; | |
| 657 | + } | |
| 658 | + Py_END_ALLOW_THREADS | |
| 659 | + if (ret) | |
| 660 | + goto onioerror; | |
| 661 | + } | |
| 662 | +#else | |
| 663 | + Py_BEGIN_ALLOW_THREADS | |
| 664 | + errno = 0; | |
| 665 | + ret = ftruncate(fileno(f->f_fp), newsize); | |
| 666 | + Py_END_ALLOW_THREADS | |
| 667 | + if (ret != 0) | |
| 668 | + goto onioerror; | |
| 669 | +#endif /* !MS_WINDOWS */ | |
| 670 | + | |
| 671 | + /* Restore original file position. */ | |
| 672 | + Py_BEGIN_ALLOW_THREADS | |
| 673 | + errno = 0; | |
| 674 | + ret = _portable_fseek(f->f_fp, initialpos, SEEK_SET) != 0; | |
| 675 | + Py_END_ALLOW_THREADS | |
| 676 | + if (ret) | |
| 677 | + goto onioerror; | |
| 678 | + | |
| 679 | + Py_INCREF(Py_None); | |
| 680 | + return Py_None; | |
| 681 | + | |
| 682 | +onioerror: | |
| 683 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 684 | + clearerr(f->f_fp); | |
| 685 | + return NULL; | |
| 686 | +} | |
| 687 | +#endif /* HAVE_FTRUNCATE */ | |
| 688 | + | |
| 689 | +static PyObject * | |
| 690 | +file_tell(PyFileObject *f) | |
| 691 | +{ | |
| 692 | + Py_off_t pos; | |
| 693 | + | |
| 694 | + if (f->f_fp == NULL) | |
| 695 | + return err_closed(); | |
| 696 | + Py_BEGIN_ALLOW_THREADS | |
| 697 | + errno = 0; | |
| 698 | + pos = _portable_ftell(f->f_fp); | |
| 699 | + Py_END_ALLOW_THREADS | |
| 700 | + if (pos == -1) { | |
| 701 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 702 | + clearerr(f->f_fp); | |
| 703 | + return NULL; | |
| 704 | + } | |
| 705 | + if (f->f_skipnextlf) { | |
| 706 | + int c; | |
| 707 | + c = GETC(f->f_fp); | |
| 708 | + if (c == '\n') { | |
| 709 | + pos++; | |
| 710 | + f->f_skipnextlf = 0; | |
| 711 | + } else if (c != EOF) ungetc(c, f->f_fp); | |
| 712 | + } | |
| 713 | +#if !defined(HAVE_LARGEFILE_SUPPORT) | |
| 714 | + return PyInt_FromLong(pos); | |
| 715 | +#else | |
| 716 | + return PyLong_FromLongLong(pos); | |
| 717 | +#endif | |
| 718 | +} | |
| 719 | + | |
| 720 | +static PyObject * | |
| 721 | +file_fileno(PyFileObject *f) | |
| 722 | +{ | |
| 723 | + if (f->f_fp == NULL) | |
| 724 | + return err_closed(); | |
| 725 | + return PyInt_FromLong((long) fileno(f->f_fp)); | |
| 726 | +} | |
| 727 | + | |
| 728 | +static PyObject * | |
| 729 | +file_flush(PyFileObject *f) | |
| 730 | +{ | |
| 731 | + int res; | |
| 732 | + | |
| 733 | + if (f->f_fp == NULL) | |
| 734 | + return err_closed(); | |
| 735 | + Py_BEGIN_ALLOW_THREADS | |
| 736 | + errno = 0; | |
| 737 | + res = fflush(f->f_fp); | |
| 738 | + Py_END_ALLOW_THREADS | |
| 739 | + if (res != 0) { | |
| 740 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 741 | + clearerr(f->f_fp); | |
| 742 | + return NULL; | |
| 743 | + } | |
| 744 | + Py_INCREF(Py_None); | |
| 745 | + return Py_None; | |
| 746 | +} | |
| 747 | + | |
| 748 | +static PyObject * | |
| 749 | +file_isatty(PyFileObject *f) | |
| 750 | +{ | |
| 751 | + long res; | |
| 752 | + if (f->f_fp == NULL) | |
| 753 | + return err_closed(); | |
| 754 | + Py_BEGIN_ALLOW_THREADS | |
| 755 | + res = isatty((int)fileno(f->f_fp)); | |
| 756 | + Py_END_ALLOW_THREADS | |
| 757 | + return PyBool_FromLong(res); | |
| 758 | +} | |
| 759 | + | |
| 760 | + | |
| 761 | +#if BUFSIZ < 8192 | |
| 762 | +#define SMALLCHUNK 8192 | |
| 763 | +#else | |
| 764 | +#define SMALLCHUNK BUFSIZ | |
| 765 | +#endif | |
| 766 | + | |
| 767 | +#if SIZEOF_INT < 4 | |
| 768 | +#define BIGCHUNK (512 * 32) | |
| 769 | +#else | |
| 770 | +#define BIGCHUNK (512 * 1024) | |
| 771 | +#endif | |
| 772 | + | |
| 773 | +static size_t | |
| 774 | +new_buffersize(PyFileObject *f, size_t currentsize) | |
| 775 | +{ | |
| 776 | +#ifdef HAVE_FSTAT | |
| 777 | + off_t pos, end; | |
| 778 | + struct stat st; | |
| 779 | + if (fstat(fileno(f->f_fp), &st) == 0) { | |
| 780 | + end = st.st_size; | |
| 781 | + /* The following is not a bug: we really need to call lseek() | |
| 782 | + *and* ftell(). The reason is that some stdio libraries | |
| 783 | + mistakenly flush their buffer when ftell() is called and | |
| 784 | + the lseek() call it makes fails, thereby throwing away | |
| 785 | + data that cannot be recovered in any way. To avoid this, | |
| 786 | + we first test lseek(), and only call ftell() if lseek() | |
| 787 | + works. We can't use the lseek() value either, because we | |
| 788 | + need to take the amount of buffered data into account. | |
| 789 | + (Yet another reason why stdio stinks. :-) */ | |
| 790 | + pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR); | |
| 791 | + if (pos >= 0) { | |
| 792 | + pos = ftell(f->f_fp); | |
| 793 | + } | |
| 794 | + if (pos < 0) | |
| 795 | + clearerr(f->f_fp); | |
| 796 | + if (end > pos && pos >= 0) | |
| 797 | + return currentsize + end - pos + 1; | |
| 798 | + /* Add 1 so if the file were to grow we'd notice. */ | |
| 799 | + } | |
| 800 | +#endif | |
| 801 | + if (currentsize > SMALLCHUNK) { | |
| 802 | + /* Keep doubling until we reach BIGCHUNK; | |
| 803 | + then keep adding BIGCHUNK. */ | |
| 804 | + if (currentsize <= BIGCHUNK) | |
| 805 | + return currentsize + currentsize; | |
| 806 | + else | |
| 807 | + return currentsize + BIGCHUNK; | |
| 808 | + } | |
| 809 | + return currentsize + SMALLCHUNK; | |
| 810 | +} | |
| 811 | + | |
| 812 | +#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN | |
| 813 | +#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK || (x) == EAGAIN) | |
| 814 | +#else | |
| 815 | +#ifdef EWOULDBLOCK | |
| 816 | +#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK) | |
| 817 | +#else | |
| 818 | +#ifdef EAGAIN | |
| 819 | +#define BLOCKED_ERRNO(x) ((x) == EAGAIN) | |
| 820 | +#else | |
| 821 | +#define BLOCKED_ERRNO(x) 0 | |
| 822 | +#endif | |
| 823 | +#endif | |
| 824 | +#endif | |
| 825 | + | |
| 826 | +static PyObject * | |
| 827 | +file_read(PyFileObject *f, PyObject *args) | |
| 828 | +{ | |
| 829 | + long bytesrequested = -1; | |
| 830 | + size_t bytesread, buffersize, chunksize; | |
| 831 | + PyObject *v; | |
| 832 | + | |
| 833 | + if (f->f_fp == NULL) | |
| 834 | + return err_closed(); | |
| 835 | + /* refuse to mix with f.next() */ | |
| 836 | + if (f->f_buf != NULL && | |
| 837 | + (f->f_bufend - f->f_bufptr) > 0 && | |
| 838 | + f->f_buf[0] != '\0') | |
| 839 | + return err_iterbuffered(); | |
| 840 | + if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested)) | |
| 841 | + return NULL; | |
| 842 | + if (bytesrequested < 0) | |
| 843 | + buffersize = new_buffersize(f, (size_t)0); | |
| 844 | + else | |
| 845 | + buffersize = bytesrequested; | |
| 846 | + if (buffersize > PY_SSIZE_T_MAX) { | |
| 847 | + PyErr_SetString(PyExc_OverflowError, | |
| 848 | + "requested number of bytes is more than a Python string can hold"); | |
| 849 | + return NULL; | |
| 850 | + } | |
| 851 | + v = PyString_FromStringAndSize((char *)NULL, buffersize); | |
| 852 | + if (v == NULL) | |
| 853 | + return NULL; | |
| 854 | + bytesread = 0; | |
| 855 | + for (;;) { | |
| 856 | + Py_BEGIN_ALLOW_THREADS | |
| 857 | + errno = 0; | |
| 858 | + chunksize = Py_UniversalNewlineFread(BUF(v) + bytesread, | |
| 859 | + buffersize - bytesread, f->f_fp, (PyObject *)f); | |
| 860 | + Py_END_ALLOW_THREADS | |
| 861 | + if (chunksize == 0) { | |
| 862 | + if (!ferror(f->f_fp)) | |
| 863 | + break; | |
| 864 | + clearerr(f->f_fp); | |
| 865 | + /* When in non-blocking mode, data shouldn't | |
| 866 | + * be discarded if a blocking signal was | |
| 867 | + * received. That will also happen if | |
| 868 | + * chunksize != 0, but bytesread < buffersize. */ | |
| 869 | + if (bytesread > 0 && BLOCKED_ERRNO(errno)) | |
| 870 | + break; | |
| 871 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 872 | + Py_DECREF(v); | |
| 873 | + return NULL; | |
| 874 | + } | |
| 875 | + bytesread += chunksize; | |
| 876 | + if (bytesread < buffersize) { | |
| 877 | + clearerr(f->f_fp); | |
| 878 | + break; | |
| 879 | + } | |
| 880 | + if (bytesrequested < 0) { | |
| 881 | + buffersize = new_buffersize(f, buffersize); | |
| 882 | + if (_PyString_Resize(&v, buffersize) < 0) | |
| 883 | + return NULL; | |
| 884 | + } else { | |
| 885 | + /* Got what was requested. */ | |
| 886 | + break; | |
| 887 | + } | |
| 888 | + } | |
| 889 | + if (bytesread != buffersize) | |
| 890 | + _PyString_Resize(&v, bytesread); | |
| 891 | + return v; | |
| 892 | +} | |
| 893 | + | |
| 894 | +static PyObject * | |
| 895 | +file_readinto(PyFileObject *f, PyObject *args) | |
| 896 | +{ | |
| 897 | + char *ptr; | |
| 898 | + Py_ssize_t ntodo; | |
| 899 | + Py_ssize_t ndone, nnow; | |
| 900 | + | |
| 901 | + if (f->f_fp == NULL) | |
| 902 | + return err_closed(); | |
| 903 | + /* refuse to mix with f.next() */ | |
| 904 | + if (f->f_buf != NULL && | |
| 905 | + (f->f_bufend - f->f_bufptr) > 0 && | |
| 906 | + f->f_buf[0] != '\0') | |
| 907 | + return err_iterbuffered(); | |
| 908 | + if (!PyArg_ParseTuple(args, "w#", &ptr, &ntodo)) | |
| 909 | + return NULL; | |
| 910 | + ndone = 0; | |
| 911 | + while (ntodo > 0) { | |
| 912 | + Py_BEGIN_ALLOW_THREADS | |
| 913 | + errno = 0; | |
| 914 | + nnow = Py_UniversalNewlineFread(ptr+ndone, ntodo, f->f_fp, | |
| 915 | + (PyObject *)f); | |
| 916 | + Py_END_ALLOW_THREADS | |
| 917 | + if (nnow == 0) { | |
| 918 | + if (!ferror(f->f_fp)) | |
| 919 | + break; | |
| 920 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 921 | + clearerr(f->f_fp); | |
| 922 | + return NULL; | |
| 923 | + } | |
| 924 | + ndone += nnow; | |
| 925 | + ntodo -= nnow; | |
| 926 | + } | |
| 927 | + return PyInt_FromSsize_t(ndone); | |
| 928 | +} | |
| 929 | + | |
| 930 | +/************************************************************************** | |
| 931 | +Routine to get next line using platform fgets(). | |
| 932 | + | |
| 933 | +Under MSVC 6: | |
| 934 | + | |
| 935 | ++ MS threadsafe getc is very slow (multiple layers of function calls before+ | |
| 936 | + after each character, to lock+unlock the stream). | |
| 937 | ++ The stream-locking functions are MS-internal -- can't access them from user | |
| 938 | + code. | |
| 939 | ++ There's nothing Tim could find in the MS C or platform SDK libraries that | |
| 940 | + can worm around this. | |
| 941 | ++ MS fgets locks/unlocks only once per line; it's the only hook we have. | |
| 942 | + | |
| 943 | +So we use fgets for speed(!), despite that it's painful. | |
| 944 | + | |
| 945 | +MS realloc is also slow. | |
| 946 | + | |
| 947 | +Reports from other platforms on this method vs getc_unlocked (which MS doesn't | |
| 948 | +have): | |
| 949 | + Linux a wash | |
| 950 | + Solaris a wash | |
| 951 | + Tru64 Unix getline_via_fgets significantly faster | |
| 952 | + | |
| 953 | +CAUTION: The C std isn't clear about this: in those cases where fgets | |
| 954 | +writes something into the buffer, can it write into any position beyond the | |
| 955 | +required trailing null byte? MSVC 6 fgets does not, and no platform is (yet) | |
| 956 | +known on which it does; and it would be a strange way to code fgets. Still, | |
| 957 | +getline_via_fgets may not work correctly if it does. The std test | |
| 958 | +test_bufio.py should fail if platform fgets() routinely writes beyond the | |
| 959 | +trailing null byte. #define DONT_USE_FGETS_IN_GETLINE to disable this code. | |
| 960 | +**************************************************************************/ | |
| 961 | + | |
| 962 | +/* Use this routine if told to, or by default on non-get_unlocked() | |
| 963 | + * platforms unless told not to. Yikes! Let's spell that out: | |
| 964 | + * On a platform with getc_unlocked(): | |
| 965 | + * By default, use getc_unlocked(). | |
| 966 | + * If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE. | |
| 967 | + * On a platform without getc_unlocked(): | |
| 968 | + * By default, use fgets(). | |
| 969 | + * If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE. | |
| 970 | + */ | |
| 971 | +#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED) | |
| 972 | +#define USE_FGETS_IN_GETLINE | |
| 973 | +#endif | |
| 974 | + | |
| 975 | +#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE) | |
| 976 | +#undef USE_FGETS_IN_GETLINE | |
| 977 | +#endif | |
| 978 | + | |
| 979 | +#ifdef USE_FGETS_IN_GETLINE | |
| 980 | +static PyObject* | |
| 981 | +getline_via_fgets(FILE *fp) | |
| 982 | +{ | |
| 983 | +/* INITBUFSIZE is the maximum line length that lets us get away with the fast | |
| 984 | + * no-realloc, one-fgets()-call path. Boosting it isn't free, because we have | |
| 985 | + * to fill this much of the buffer with a known value in order to figure out | |
| 986 | + * how much of the buffer fgets() overwrites. So if INITBUFSIZE is larger | |
| 987 | + * than "most" lines, we waste time filling unused buffer slots. 100 is | |
| 988 | + * surely adequate for most peoples' email archives, chewing over source code, | |
| 989 | + * etc -- "regular old text files". | |
| 990 | + * MAXBUFSIZE is the maximum line length that lets us get away with the less | |
| 991 | + * fast (but still zippy) no-realloc, two-fgets()-call path. See above for | |
| 992 | + * cautions about boosting that. 300 was chosen because the worst real-life | |
| 993 | + * text-crunching job reported on Python-Dev was a mail-log crawler where over | |
| 994 | + * half the lines were 254 chars. | |
| 995 | + */ | |
| 996 | +#define INITBUFSIZE 100 | |
| 997 | +#define MAXBUFSIZE 300 | |
| 998 | + char* p; /* temp */ | |
| 999 | + char buf[MAXBUFSIZE]; | |
| 1000 | + PyObject* v; /* the string object result */ | |
| 1001 | + char* pvfree; /* address of next free slot */ | |
| 1002 | + char* pvend; /* address one beyond last free slot */ | |
| 1003 | + size_t nfree; /* # of free buffer slots; pvend-pvfree */ | |
| 1004 | + size_t total_v_size; /* total # of slots in buffer */ | |
| 1005 | + size_t increment; /* amount to increment the buffer */ | |
| 1006 | + size_t prev_v_size; | |
| 1007 | + | |
| 1008 | + /* Optimize for normal case: avoid _PyString_Resize if at all | |
| 1009 | + * possible via first reading into stack buffer "buf". | |
| 1010 | + */ | |
| 1011 | + total_v_size = INITBUFSIZE; /* start small and pray */ | |
| 1012 | + pvfree = buf; | |
| 1013 | + for (;;) { | |
| 1014 | + Py_BEGIN_ALLOW_THREADS | |
| 1015 | + pvend = buf + total_v_size; | |
| 1016 | + nfree = pvend - pvfree; | |
| 1017 | + memset(pvfree, '\n', nfree); | |
| 1018 | + assert(nfree < INT_MAX); /* Should be atmost MAXBUFSIZE */ | |
| 1019 | + p = fgets(pvfree, (int)nfree, fp); | |
| 1020 | + Py_END_ALLOW_THREADS | |
| 1021 | + | |
| 1022 | + if (p == NULL) { | |
| 1023 | + clearerr(fp); | |
| 1024 | + if (PyErr_CheckSignals()) | |
| 1025 | + return NULL; | |
| 1026 | + v = PyString_FromStringAndSize(buf, pvfree - buf); | |
| 1027 | + return v; | |
| 1028 | + } | |
| 1029 | + /* fgets read *something* */ | |
| 1030 | + p = memchr(pvfree, '\n', nfree); | |
| 1031 | + if (p != NULL) { | |
| 1032 | + /* Did the \n come from fgets or from us? | |
| 1033 | + * Since fgets stops at the first \n, and then writes | |
| 1034 | + * \0, if it's from fgets a \0 must be next. But if | |
| 1035 | + * that's so, it could not have come from us, since | |
| 1036 | + * the \n's we filled the buffer with have only more | |
| 1037 | + * \n's to the right. | |
| 1038 | + */ | |
| 1039 | + if (p+1 < pvend && *(p+1) == '\0') { | |
| 1040 | + /* It's from fgets: we win! In particular, | |
| 1041 | + * we haven't done any mallocs yet, and can | |
| 1042 | + * build the final result on the first try. | |
| 1043 | + */ | |
| 1044 | + ++p; /* include \n from fgets */ | |
| 1045 | + } | |
| 1046 | + else { | |
| 1047 | + /* Must be from us: fgets didn't fill the | |
| 1048 | + * buffer and didn't find a newline, so it | |
| 1049 | + * must be the last and newline-free line of | |
| 1050 | + * the file. | |
| 1051 | + */ | |
| 1052 | + assert(p > pvfree && *(p-1) == '\0'); | |
| 1053 | + --p; /* don't include \0 from fgets */ | |
| 1054 | + } | |
| 1055 | + v = PyString_FromStringAndSize(buf, p - buf); | |
| 1056 | + return v; | |
| 1057 | + } | |
| 1058 | + /* yuck: fgets overwrote all the newlines, i.e. the entire | |
| 1059 | + * buffer. So this line isn't over yet, or maybe it is but | |
| 1060 | + * we're exactly at EOF. If we haven't already, try using the | |
| 1061 | + * rest of the stack buffer. | |
| 1062 | + */ | |
| 1063 | + assert(*(pvend-1) == '\0'); | |
| 1064 | + if (pvfree == buf) { | |
| 1065 | + pvfree = pvend - 1; /* overwrite trailing null */ | |
| 1066 | + total_v_size = MAXBUFSIZE; | |
| 1067 | + } | |
| 1068 | + else | |
| 1069 | + break; | |
| 1070 | + } | |
| 1071 | + | |
| 1072 | + /* The stack buffer isn't big enough; malloc a string object and read | |
| 1073 | + * into its buffer. | |
| 1074 | + */ | |
| 1075 | + total_v_size = MAXBUFSIZE << 1; | |
| 1076 | + v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size); | |
| 1077 | + if (v == NULL) | |
| 1078 | + return v; | |
| 1079 | + /* copy over everything except the last null byte */ | |
| 1080 | + memcpy(BUF(v), buf, MAXBUFSIZE-1); | |
| 1081 | + pvfree = BUF(v) + MAXBUFSIZE - 1; | |
| 1082 | + | |
| 1083 | + /* Keep reading stuff into v; if it ever ends successfully, break | |
| 1084 | + * after setting p one beyond the end of the line. The code here is | |
| 1085 | + * very much like the code above, except reads into v's buffer; see | |
| 1086 | + * the code above for detailed comments about the logic. | |
| 1087 | + */ | |
| 1088 | + for (;;) { | |
| 1089 | + Py_BEGIN_ALLOW_THREADS | |
| 1090 | + pvend = BUF(v) + total_v_size; | |
| 1091 | + nfree = pvend - pvfree; | |
| 1092 | + memset(pvfree, '\n', nfree); | |
| 1093 | + assert(nfree < INT_MAX); | |
| 1094 | + p = fgets(pvfree, (int)nfree, fp); | |
| 1095 | + Py_END_ALLOW_THREADS | |
| 1096 | + | |
| 1097 | + if (p == NULL) { | |
| 1098 | + clearerr(fp); | |
| 1099 | + if (PyErr_CheckSignals()) { | |
| 1100 | + Py_DECREF(v); | |
| 1101 | + return NULL; | |
| 1102 | + } | |
| 1103 | + p = pvfree; | |
| 1104 | + break; | |
| 1105 | + } | |
| 1106 | + p = memchr(pvfree, '\n', nfree); | |
| 1107 | + if (p != NULL) { | |
| 1108 | + if (p+1 < pvend && *(p+1) == '\0') { | |
| 1109 | + /* \n came from fgets */ | |
| 1110 | + ++p; | |
| 1111 | + break; | |
| 1112 | + } | |
| 1113 | + /* \n came from us; last line of file, no newline */ | |
| 1114 | + assert(p > pvfree && *(p-1) == '\0'); | |
| 1115 | + --p; | |
| 1116 | + break; | |
| 1117 | + } | |
| 1118 | + /* expand buffer and try again */ | |
| 1119 | + assert(*(pvend-1) == '\0'); | |
| 1120 | + increment = total_v_size >> 2; /* mild exponential growth */ | |
| 1121 | + prev_v_size = total_v_size; | |
| 1122 | + total_v_size += increment; | |
| 1123 | + /* check for overflow */ | |
| 1124 | + if (total_v_size <= prev_v_size || | |
| 1125 | + total_v_size > PY_SSIZE_T_MAX) { | |
| 1126 | + PyErr_SetString(PyExc_OverflowError, | |
| 1127 | + "line is longer than a Python string can hold"); | |
| 1128 | + Py_DECREF(v); | |
| 1129 | + return NULL; | |
| 1130 | + } | |
| 1131 | + if (_PyString_Resize(&v, (int)total_v_size) < 0) | |
| 1132 | + return NULL; | |
| 1133 | + /* overwrite the trailing null byte */ | |
| 1134 | + pvfree = BUF(v) + (prev_v_size - 1); | |
| 1135 | + } | |
| 1136 | + if (BUF(v) + total_v_size != p) | |
| 1137 | + _PyString_Resize(&v, p - BUF(v)); | |
| 1138 | + return v; | |
| 1139 | +#undef INITBUFSIZE | |
| 1140 | +#undef MAXBUFSIZE | |
| 1141 | +} | |
| 1142 | +#endif /* ifdef USE_FGETS_IN_GETLINE */ | |
| 1143 | + | |
| 1144 | +/* Internal routine to get a line. | |
| 1145 | + Size argument interpretation: | |
| 1146 | + > 0: max length; | |
| 1147 | + <= 0: read arbitrary line | |
| 1148 | +*/ | |
| 1149 | + | |
| 1150 | +static PyObject * | |
| 1151 | +get_line(PyFileObject *f, int n) | |
| 1152 | +{ | |
| 1153 | + FILE *fp = f->f_fp; | |
| 1154 | + int c; | |
| 1155 | + char *buf, *end; | |
| 1156 | + size_t total_v_size; /* total # of slots in buffer */ | |
| 1157 | + size_t used_v_size; /* # used slots in buffer */ | |
| 1158 | + size_t increment; /* amount to increment the buffer */ | |
| 1159 | + PyObject *v; | |
| 1160 | + int newlinetypes = f->f_newlinetypes; | |
| 1161 | + int skipnextlf = f->f_skipnextlf; | |
| 1162 | + int univ_newline = f->f_univ_newline; | |
| 1163 | + | |
| 1164 | +#if defined(USE_FGETS_IN_GETLINE) | |
| 1165 | + if (n <= 0 && !univ_newline ) | |
| 1166 | + return getline_via_fgets(fp); | |
| 1167 | +#endif | |
| 1168 | + total_v_size = n > 0 ? n : 100; | |
| 1169 | + v = PyString_FromStringAndSize((char *)NULL, total_v_size); | |
| 1170 | + if (v == NULL) | |
| 1171 | + return NULL; | |
| 1172 | + buf = BUF(v); | |
| 1173 | + end = buf + total_v_size; | |
| 1174 | + | |
| 1175 | + for (;;) { | |
| 1176 | + Py_BEGIN_ALLOW_THREADS | |
| 1177 | + FLOCKFILE(fp); | |
| 1178 | + if (univ_newline) { | |
| 1179 | + c = 'x'; /* Shut up gcc warning */ | |
| 1180 | + while ( buf != end && (c = GETC(fp)) != EOF ) { | |
| 1181 | + if (skipnextlf ) { | |
| 1182 | + skipnextlf = 0; | |
| 1183 | + if (c == '\n') { | |
| 1184 | + /* Seeing a \n here with | |
| 1185 | + * skipnextlf true means we | |
| 1186 | + * saw a \r before. | |
| 1187 | + */ | |
| 1188 | + newlinetypes |= NEWLINE_CRLF; | |
| 1189 | + c = GETC(fp); | |
| 1190 | + if (c == EOF) break; | |
| 1191 | + } else { | |
| 1192 | + newlinetypes |= NEWLINE_CR; | |
| 1193 | + } | |
| 1194 | + } | |
| 1195 | + if (c == '\r') { | |
| 1196 | + skipnextlf = 1; | |
| 1197 | + c = '\n'; | |
| 1198 | + } else if ( c == '\n') | |
| 1199 | + newlinetypes |= NEWLINE_LF; | |
| 1200 | + *buf++ = c; | |
| 1201 | + if (c == '\n') break; | |
| 1202 | + } | |
| 1203 | + if ( c == EOF && skipnextlf ) | |
| 1204 | + newlinetypes |= NEWLINE_CR; | |
| 1205 | + } else /* If not universal newlines use the normal loop */ | |
| 1206 | + while ((c = GETC(fp)) != EOF && | |
| 1207 | + (*buf++ = c) != '\n' && | |
| 1208 | + buf != end) | |
| 1209 | + ; | |
| 1210 | + FUNLOCKFILE(fp); | |
| 1211 | + Py_END_ALLOW_THREADS | |
| 1212 | + f->f_newlinetypes = newlinetypes; | |
| 1213 | + f->f_skipnextlf = skipnextlf; | |
| 1214 | + if (c == '\n') | |
| 1215 | + break; | |
| 1216 | + if (c == EOF) { | |
| 1217 | + if (ferror(fp)) { | |
| 1218 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 1219 | + clearerr(fp); | |
| 1220 | + Py_DECREF(v); | |
| 1221 | + return NULL; | |
| 1222 | + } | |
| 1223 | + clearerr(fp); | |
| 1224 | + if (PyErr_CheckSignals()) { | |
| 1225 | + Py_DECREF(v); | |
| 1226 | + return NULL; | |
| 1227 | + } | |
| 1228 | + break; | |
| 1229 | + } | |
| 1230 | + /* Must be because buf == end */ | |
| 1231 | + if (n > 0) | |
| 1232 | + break; | |
| 1233 | + used_v_size = total_v_size; | |
| 1234 | + increment = total_v_size >> 2; /* mild exponential growth */ | |
| 1235 | + total_v_size += increment; | |
| 1236 | + if (total_v_size > PY_SSIZE_T_MAX) { | |
| 1237 | + PyErr_SetString(PyExc_OverflowError, | |
| 1238 | + "line is longer than a Python string can hold"); | |
| 1239 | + Py_DECREF(v); | |
| 1240 | + return NULL; | |
| 1241 | + } | |
| 1242 | + if (_PyString_Resize(&v, total_v_size) < 0) | |
| 1243 | + return NULL; | |
| 1244 | + buf = BUF(v) + used_v_size; | |
| 1245 | + end = BUF(v) + total_v_size; | |
| 1246 | + } | |
| 1247 | + | |
| 1248 | + used_v_size = buf - BUF(v); | |
| 1249 | + if (used_v_size != total_v_size) | |
| 1250 | + _PyString_Resize(&v, used_v_size); | |
| 1251 | + return v; | |
| 1252 | +} | |
| 1253 | + | |
| 1254 | +/* External C interface */ | |
| 1255 | + | |
| 1256 | +PyObject * | |
| 1257 | +PyFile_GetLine(PyObject *f, int n) | |
| 1258 | +{ | |
| 1259 | + PyObject *result; | |
| 1260 | + | |
| 1261 | + if (f == NULL) { | |
| 1262 | + PyErr_BadInternalCall(); | |
| 1263 | + return NULL; | |
| 1264 | + } | |
| 1265 | + | |
| 1266 | + if (PyFile_Check(f)) { | |
| 1267 | + PyFileObject *fo = (PyFileObject *)f; | |
| 1268 | + if (fo->f_fp == NULL) | |
| 1269 | + return err_closed(); | |
| 1270 | + /* refuse to mix with f.next() */ | |
| 1271 | + if (fo->f_buf != NULL && | |
| 1272 | + (fo->f_bufend - fo->f_bufptr) > 0 && | |
| 1273 | + fo->f_buf[0] != '\0') | |
| 1274 | + return err_iterbuffered(); | |
| 1275 | + result = get_line(fo, n); | |
| 1276 | + } | |
| 1277 | + else { | |
| 1278 | + PyObject *reader; | |
| 1279 | + PyObject *args; | |
| 1280 | + | |
| 1281 | + reader = PyObject_GetAttrString(f, "readline"); | |
| 1282 | + if (reader == NULL) | |
| 1283 | + return NULL; | |
| 1284 | + if (n <= 0) | |
| 1285 | + args = PyTuple_New(0); | |
| 1286 | + else | |
| 1287 | + args = Py_BuildValue("(i)", n); | |
| 1288 | + if (args == NULL) { | |
| 1289 | + Py_DECREF(reader); | |
| 1290 | + return NULL; | |
| 1291 | + } | |
| 1292 | + result = PyEval_CallObject(reader, args); | |
| 1293 | + Py_DECREF(reader); | |
| 1294 | + Py_DECREF(args); | |
| 1295 | + if (result != NULL && !PyString_Check(result) && | |
| 1296 | + !PyUnicode_Check(result)) { | |
| 1297 | + Py_DECREF(result); | |
| 1298 | + result = NULL; | |
| 1299 | + PyErr_SetString(PyExc_TypeError, | |
| 1300 | + "object.readline() returned non-string"); | |
| 1301 | + } | |
| 1302 | + } | |
| 1303 | + | |
| 1304 | + if (n < 0 && result != NULL && PyString_Check(result)) { | |
| 1305 | + char *s = PyString_AS_STRING(result); | |
| 1306 | + Py_ssize_t len = PyString_GET_SIZE(result); | |
| 1307 | + if (len == 0) { | |
| 1308 | + Py_DECREF(result); | |
| 1309 | + result = NULL; | |
| 1310 | + PyErr_SetString(PyExc_EOFError, | |
| 1311 | + "EOF when reading a line"); | |
| 1312 | + } | |
| 1313 | + else if (s[len-1] == '\n') { | |
| 1314 | + if (result->ob_refcnt == 1) | |
| 1315 | + _PyString_Resize(&result, len-1); | |
| 1316 | + else { | |
| 1317 | + PyObject *v; | |
| 1318 | + v = PyString_FromStringAndSize(s, len-1); | |
| 1319 | + Py_DECREF(result); | |
| 1320 | + result = v; | |
| 1321 | + } | |
| 1322 | + } | |
| 1323 | + } | |
| 1324 | +#ifdef Py_USING_UNICODE | |
| 1325 | + if (n < 0 && result != NULL && PyUnicode_Check(result)) { | |
| 1326 | + Py_UNICODE *s = PyUnicode_AS_UNICODE(result); | |
| 1327 | + Py_ssize_t len = PyUnicode_GET_SIZE(result); | |
| 1328 | + if (len == 0) { | |
| 1329 | + Py_DECREF(result); | |
| 1330 | + result = NULL; | |
| 1331 | + PyErr_SetString(PyExc_EOFError, | |
| 1332 | + "EOF when reading a line"); | |
| 1333 | + } | |
| 1334 | + else if (s[len-1] == '\n') { | |
| 1335 | + if (result->ob_refcnt == 1) | |
| 1336 | + PyUnicode_Resize(&result, len-1); | |
| 1337 | + else { | |
| 1338 | + PyObject *v; | |
| 1339 | + v = PyUnicode_FromUnicode(s, len-1); | |
| 1340 | + Py_DECREF(result); | |
| 1341 | + result = v; | |
| 1342 | + } | |
| 1343 | + } | |
| 1344 | + } | |
| 1345 | +#endif | |
| 1346 | + return result; | |
| 1347 | +} | |
| 1348 | + | |
| 1349 | +/* Python method */ | |
| 1350 | + | |
| 1351 | +static PyObject * | |
| 1352 | +file_readline(PyFileObject *f, PyObject *args) | |
| 1353 | +{ | |
| 1354 | + int n = -1; | |
| 1355 | + | |
| 1356 | + if (f->f_fp == NULL) | |
| 1357 | + return err_closed(); | |
| 1358 | + /* refuse to mix with f.next() */ | |
| 1359 | + if (f->f_buf != NULL && | |
| 1360 | + (f->f_bufend - f->f_bufptr) > 0 && | |
| 1361 | + f->f_buf[0] != '\0') | |
| 1362 | + return err_iterbuffered(); | |
| 1363 | + if (!PyArg_ParseTuple(args, "|i:readline", &n)) | |
| 1364 | + return NULL; | |
| 1365 | + if (n == 0) | |
| 1366 | + return PyString_FromString(""); | |
| 1367 | + if (n < 0) | |
| 1368 | + n = 0; | |
| 1369 | + return get_line(f, n); | |
| 1370 | +} | |
| 1371 | + | |
| 1372 | +static PyObject * | |
| 1373 | +file_readlines(PyFileObject *f, PyObject *args) | |
| 1374 | +{ | |
| 1375 | + long sizehint = 0; | |
| 1376 | + PyObject *list; | |
| 1377 | + PyObject *line; | |
| 1378 | + char small_buffer[SMALLCHUNK]; | |
| 1379 | + char *buffer = small_buffer; | |
| 1380 | + size_t buffersize = SMALLCHUNK; | |
| 1381 | + PyObject *big_buffer = NULL; | |
| 1382 | + size_t nfilled = 0; | |
| 1383 | + size_t nread; | |
| 1384 | + size_t totalread = 0; | |
| 1385 | + char *p, *q, *end; | |
| 1386 | + int err; | |
| 1387 | + int shortread = 0; | |
| 1388 | + | |
| 1389 | + if (f->f_fp == NULL) | |
| 1390 | + return err_closed(); | |
| 1391 | + /* refuse to mix with f.next() */ | |
| 1392 | + if (f->f_buf != NULL && | |
| 1393 | + (f->f_bufend - f->f_bufptr) > 0 && | |
| 1394 | + f->f_buf[0] != '\0') | |
| 1395 | + return err_iterbuffered(); | |
| 1396 | + if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint)) | |
| 1397 | + return NULL; | |
| 1398 | + if ((list = PyList_New(0)) == NULL) | |
| 1399 | + return NULL; | |
| 1400 | + for (;;) { | |
| 1401 | + if (shortread) | |
| 1402 | + nread = 0; | |
| 1403 | + else { | |
| 1404 | + Py_BEGIN_ALLOW_THREADS | |
| 1405 | + errno = 0; | |
| 1406 | + nread = Py_UniversalNewlineFread(buffer+nfilled, | |
| 1407 | + buffersize-nfilled, f->f_fp, (PyObject *)f); | |
| 1408 | + Py_END_ALLOW_THREADS | |
| 1409 | + shortread = (nread < buffersize-nfilled); | |
| 1410 | + } | |
| 1411 | + if (nread == 0) { | |
| 1412 | + sizehint = 0; | |
| 1413 | + if (!ferror(f->f_fp)) | |
| 1414 | + break; | |
| 1415 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 1416 | + clearerr(f->f_fp); | |
| 1417 | + error: | |
| 1418 | + Py_DECREF(list); | |
| 1419 | + list = NULL; | |
| 1420 | + goto cleanup; | |
| 1421 | + } | |
| 1422 | + totalread += nread; | |
| 1423 | + p = (char *)memchr(buffer+nfilled, '\n', nread); | |
| 1424 | + if (p == NULL) { | |
| 1425 | + /* Need a larger buffer to fit this line */ | |
| 1426 | + nfilled += nread; | |
| 1427 | + buffersize *= 2; | |
| 1428 | + if (buffersize > PY_SSIZE_T_MAX) { | |
| 1429 | + PyErr_SetString(PyExc_OverflowError, | |
| 1430 | + "line is longer than a Python string can hold"); | |
| 1431 | + goto error; | |
| 1432 | + } | |
| 1433 | + if (big_buffer == NULL) { | |
| 1434 | + /* Create the big buffer */ | |
| 1435 | + big_buffer = PyString_FromStringAndSize( | |
| 1436 | + NULL, buffersize); | |
| 1437 | + if (big_buffer == NULL) | |
| 1438 | + goto error; | |
| 1439 | + buffer = PyString_AS_STRING(big_buffer); | |
| 1440 | + memcpy(buffer, small_buffer, nfilled); | |
| 1441 | + } | |
| 1442 | + else { | |
| 1443 | + /* Grow the big buffer */ | |
| 1444 | + if ( _PyString_Resize(&big_buffer, buffersize) < 0 ) | |
| 1445 | + goto error; | |
| 1446 | + buffer = PyString_AS_STRING(big_buffer); | |
| 1447 | + } | |
| 1448 | + continue; | |
| 1449 | + } | |
| 1450 | + end = buffer+nfilled+nread; | |
| 1451 | + q = buffer; | |
| 1452 | + do { | |
| 1453 | + /* Process complete lines */ | |
| 1454 | + p++; | |
| 1455 | + line = PyString_FromStringAndSize(q, p-q); | |
| 1456 | + if (line == NULL) | |
| 1457 | + goto error; | |
| 1458 | + err = PyList_Append(list, line); | |
| 1459 | + Py_DECREF(line); | |
| 1460 | + if (err != 0) | |
| 1461 | + goto error; | |
| 1462 | + q = p; | |
| 1463 | + p = (char *)memchr(q, '\n', end-q); | |
| 1464 | + } while (p != NULL); | |
| 1465 | + /* Move the remaining incomplete line to the start */ | |
| 1466 | + nfilled = end-q; | |
| 1467 | + memmove(buffer, q, nfilled); | |
| 1468 | + if (sizehint > 0) | |
| 1469 | + if (totalread >= (size_t)sizehint) | |
| 1470 | + break; | |
| 1471 | + } | |
| 1472 | + if (nfilled != 0) { | |
| 1473 | + /* Partial last line */ | |
| 1474 | + line = PyString_FromStringAndSize(buffer, nfilled); | |
| 1475 | + if (line == NULL) | |
| 1476 | + goto error; | |
| 1477 | + if (sizehint > 0) { | |
| 1478 | + /* Need to complete the last line */ | |
| 1479 | + PyObject *rest = get_line(f, 0); | |
| 1480 | + if (rest == NULL) { | |
| 1481 | + Py_DECREF(line); | |
| 1482 | + goto error; | |
| 1483 | + } | |
| 1484 | + PyString_Concat(&line, rest); | |
| 1485 | + Py_DECREF(rest); | |
| 1486 | + if (line == NULL) | |
| 1487 | + goto error; | |
| 1488 | + } | |
| 1489 | + err = PyList_Append(list, line); | |
| 1490 | + Py_DECREF(line); | |
| 1491 | + if (err != 0) | |
| 1492 | + goto error; | |
| 1493 | + } | |
| 1494 | + cleanup: | |
| 1495 | + Py_XDECREF(big_buffer); | |
| 1496 | + return list; | |
| 1497 | +} | |
| 1498 | + | |
| 1499 | +static PyObject * | |
| 1500 | +file_write(PyFileObject *f, PyObject *args) | |
| 1501 | +{ | |
| 1502 | + char *s; | |
| 1503 | + Py_ssize_t n, n2; | |
| 1504 | + if (f->f_fp == NULL) | |
| 1505 | + return err_closed(); | |
| 1506 | + if (!PyArg_ParseTuple(args, f->f_binary ? "s#" : "t#", &s, &n)) | |
| 1507 | + return NULL; | |
| 1508 | + f->f_softspace = 0; | |
| 1509 | + Py_BEGIN_ALLOW_THREADS | |
| 1510 | + errno = 0; | |
| 1511 | + n2 = fwrite(s, 1, n, f->f_fp); | |
| 1512 | + Py_END_ALLOW_THREADS | |
| 1513 | + if (n2 != n) { | |
| 1514 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 1515 | + clearerr(f->f_fp); | |
| 1516 | + return NULL; | |
| 1517 | + } | |
| 1518 | + Py_INCREF(Py_None); | |
| 1519 | + return Py_None; | |
| 1520 | +} | |
| 1521 | + | |
| 1522 | +static PyObject * | |
| 1523 | +file_writelines(PyFileObject *f, PyObject *seq) | |
| 1524 | +{ | |
| 1525 | +#define CHUNKSIZE 1000 | |
| 1526 | + PyObject *list, *line; | |
| 1527 | + PyObject *it; /* iter(seq) */ | |
| 1528 | + PyObject *result; | |
| 1529 | + int index, islist; | |
| 1530 | + Py_ssize_t i, j, nwritten, len; | |
| 1531 | + | |
| 1532 | + assert(seq != NULL); | |
| 1533 | + if (f->f_fp == NULL) | |
| 1534 | + return err_closed(); | |
| 1535 | + | |
| 1536 | + result = NULL; | |
| 1537 | + list = NULL; | |
| 1538 | + islist = PyList_Check(seq); | |
| 1539 | + if (islist) | |
| 1540 | + it = NULL; | |
| 1541 | + else { | |
| 1542 | + it = PyObject_GetIter(seq); | |
| 1543 | + if (it == NULL) { | |
| 1544 | + PyErr_SetString(PyExc_TypeError, | |
| 1545 | + "writelines() requires an iterable argument"); | |
| 1546 | + return NULL; | |
| 1547 | + } | |
| 1548 | + /* From here on, fail by going to error, to reclaim "it". */ | |
| 1549 | + list = PyList_New(CHUNKSIZE); | |
| 1550 | + if (list == NULL) | |
| 1551 | + goto error; | |
| 1552 | + } | |
| 1553 | + | |
| 1554 | + /* Strategy: slurp CHUNKSIZE lines into a private list, | |
| 1555 | + checking that they are all strings, then write that list | |
| 1556 | + without holding the interpreter lock, then come back for more. */ | |
| 1557 | + for (index = 0; ; index += CHUNKSIZE) { | |
| 1558 | + if (islist) { | |
| 1559 | + Py_XDECREF(list); | |
| 1560 | + list = PyList_GetSlice(seq, index, index+CHUNKSIZE); | |
| 1561 | + if (list == NULL) | |
| 1562 | + goto error; | |
| 1563 | + j = PyList_GET_SIZE(list); | |
| 1564 | + } | |
| 1565 | + else { | |
| 1566 | + for (j = 0; j < CHUNKSIZE; j++) { | |
| 1567 | + line = PyIter_Next(it); | |
| 1568 | + if (line == NULL) { | |
| 1569 | + if (PyErr_Occurred()) | |
| 1570 | + goto error; | |
| 1571 | + break; | |
| 1572 | + } | |
| 1573 | + PyList_SetItem(list, j, line); | |
| 1574 | + } | |
| 1575 | + } | |
| 1576 | + if (j == 0) | |
| 1577 | + break; | |
| 1578 | + | |
| 1579 | + /* Check that all entries are indeed strings. If not, | |
| 1580 | + apply the same rules as for file.write() and | |
| 1581 | + convert the results to strings. This is slow, but | |
| 1582 | + seems to be the only way since all conversion APIs | |
| 1583 | + could potentially execute Python code. */ | |
| 1584 | + for (i = 0; i < j; i++) { | |
| 1585 | + PyObject *v = PyList_GET_ITEM(list, i); | |
| 1586 | + if (!PyString_Check(v)) { | |
| 1587 | + const char *buffer; | |
| 1588 | + if (((f->f_binary && | |
| 1589 | + PyObject_AsReadBuffer(v, | |
| 1590 | + (const void**)&buffer, | |
| 1591 | + &len)) || | |
| 1592 | + PyObject_AsCharBuffer(v, | |
| 1593 | + &buffer, | |
| 1594 | + &len))) { | |
| 1595 | + PyErr_SetString(PyExc_TypeError, | |
| 1596 | + "writelines() argument must be a sequence of strings"); | |
| 1597 | + goto error; | |
| 1598 | + } | |
| 1599 | + line = PyString_FromStringAndSize(buffer, | |
| 1600 | + len); | |
| 1601 | + if (line == NULL) | |
| 1602 | + goto error; | |
| 1603 | + Py_DECREF(v); | |
| 1604 | + PyList_SET_ITEM(list, i, line); | |
| 1605 | + } | |
| 1606 | + } | |
| 1607 | + | |
| 1608 | + /* Since we are releasing the global lock, the | |
| 1609 | + following code may *not* execute Python code. */ | |
| 1610 | + Py_BEGIN_ALLOW_THREADS | |
| 1611 | + f->f_softspace = 0; | |
| 1612 | + errno = 0; | |
| 1613 | + for (i = 0; i < j; i++) { | |
| 1614 | + line = PyList_GET_ITEM(list, i); | |
| 1615 | + len = PyString_GET_SIZE(line); | |
| 1616 | + nwritten = fwrite(PyString_AS_STRING(line), | |
| 1617 | + 1, len, f->f_fp); | |
| 1618 | + if (nwritten != len) { | |
| 1619 | + Py_BLOCK_THREADS | |
| 1620 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 1621 | + clearerr(f->f_fp); | |
| 1622 | + goto error; | |
| 1623 | + } | |
| 1624 | + } | |
| 1625 | + Py_END_ALLOW_THREADS | |
| 1626 | + | |
| 1627 | + if (j < CHUNKSIZE) | |
| 1628 | + break; | |
| 1629 | + } | |
| 1630 | + | |
| 1631 | + Py_INCREF(Py_None); | |
| 1632 | + result = Py_None; | |
| 1633 | + error: | |
| 1634 | + Py_XDECREF(list); | |
| 1635 | + Py_XDECREF(it); | |
| 1636 | + return result; | |
| 1637 | +#undef CHUNKSIZE | |
| 1638 | +} | |
| 1639 | + | |
| 1640 | +static PyObject * | |
| 1641 | +file_self(PyFileObject *f) | |
| 1642 | +{ | |
| 1643 | + if (f->f_fp == NULL) | |
| 1644 | + return err_closed(); | |
| 1645 | + Py_INCREF(f); | |
| 1646 | + return (PyObject *)f; | |
| 1647 | +} | |
| 1648 | + | |
| 1649 | +static PyObject * | |
| 1650 | +file_exit(PyFileObject *f, PyObject *args) | |
| 1651 | +{ | |
| 1652 | + PyObject *ret = file_close(f); | |
| 1653 | + if (!ret) | |
| 1654 | + /* If error occurred, pass through */ | |
| 1655 | + return NULL; | |
| 1656 | + Py_DECREF(ret); | |
| 1657 | + /* We cannot return the result of close since a true | |
| 1658 | + * value will be interpreted as "yes, swallow the | |
| 1659 | + * exception if one was raised inside the with block". */ | |
| 1660 | + Py_RETURN_NONE; | |
| 1661 | +} | |
| 1662 | + | |
| 1663 | +PyDoc_STRVAR(readline_doc, | |
| 1664 | +"readline([size]) -> next line from the file, as a string.\n" | |
| 1665 | +"\n" | |
| 1666 | +"Retain newline. A non-negative size argument limits the maximum\n" | |
| 1667 | +"number of bytes to return (an incomplete line may be returned then).\n" | |
| 1668 | +"Return an empty string at EOF."); | |
| 1669 | + | |
| 1670 | +PyDoc_STRVAR(read_doc, | |
| 1671 | +"read([size]) -> read at most size bytes, returned as a string.\n" | |
| 1672 | +"\n" | |
| 1673 | +"If the size argument is negative or omitted, read until EOF is reached.\n" | |
| 1674 | +"Notice that when in non-blocking mode, less data than what was requested\n" | |
| 1675 | +"may be returned, even if no size parameter was given."); | |
| 1676 | + | |
| 1677 | +PyDoc_STRVAR(write_doc, | |
| 1678 | +"write(str) -> None. Write string str to file.\n" | |
| 1679 | +"\n" | |
| 1680 | +"Note that due to buffering, flush() or close() may be needed before\n" | |
| 1681 | +"the file on disk reflects the data written."); | |
| 1682 | + | |
| 1683 | +PyDoc_STRVAR(fileno_doc, | |
| 1684 | +"fileno() -> integer \"file descriptor\".\n" | |
| 1685 | +"\n" | |
| 1686 | +"This is needed for lower-level file interfaces, such os.read()."); | |
| 1687 | + | |
| 1688 | +PyDoc_STRVAR(seek_doc, | |
| 1689 | +"seek(offset[, whence]) -> None. Move to new file position.\n" | |
| 1690 | +"\n" | |
| 1691 | +"Argument offset is a byte count. Optional argument whence defaults to\n" | |
| 1692 | +"0 (offset from start of file, offset should be >= 0); other values are 1\n" | |
| 1693 | +"(move relative to current position, positive or negative), and 2 (move\n" | |
| 1694 | +"relative to end of file, usually negative, although many platforms allow\n" | |
| 1695 | +"seeking beyond the end of a file). If the file is opened in text mode,\n" | |
| 1696 | +"only offsets returned by tell() are legal. Use of other offsets causes\n" | |
| 1697 | +"undefined behavior." | |
| 1698 | +"\n" | |
| 1699 | +"Note that not all file objects are seekable."); | |
| 1700 | + | |
| 1701 | +#ifdef HAVE_FTRUNCATE | |
| 1702 | +PyDoc_STRVAR(truncate_doc, | |
| 1703 | +"truncate([size]) -> None. Truncate the file to at most size bytes.\n" | |
| 1704 | +"\n" | |
| 1705 | +"Size defaults to the current file position, as returned by tell()."); | |
| 1706 | +#endif | |
| 1707 | + | |
| 1708 | +PyDoc_STRVAR(tell_doc, | |
| 1709 | +"tell() -> current file position, an integer (may be a long integer)."); | |
| 1710 | + | |
| 1711 | +PyDoc_STRVAR(readinto_doc, | |
| 1712 | +"readinto() -> Undocumented. Don't use this; it may go away."); | |
| 1713 | + | |
| 1714 | +PyDoc_STRVAR(readlines_doc, | |
| 1715 | +"readlines([size]) -> list of strings, each a line from the file.\n" | |
| 1716 | +"\n" | |
| 1717 | +"Call readline() repeatedly and return a list of the lines so read.\n" | |
| 1718 | +"The optional size argument, if given, is an approximate bound on the\n" | |
| 1719 | +"total number of bytes in the lines returned."); | |
| 1720 | + | |
| 1721 | +PyDoc_STRVAR(xreadlines_doc, | |
| 1722 | +"xreadlines() -> returns self.\n" | |
| 1723 | +"\n" | |
| 1724 | +"For backward compatibility. File objects now include the performance\n" | |
| 1725 | +"optimizations previously implemented in the xreadlines module."); | |
| 1726 | + | |
| 1727 | +PyDoc_STRVAR(writelines_doc, | |
| 1728 | +"writelines(sequence_of_strings) -> None. Write the strings to the file.\n" | |
| 1729 | +"\n" | |
| 1730 | +"Note that newlines are not added. The sequence can be any iterable object\n" | |
| 1731 | +"producing strings. This is equivalent to calling write() for each string."); | |
| 1732 | + | |
| 1733 | +PyDoc_STRVAR(flush_doc, | |
| 1734 | +"flush() -> None. Flush the internal I/O buffer."); | |
| 1735 | + | |
| 1736 | +PyDoc_STRVAR(close_doc, | |
| 1737 | +"close() -> None or (perhaps) an integer. Close the file.\n" | |
| 1738 | +"\n" | |
| 1739 | +"Sets data attribute .closed to True. A closed file cannot be used for\n" | |
| 1740 | +"further I/O operations. close() may be called more than once without\n" | |
| 1741 | +"error. Some kinds of file objects (for example, opened by popen())\n" | |
| 1742 | +"may return an exit status upon closing."); | |
| 1743 | + | |
| 1744 | +PyDoc_STRVAR(isatty_doc, | |
| 1745 | +"isatty() -> true or false. True if the file is connected to a tty device."); | |
| 1746 | + | |
| 1747 | +PyDoc_STRVAR(enter_doc, | |
| 1748 | + "__enter__() -> self."); | |
| 1749 | + | |
| 1750 | +PyDoc_STRVAR(exit_doc, | |
| 1751 | + "__exit__(*excinfo) -> None. Closes the file."); | |
| 1752 | + | |
| 1753 | +static PyMethodDef file_methods[] = { | |
| 1754 | + {"readline", (PyCFunction)file_readline, METH_VARARGS, readline_doc}, | |
| 1755 | + {"read", (PyCFunction)file_read, METH_VARARGS, read_doc}, | |
| 1756 | + {"write", (PyCFunction)file_write, METH_VARARGS, write_doc}, | |
| 1757 | + {"fileno", (PyCFunction)file_fileno, METH_NOARGS, fileno_doc}, | |
| 1758 | + {"seek", (PyCFunction)file_seek, METH_VARARGS, seek_doc}, | |
| 1759 | +#ifdef HAVE_FTRUNCATE | |
| 1760 | + {"truncate", (PyCFunction)file_truncate, METH_VARARGS, truncate_doc}, | |
| 1761 | +#endif | |
| 1762 | + {"tell", (PyCFunction)file_tell, METH_NOARGS, tell_doc}, | |
| 1763 | + {"readinto", (PyCFunction)file_readinto, METH_VARARGS, readinto_doc}, | |
| 1764 | + {"readlines", (PyCFunction)file_readlines,METH_VARARGS, readlines_doc}, | |
| 1765 | + {"xreadlines",(PyCFunction)file_self, METH_NOARGS, xreadlines_doc}, | |
| 1766 | + {"writelines",(PyCFunction)file_writelines, METH_O, writelines_doc}, | |
| 1767 | + {"flush", (PyCFunction)file_flush, METH_NOARGS, flush_doc}, | |
| 1768 | + {"close", (PyCFunction)file_close, METH_NOARGS, close_doc}, | |
| 1769 | + {"isatty", (PyCFunction)file_isatty, METH_NOARGS, isatty_doc}, | |
| 1770 | + {"__enter__", (PyCFunction)file_self, METH_NOARGS, enter_doc}, | |
| 1771 | + {"__exit__", (PyCFunction)file_exit, METH_VARARGS, exit_doc}, | |
| 1772 | + {NULL, NULL} /* sentinel */ | |
| 1773 | +}; | |
| 1774 | + | |
| 1775 | +#define OFF(x) offsetof(PyFileObject, x) | |
| 1776 | + | |
| 1777 | +static PyMemberDef file_memberlist[] = { | |
| 1778 | + {"softspace", T_INT, OFF(f_softspace), 0, | |
| 1779 | + "flag indicating that a space needs to be printed; used by print"}, | |
| 1780 | + {"mode", T_OBJECT, OFF(f_mode), RO, | |
| 1781 | + "file mode ('r', 'U', 'w', 'a', possibly with 'b' or '+' added)"}, | |
| 1782 | + {"name", T_OBJECT, OFF(f_name), RO, | |
| 1783 | + "file name"}, | |
| 1784 | + {"encoding", T_OBJECT, OFF(f_encoding), RO, | |
| 1785 | + "file encoding"}, | |
| 1786 | + /* getattr(f, "closed") is implemented without this table */ | |
| 1787 | + {NULL} /* Sentinel */ | |
| 1788 | +}; | |
| 1789 | + | |
| 1790 | +static PyObject * | |
| 1791 | +get_closed(PyFileObject *f, void *closure) | |
| 1792 | +{ | |
| 1793 | + return PyBool_FromLong((long)(f->f_fp == 0)); | |
| 1794 | +} | |
| 1795 | +static PyObject * | |
| 1796 | +get_newlines(PyFileObject *f, void *closure) | |
| 1797 | +{ | |
| 1798 | + switch (f->f_newlinetypes) { | |
| 1799 | + case NEWLINE_UNKNOWN: | |
| 1800 | + Py_INCREF(Py_None); | |
| 1801 | + return Py_None; | |
| 1802 | + case NEWLINE_CR: | |
| 1803 | + return PyString_FromString("\r"); | |
| 1804 | + case NEWLINE_LF: | |
| 1805 | + return PyString_FromString("\n"); | |
| 1806 | + case NEWLINE_CR|NEWLINE_LF: | |
| 1807 | + return Py_BuildValue("(ss)", "\r", "\n"); | |
| 1808 | + case NEWLINE_CRLF: | |
| 1809 | + return PyString_FromString("\r\n"); | |
| 1810 | + case NEWLINE_CR|NEWLINE_CRLF: | |
| 1811 | + return Py_BuildValue("(ss)", "\r", "\r\n"); | |
| 1812 | + case NEWLINE_LF|NEWLINE_CRLF: | |
| 1813 | + return Py_BuildValue("(ss)", "\n", "\r\n"); | |
| 1814 | + case NEWLINE_CR|NEWLINE_LF|NEWLINE_CRLF: | |
| 1815 | + return Py_BuildValue("(sss)", "\r", "\n", "\r\n"); | |
| 1816 | + default: | |
| 1817 | + PyErr_Format(PyExc_SystemError, | |
| 1818 | + "Unknown newlines value 0x%x\n", | |
| 1819 | + f->f_newlinetypes); | |
| 1820 | + return NULL; | |
| 1821 | + } | |
| 1822 | +} | |
| 1823 | + | |
| 1824 | +static PyGetSetDef file_getsetlist[] = { | |
| 1825 | + {"closed", (getter)get_closed, NULL, "True if the file is closed"}, | |
| 1826 | + {"newlines", (getter)get_newlines, NULL, | |
| 1827 | + "end-of-line convention used in this file"}, | |
| 1828 | + {0}, | |
| 1829 | +}; | |
| 1830 | + | |
| 1831 | +static void | |
| 1832 | +drop_readahead(PyFileObject *f) | |
| 1833 | +{ | |
| 1834 | + if (f->f_buf != NULL) { | |
| 1835 | + PyMem_Free(f->f_buf); | |
| 1836 | + f->f_buf = NULL; | |
| 1837 | + } | |
| 1838 | +} | |
| 1839 | + | |
| 1840 | +/* Make sure that file has a readahead buffer with at least one byte | |
| 1841 | + (unless at EOF) and no more than bufsize. Returns negative value on | |
| 1842 | + error, will set MemoryError if bufsize bytes cannot be allocated. */ | |
| 1843 | +static int | |
| 1844 | +readahead(PyFileObject *f, int bufsize) | |
| 1845 | +{ | |
| 1846 | + Py_ssize_t chunksize; | |
| 1847 | + | |
| 1848 | + if (f->f_buf != NULL) { | |
| 1849 | + if( (f->f_bufend - f->f_bufptr) >= 1) | |
| 1850 | + return 0; | |
| 1851 | + else | |
| 1852 | + drop_readahead(f); | |
| 1853 | + } | |
| 1854 | + if ((f->f_buf = (char *)PyMem_Malloc(bufsize)) == NULL) { | |
| 1855 | + PyErr_NoMemory(); | |
| 1856 | + return -1; | |
| 1857 | + } | |
| 1858 | + Py_BEGIN_ALLOW_THREADS | |
| 1859 | + errno = 0; | |
| 1860 | + chunksize = Py_UniversalNewlineFread( | |
| 1861 | + f->f_buf, bufsize, f->f_fp, (PyObject *)f); | |
| 1862 | + Py_END_ALLOW_THREADS | |
| 1863 | + if (chunksize == 0) { | |
| 1864 | + if (ferror(f->f_fp)) { | |
| 1865 | + PyErr_SetFromErrno(PyExc_IOError); | |
| 1866 | + clearerr(f->f_fp); | |
| 1867 | + drop_readahead(f); | |
| 1868 | + return -1; | |
| 1869 | + } | |
| 1870 | + } | |
| 1871 | + f->f_bufptr = f->f_buf; | |
| 1872 | + f->f_bufend = f->f_buf + chunksize; | |
| 1873 | + return 0; | |
| 1874 | +} | |
| 1875 | + | |
| 1876 | +/* Used by file_iternext. The returned string will start with 'skip' | |
| 1877 | + uninitialized bytes followed by the remainder of the line. Don't be | |
| 1878 | + horrified by the recursive call: maximum recursion depth is limited by | |
| 1879 | + logarithmic buffer growth to about 50 even when reading a 1gb line. */ | |
| 1880 | + | |
| 1881 | +static PyStringObject * | |
| 1882 | +readahead_get_line_skip(PyFileObject *f, int skip, int bufsize) | |
| 1883 | +{ | |
| 1884 | + PyStringObject* s; | |
| 1885 | + char *bufptr; | |
| 1886 | + char *buf; | |
| 1887 | + Py_ssize_t len; | |
| 1888 | + | |
| 1889 | + if (f->f_buf == NULL) | |
| 1890 | + if (readahead(f, bufsize) < 0) | |
| 1891 | + return NULL; | |
| 1892 | + | |
| 1893 | + len = f->f_bufend - f->f_bufptr; | |
| 1894 | + if (len == 0) | |
| 1895 | + return (PyStringObject *) | |
| 1896 | + PyString_FromStringAndSize(NULL, skip); | |
| 1897 | + bufptr = (char *)memchr(f->f_bufptr, '\n', len); | |
| 1898 | + if (bufptr != NULL) { | |
| 1899 | + bufptr++; /* Count the '\n' */ | |
| 1900 | + len = bufptr - f->f_bufptr; | |
| 1901 | + s = (PyStringObject *) | |
| 1902 | + PyString_FromStringAndSize(NULL, skip+len); | |
| 1903 | + if (s == NULL) | |
| 1904 | + return NULL; | |
| 1905 | + memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len); | |
| 1906 | + f->f_bufptr = bufptr; | |
| 1907 | + if (bufptr == f->f_bufend) | |
| 1908 | + drop_readahead(f); | |
| 1909 | + } else { | |
| 1910 | + bufptr = f->f_bufptr; | |
| 1911 | + buf = f->f_buf; | |
| 1912 | + f->f_buf = NULL; /* Force new readahead buffer */ | |
| 1913 | + assert(skip+len < INT_MAX); | |
| 1914 | + s = readahead_get_line_skip( | |
| 1915 | + f, (int)(skip+len), bufsize + (bufsize>>2) ); | |
| 1916 | + if (s == NULL) { | |
| 1917 | + PyMem_Free(buf); | |
| 1918 | + return NULL; | |
| 1919 | + } | |
| 1920 | + memcpy(PyString_AS_STRING(s)+skip, bufptr, len); | |
| 1921 | + PyMem_Free(buf); | |
| 1922 | + } | |
| 1923 | + return s; | |
| 1924 | +} | |
| 1925 | + | |
| 1926 | +/* A larger buffer size may actually decrease performance. */ | |
| 1927 | +#define READAHEAD_BUFSIZE 8192 | |
| 1928 | + | |
| 1929 | +static PyObject * | |
| 1930 | +file_iternext(PyFileObject *f) | |
| 1931 | +{ | |
| 1932 | + PyStringObject* l; | |
| 1933 | + | |
| 1934 | + if (f->f_fp == NULL) | |
| 1935 | + return err_closed(); | |
| 1936 | + | |
| 1937 | + l = readahead_get_line_skip(f, 0, READAHEAD_BUFSIZE); | |
| 1938 | + if (l == NULL || PyString_GET_SIZE(l) == 0) { | |
| 1939 | + Py_XDECREF(l); | |
| 1940 | + return NULL; | |
| 1941 | + } | |
| 1942 | + return (PyObject *)l; | |
| 1943 | +} | |
| 1944 | + | |
| 1945 | + | |
| 1946 | +static PyObject * | |
| 1947 | +file_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 1948 | +{ | |
| 1949 | + PyObject *self; | |
| 1950 | + static PyObject *not_yet_string; | |
| 1951 | + | |
| 1952 | + assert(type != NULL && type->tp_alloc != NULL); | |
| 1953 | + | |
| 1954 | + if (not_yet_string == NULL) { | |
| 1955 | + not_yet_string = PyString_FromString("<uninitialized file>"); | |
| 1956 | + if (not_yet_string == NULL) | |
| 1957 | + return NULL; | |
| 1958 | + } | |
| 1959 | + | |
| 1960 | + self = type->tp_alloc(type, 0); | |
| 1961 | + if (self != NULL) { | |
| 1962 | + /* Always fill in the name and mode, so that nobody else | |
| 1963 | + needs to special-case NULLs there. */ | |
| 1964 | + Py_INCREF(not_yet_string); | |
| 1965 | + ((PyFileObject *)self)->f_name = not_yet_string; | |
| 1966 | + Py_INCREF(not_yet_string); | |
| 1967 | + ((PyFileObject *)self)->f_mode = not_yet_string; | |
| 1968 | + Py_INCREF(Py_None); | |
| 1969 | + ((PyFileObject *)self)->f_encoding = Py_None; | |
| 1970 | + ((PyFileObject *)self)->weakreflist = NULL; | |
| 1971 | + } | |
| 1972 | + return self; | |
| 1973 | +} | |
| 1974 | + | |
| 1975 | +static int | |
| 1976 | +file_init(PyObject *self, PyObject *args, PyObject *kwds) | |
| 1977 | +{ | |
| 1978 | + PyFileObject *foself = (PyFileObject *)self; | |
| 1979 | + int ret = 0; | |
| 1980 | + static char *kwlist[] = {"name", "mode", "buffering", 0}; | |
| 1981 | + char *name = NULL; | |
| 1982 | + char *mode = "r"; | |
| 1983 | + int bufsize = -1; | |
| 1984 | + int wideargument = 0; | |
| 1985 | + | |
| 1986 | + assert(PyFile_Check(self)); | |
| 1987 | + if (foself->f_fp != NULL) { | |
| 1988 | + /* Have to close the existing file first. */ | |
| 1989 | + PyObject *closeresult = file_close(foself); | |
| 1990 | + if (closeresult == NULL) | |
| 1991 | + return -1; | |
| 1992 | + Py_DECREF(closeresult); | |
| 1993 | + } | |
| 1994 | + | |
| 1995 | +#ifdef Py_WIN_WIDE_FILENAMES | |
| 1996 | + if (GetVersion() < 0x80000000) { /* On NT, so wide API available */ | |
| 1997 | + PyObject *po; | |
| 1998 | + if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:file", | |
| 1999 | + kwlist, &po, &mode, &bufsize)) { | |
| 2000 | + wideargument = 1; | |
| 2001 | + if (fill_file_fields(foself, NULL, po, mode, | |
| 2002 | + fclose) == NULL) | |
| 2003 | + goto Error; | |
| 2004 | + } else { | |
| 2005 | + /* Drop the argument parsing error as narrow | |
| 2006 | + strings are also valid. */ | |
| 2007 | + PyErr_Clear(); | |
| 2008 | + } | |
| 2009 | + } | |
| 2010 | +#endif | |
| 2011 | + | |
| 2012 | + if (!wideargument) { | |
| 2013 | + PyObject *o_name; | |
| 2014 | + | |
| 2015 | + if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist, | |
| 2016 | + Py_FileSystemDefaultEncoding, | |
| 2017 | + &name, | |
| 2018 | + &mode, &bufsize)) | |
| 2019 | + return -1; | |
| 2020 | + | |
| 2021 | + /* We parse again to get the name as a PyObject */ | |
| 2022 | + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:file", | |
| 2023 | + kwlist, &o_name, &mode, | |
| 2024 | + &bufsize)) | |
| 2025 | + goto Error; | |
| 2026 | + | |
| 2027 | + if (fill_file_fields(foself, NULL, o_name, mode, | |
| 2028 | + fclose) == NULL) | |
| 2029 | + goto Error; | |
| 2030 | + } | |
| 2031 | + if (open_the_file(foself, name, mode) == NULL) | |
| 2032 | + goto Error; | |
| 2033 | + foself->f_setbuf = NULL; | |
| 2034 | + PyFile_SetBufSize(self, bufsize); | |
| 2035 | + goto Done; | |
| 2036 | + | |
| 2037 | +Error: | |
| 2038 | + ret = -1; | |
| 2039 | + /* fall through */ | |
| 2040 | +Done: | |
| 2041 | + PyMem_Free(name); /* free the encoded string */ | |
| 2042 | + return ret; | |
| 2043 | +} | |
| 2044 | + | |
| 2045 | +PyDoc_VAR(file_doc) = | |
| 2046 | +PyDoc_STR( | |
| 2047 | +"file(name[, mode[, buffering]]) -> file object\n" | |
| 2048 | +"\n" | |
| 2049 | +"Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n" | |
| 2050 | +"writing or appending. The file will be created if it doesn't exist\n" | |
| 2051 | +"when opened for writing or appending; it will be truncated when\n" | |
| 2052 | +"opened for writing. Add a 'b' to the mode for binary files.\n" | |
| 2053 | +"Add a '+' to the mode to allow simultaneous reading and writing.\n" | |
| 2054 | +"If the buffering argument is given, 0 means unbuffered, 1 means line\n" | |
| 2055 | +"buffered, and larger numbers specify the buffer size.\n" | |
| 2056 | +) | |
| 2057 | +PyDoc_STR( | |
| 2058 | +"Add a 'U' to mode to open the file for input with universal newline\n" | |
| 2059 | +"support. Any line ending in the input file will be seen as a '\\n'\n" | |
| 2060 | +"in Python. Also, a file so opened gains the attribute 'newlines';\n" | |
| 2061 | +"the value for this attribute is one of None (no newline read yet),\n" | |
| 2062 | +"'\\r', '\\n', '\\r\\n' or a tuple containing all the newline types seen.\n" | |
| 2063 | +"\n" | |
| 2064 | +"'U' cannot be combined with 'w' or '+' mode.\n" | |
| 2065 | +); | |
| 2066 | + | |
| 2067 | +PyTypeObject PyFile_Type = { | |
| 2068 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 2069 | + 0, | |
| 2070 | + "file", | |
| 2071 | + sizeof(PyFileObject), | |
| 2072 | + 0, | |
| 2073 | + (destructor)file_dealloc, /* tp_dealloc */ | |
| 2074 | + 0, /* tp_print */ | |
| 2075 | + 0, /* tp_getattr */ | |
| 2076 | + 0, /* tp_setattr */ | |
| 2077 | + 0, /* tp_compare */ | |
| 2078 | + (reprfunc)file_repr, /* tp_repr */ | |
| 2079 | + 0, /* tp_as_number */ | |
| 2080 | + 0, /* tp_as_sequence */ | |
| 2081 | + 0, /* tp_as_mapping */ | |
| 2082 | + 0, /* tp_hash */ | |
| 2083 | + 0, /* tp_call */ | |
| 2084 | + 0, /* tp_str */ | |
| 2085 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 2086 | + /* softspace is writable: we must supply tp_setattro */ | |
| 2087 | + PyObject_GenericSetAttr, /* tp_setattro */ | |
| 2088 | + 0, /* tp_as_buffer */ | |
| 2089 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */ | |
| 2090 | + file_doc, /* tp_doc */ | |
| 2091 | + 0, /* tp_traverse */ | |
| 2092 | + 0, /* tp_clear */ | |
| 2093 | + 0, /* tp_richcompare */ | |
| 2094 | + offsetof(PyFileObject, weakreflist), /* tp_weaklistoffset */ | |
| 2095 | + (getiterfunc)file_self, /* tp_iter */ | |
| 2096 | + (iternextfunc)file_iternext, /* tp_iternext */ | |
| 2097 | + file_methods, /* tp_methods */ | |
| 2098 | + file_memberlist, /* tp_members */ | |
| 2099 | + file_getsetlist, /* tp_getset */ | |
| 2100 | + 0, /* tp_base */ | |
| 2101 | + 0, /* tp_dict */ | |
| 2102 | + 0, /* tp_descr_get */ | |
| 2103 | + 0, /* tp_descr_set */ | |
| 2104 | + 0, /* tp_dictoffset */ | |
| 2105 | + file_init, /* tp_init */ | |
| 2106 | + PyType_GenericAlloc, /* tp_alloc */ | |
| 2107 | + file_new, /* tp_new */ | |
| 2108 | + PyObject_Del, /* tp_free */ | |
| 2109 | +}; | |
| 2110 | + | |
| 2111 | +/* Interface for the 'soft space' between print items. */ | |
| 2112 | + | |
| 2113 | +int | |
| 2114 | +PyFile_SoftSpace(PyObject *f, int newflag) | |
| 2115 | +{ | |
| 2116 | + long oldflag = 0; | |
| 2117 | + if (f == NULL) { | |
| 2118 | + /* Do nothing */ | |
| 2119 | + } | |
| 2120 | + else if (PyFile_Check(f)) { | |
| 2121 | + oldflag = ((PyFileObject *)f)->f_softspace; | |
| 2122 | + ((PyFileObject *)f)->f_softspace = newflag; | |
| 2123 | + } | |
| 2124 | + else { | |
| 2125 | + PyObject *v; | |
| 2126 | + v = PyObject_GetAttrString(f, "softspace"); | |
| 2127 | + if (v == NULL) | |
| 2128 | + PyErr_Clear(); | |
| 2129 | + else { | |
| 2130 | + if (PyInt_Check(v)) | |
| 2131 | + oldflag = PyInt_AsLong(v); | |
| 2132 | + assert(oldflag < INT_MAX); | |
| 2133 | + Py_DECREF(v); | |
| 2134 | + } | |
| 2135 | + v = PyInt_FromLong((long)newflag); | |
| 2136 | + if (v == NULL) | |
| 2137 | + PyErr_Clear(); | |
| 2138 | + else { | |
| 2139 | + if (PyObject_SetAttrString(f, "softspace", v) != 0) | |
| 2140 | + PyErr_Clear(); | |
| 2141 | + Py_DECREF(v); | |
| 2142 | + } | |
| 2143 | + } | |
| 2144 | + return (int)oldflag; | |
| 2145 | +} | |
| 2146 | + | |
| 2147 | +/* Interfaces to write objects/strings to file-like objects */ | |
| 2148 | + | |
| 2149 | +int | |
| 2150 | +PyFile_WriteObject(PyObject *v, PyObject *f, int flags) | |
| 2151 | +{ | |
| 2152 | + PyObject *writer, *value, *args, *result; | |
| 2153 | + if (f == NULL) { | |
| 2154 | + PyErr_SetString(PyExc_TypeError, "writeobject with NULL file"); | |
| 2155 | + return -1; | |
| 2156 | + } | |
| 2157 | + else if (PyFile_Check(f)) { | |
| 2158 | + FILE *fp = PyFile_AsFile(f); | |
| 2159 | +#ifdef Py_USING_UNICODE | |
| 2160 | + PyObject *enc = ((PyFileObject*)f)->f_encoding; | |
| 2161 | + int result; | |
| 2162 | +#endif | |
| 2163 | + if (fp == NULL) { | |
| 2164 | + err_closed(); | |
| 2165 | + return -1; | |
| 2166 | + } | |
| 2167 | +#ifdef Py_USING_UNICODE | |
| 2168 | + if ((flags & Py_PRINT_RAW) && | |
| 2169 | + PyUnicode_Check(v) && enc != Py_None) { | |
| 2170 | + char *cenc = PyString_AS_STRING(enc); | |
| 2171 | + value = PyUnicode_AsEncodedString(v, cenc, "strict"); | |
| 2172 | + if (value == NULL) | |
| 2173 | + return -1; | |
| 2174 | + } else { | |
| 2175 | + value = v; | |
| 2176 | + Py_INCREF(value); | |
| 2177 | + } | |
| 2178 | + result = PyObject_Print(value, fp, flags); | |
| 2179 | + Py_DECREF(value); | |
| 2180 | + return result; | |
| 2181 | +#else | |
| 2182 | + return PyObject_Print(v, fp, flags); | |
| 2183 | +#endif | |
| 2184 | + } | |
| 2185 | + writer = PyObject_GetAttrString(f, "write"); | |
| 2186 | + if (writer == NULL) | |
| 2187 | + return -1; | |
| 2188 | + if (flags & Py_PRINT_RAW) { | |
| 2189 | + if (PyUnicode_Check(v)) { | |
| 2190 | + value = v; | |
| 2191 | + Py_INCREF(value); | |
| 2192 | + } else | |
| 2193 | + value = PyObject_Str(v); | |
| 2194 | + } | |
| 2195 | + else | |
| 2196 | + value = PyObject_Repr(v); | |
| 2197 | + if (value == NULL) { | |
| 2198 | + Py_DECREF(writer); | |
| 2199 | + return -1; | |
| 2200 | + } | |
| 2201 | + args = PyTuple_Pack(1, value); | |
| 2202 | + if (args == NULL) { | |
| 2203 | + Py_DECREF(value); | |
| 2204 | + Py_DECREF(writer); | |
| 2205 | + return -1; | |
| 2206 | + } | |
| 2207 | + result = PyEval_CallObject(writer, args); | |
| 2208 | + Py_DECREF(args); | |
| 2209 | + Py_DECREF(value); | |
| 2210 | + Py_DECREF(writer); | |
| 2211 | + if (result == NULL) | |
| 2212 | + return -1; | |
| 2213 | + Py_DECREF(result); | |
| 2214 | + return 0; | |
| 2215 | +} | |
| 2216 | + | |
| 2217 | +int | |
| 2218 | +PyFile_WriteString(const char *s, PyObject *f) | |
| 2219 | +{ | |
| 2220 | + if (f == NULL) { | |
| 2221 | + /* Should be caused by a pre-existing error */ | |
| 2222 | + if (!PyErr_Occurred()) | |
| 2223 | + PyErr_SetString(PyExc_SystemError, | |
| 2224 | + "null file for PyFile_WriteString"); | |
| 2225 | + return -1; | |
| 2226 | + } | |
| 2227 | + else if (PyFile_Check(f)) { | |
| 2228 | + FILE *fp = PyFile_AsFile(f); | |
| 2229 | + if (fp == NULL) { | |
| 2230 | + err_closed(); | |
| 2231 | + return -1; | |
| 2232 | + } | |
| 2233 | + fputs(s, fp); | |
| 2234 | + return 0; | |
| 2235 | + } | |
| 2236 | + else if (!PyErr_Occurred()) { | |
| 2237 | + PyObject *v = PyString_FromString(s); | |
| 2238 | + int err; | |
| 2239 | + if (v == NULL) | |
| 2240 | + return -1; | |
| 2241 | + err = PyFile_WriteObject(v, f, Py_PRINT_RAW); | |
| 2242 | + Py_DECREF(v); | |
| 2243 | + return err; | |
| 2244 | + } | |
| 2245 | + else | |
| 2246 | + return -1; | |
| 2247 | +} | |
| 2248 | + | |
| 2249 | +/* Try to get a file-descriptor from a Python object. If the object | |
| 2250 | + is an integer or long integer, its value is returned. If not, the | |
| 2251 | + object's fileno() method is called if it exists; the method must return | |
| 2252 | + an integer or long integer, which is returned as the file descriptor value. | |
| 2253 | + -1 is returned on failure. | |
| 2254 | +*/ | |
| 2255 | + | |
| 2256 | +int PyObject_AsFileDescriptor(PyObject *o) | |
| 2257 | +{ | |
| 2258 | + int fd; | |
| 2259 | + PyObject *meth; | |
| 2260 | + | |
| 2261 | + if (PyInt_Check(o)) { | |
| 2262 | + fd = PyInt_AsLong(o); | |
| 2263 | + } | |
| 2264 | + else if (PyLong_Check(o)) { | |
| 2265 | + fd = PyLong_AsLong(o); | |
| 2266 | + } | |
| 2267 | + else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL) | |
| 2268 | + { | |
| 2269 | + PyObject *fno = PyEval_CallObject(meth, NULL); | |
| 2270 | + Py_DECREF(meth); | |
| 2271 | + if (fno == NULL) | |
| 2272 | + return -1; | |
| 2273 | + | |
| 2274 | + if (PyInt_Check(fno)) { | |
| 2275 | + fd = PyInt_AsLong(fno); | |
| 2276 | + Py_DECREF(fno); | |
| 2277 | + } | |
| 2278 | + else if (PyLong_Check(fno)) { | |
| 2279 | + fd = PyLong_AsLong(fno); | |
| 2280 | + Py_DECREF(fno); | |
| 2281 | + } | |
| 2282 | + else { | |
| 2283 | + PyErr_SetString(PyExc_TypeError, | |
| 2284 | + "fileno() returned a non-integer"); | |
| 2285 | + Py_DECREF(fno); | |
| 2286 | + return -1; | |
| 2287 | + } | |
| 2288 | + } | |
| 2289 | + else { | |
| 2290 | + PyErr_SetString(PyExc_TypeError, | |
| 2291 | + "argument must be an int, or have a fileno() method."); | |
| 2292 | + return -1; | |
| 2293 | + } | |
| 2294 | + | |
| 2295 | + if (fd < 0) { | |
| 2296 | + PyErr_Format(PyExc_ValueError, | |
| 2297 | + "file descriptor cannot be a negative integer (%i)", | |
| 2298 | + fd); | |
| 2299 | + return -1; | |
| 2300 | + } | |
| 2301 | + return fd; | |
| 2302 | +} | |
| 2303 | + | |
| 2304 | +/* From here on we need access to the real fgets and fread */ | |
| 2305 | +#undef fgets | |
| 2306 | +#undef fread | |
| 2307 | + | |
| 2308 | +/* | |
| 2309 | +** Py_UniversalNewlineFgets is an fgets variation that understands | |
| 2310 | +** all of \r, \n and \r\n conventions. | |
| 2311 | +** The stream should be opened in binary mode. | |
| 2312 | +** If fobj is NULL the routine always does newline conversion, and | |
| 2313 | +** it may peek one char ahead to gobble the second char in \r\n. | |
| 2314 | +** If fobj is non-NULL it must be a PyFileObject. In this case there | |
| 2315 | +** is no readahead but in stead a flag is used to skip a following | |
| 2316 | +** \n on the next read. Also, if the file is open in binary mode | |
| 2317 | +** the whole conversion is skipped. Finally, the routine keeps track of | |
| 2318 | +** the different types of newlines seen. | |
| 2319 | +** Note that we need no error handling: fgets() treats error and eof | |
| 2320 | +** identically. | |
| 2321 | +*/ | |
| 2322 | +char * | |
| 2323 | +Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) | |
| 2324 | +{ | |
| 2325 | + char *p = buf; | |
| 2326 | + int c; | |
| 2327 | + int newlinetypes = 0; | |
| 2328 | + int skipnextlf = 0; | |
| 2329 | + int univ_newline = 1; | |
| 2330 | + | |
| 2331 | + if (fobj) { | |
| 2332 | + if (!PyFile_Check(fobj)) { | |
| 2333 | + errno = ENXIO; /* What can you do... */ | |
| 2334 | + return NULL; | |
| 2335 | + } | |
| 2336 | + univ_newline = ((PyFileObject *)fobj)->f_univ_newline; | |
| 2337 | + if ( !univ_newline ) | |
| 2338 | + return fgets(buf, n, stream); | |
| 2339 | + newlinetypes = ((PyFileObject *)fobj)->f_newlinetypes; | |
| 2340 | + skipnextlf = ((PyFileObject *)fobj)->f_skipnextlf; | |
| 2341 | + } | |
| 2342 | + FLOCKFILE(stream); | |
| 2343 | + c = 'x'; /* Shut up gcc warning */ | |
| 2344 | + while (--n > 0 && (c = GETC(stream)) != EOF ) { | |
| 2345 | + if (skipnextlf ) { | |
| 2346 | + skipnextlf = 0; | |
| 2347 | + if (c == '\n') { | |
| 2348 | + /* Seeing a \n here with skipnextlf true | |
| 2349 | + ** means we saw a \r before. | |
| 2350 | + */ | |
| 2351 | + newlinetypes |= NEWLINE_CRLF; | |
| 2352 | + c = GETC(stream); | |
| 2353 | + if (c == EOF) break; | |
| 2354 | + } else { | |
| 2355 | + /* | |
| 2356 | + ** Note that c == EOF also brings us here, | |
| 2357 | + ** so we're okay if the last char in the file | |
| 2358 | + ** is a CR. | |
| 2359 | + */ | |
| 2360 | + newlinetypes |= NEWLINE_CR; | |
| 2361 | + } | |
| 2362 | + } | |
| 2363 | + if (c == '\r') { | |
| 2364 | + /* A \r is translated into a \n, and we skip | |
| 2365 | + ** an adjacent \n, if any. We don't set the | |
| 2366 | + ** newlinetypes flag until we've seen the next char. | |
| 2367 | + */ | |
| 2368 | + skipnextlf = 1; | |
| 2369 | + c = '\n'; | |
| 2370 | + } else if ( c == '\n') { | |
| 2371 | + newlinetypes |= NEWLINE_LF; | |
| 2372 | + } | |
| 2373 | + *p++ = c; | |
| 2374 | + if (c == '\n') break; | |
| 2375 | + } | |
| 2376 | + if ( c == EOF && skipnextlf ) | |
| 2377 | + newlinetypes |= NEWLINE_CR; | |
| 2378 | + FUNLOCKFILE(stream); | |
| 2379 | + *p = '\0'; | |
| 2380 | + if (fobj) { | |
| 2381 | + ((PyFileObject *)fobj)->f_newlinetypes = newlinetypes; | |
| 2382 | + ((PyFileObject *)fobj)->f_skipnextlf = skipnextlf; | |
| 2383 | + } else if ( skipnextlf ) { | |
| 2384 | + /* If we have no file object we cannot save the | |
| 2385 | + ** skipnextlf flag. We have to readahead, which | |
| 2386 | + ** will cause a pause if we're reading from an | |
| 2387 | + ** interactive stream, but that is very unlikely | |
| 2388 | + ** unless we're doing something silly like | |
| 2389 | + ** execfile("/dev/tty"). | |
| 2390 | + */ | |
| 2391 | + c = GETC(stream); | |
| 2392 | + if ( c != '\n' ) | |
| 2393 | + ungetc(c, stream); | |
| 2394 | + } | |
| 2395 | + if (p == buf) | |
| 2396 | + return NULL; | |
| 2397 | + return buf; | |
| 2398 | +} | |
| 2399 | + | |
| 2400 | +/* | |
| 2401 | +** Py_UniversalNewlineFread is an fread variation that understands | |
| 2402 | +** all of \r, \n and \r\n conventions. | |
| 2403 | +** The stream should be opened in binary mode. | |
| 2404 | +** fobj must be a PyFileObject. In this case there | |
| 2405 | +** is no readahead but in stead a flag is used to skip a following | |
| 2406 | +** \n on the next read. Also, if the file is open in binary mode | |
| 2407 | +** the whole conversion is skipped. Finally, the routine keeps track of | |
| 2408 | +** the different types of newlines seen. | |
| 2409 | +*/ | |
| 2410 | +size_t | |
| 2411 | +Py_UniversalNewlineFread(char *buf, size_t n, | |
| 2412 | + FILE *stream, PyObject *fobj) | |
| 2413 | +{ | |
| 2414 | + char *dst = buf; | |
| 2415 | + PyFileObject *f = (PyFileObject *)fobj; | |
| 2416 | + int newlinetypes, skipnextlf; | |
| 2417 | + | |
| 2418 | + assert(buf != NULL); | |
| 2419 | + assert(stream != NULL); | |
| 2420 | + | |
| 2421 | + if (!fobj || !PyFile_Check(fobj)) { | |
| 2422 | + errno = ENXIO; /* What can you do... */ | |
| 2423 | + return 0; | |
| 2424 | + } | |
| 2425 | + if (!f->f_univ_newline) | |
| 2426 | + return fread(buf, 1, n, stream); | |
| 2427 | + newlinetypes = f->f_newlinetypes; | |
| 2428 | + skipnextlf = f->f_skipnextlf; | |
| 2429 | + /* Invariant: n is the number of bytes remaining to be filled | |
| 2430 | + * in the buffer. | |
| 2431 | + */ | |
| 2432 | + while (n) { | |
| 2433 | + size_t nread; | |
| 2434 | + int shortread; | |
| 2435 | + char *src = dst; | |
| 2436 | + | |
| 2437 | + nread = fread(dst, 1, n, stream); | |
| 2438 | + assert(nread <= n); | |
| 2439 | + if (nread == 0) | |
| 2440 | + break; | |
| 2441 | + | |
| 2442 | + n -= nread; /* assuming 1 byte out for each in; will adjust */ | |
| 2443 | + shortread = n != 0; /* true iff EOF or error */ | |
| 2444 | + while (nread--) { | |
| 2445 | + char c = *src++; | |
| 2446 | + if (c == '\r') { | |
| 2447 | + /* Save as LF and set flag to skip next LF. */ | |
| 2448 | + *dst++ = '\n'; | |
| 2449 | + skipnextlf = 1; | |
| 2450 | + } | |
| 2451 | + else if (skipnextlf && c == '\n') { | |
| 2452 | + /* Skip LF, and remember we saw CR LF. */ | |
| 2453 | + skipnextlf = 0; | |
| 2454 | + newlinetypes |= NEWLINE_CRLF; | |
| 2455 | + ++n; | |
| 2456 | + } | |
| 2457 | + else { | |
| 2458 | + /* Normal char to be stored in buffer. Also | |
| 2459 | + * update the newlinetypes flag if either this | |
| 2460 | + * is an LF or the previous char was a CR. | |
| 2461 | + */ | |
| 2462 | + if (c == '\n') | |
| 2463 | + newlinetypes |= NEWLINE_LF; | |
| 2464 | + else if (skipnextlf) | |
| 2465 | + newlinetypes |= NEWLINE_CR; | |
| 2466 | + *dst++ = c; | |
| 2467 | + skipnextlf = 0; | |
| 2468 | + } | |
| 2469 | + } | |
| 2470 | + if (shortread) { | |
| 2471 | + /* If this is EOF, update type flags. */ | |
| 2472 | + if (skipnextlf && feof(stream)) | |
| 2473 | + newlinetypes |= NEWLINE_CR; | |
| 2474 | + break; | |
| 2475 | + } | |
| 2476 | + } | |
| 2477 | + f->f_newlinetypes = newlinetypes; | |
| 2478 | + f->f_skipnextlf = skipnextlf; | |
| 2479 | + return dst - buf; | |
| 2480 | +} | |
| 2481 | + | |
| 2482 | +#ifdef __cplusplus | |
| 2483 | +} | |
| 2484 | +#endif | |
| @@ -0,0 +1,1748 @@ | ||
| 1 | + | |
| 2 | +/* Float object implementation */ | |
| 3 | + | |
| 4 | +/* XXX There should be overflow checks here, but it's hard to check | |
| 5 | + for any kind of float exception without losing portability. */ | |
| 6 | + | |
| 7 | +#include "Python.h" | |
| 8 | + | |
| 9 | +#include <ctype.h> | |
| 10 | + | |
| 11 | +#if !defined(__STDC__) | |
| 12 | +extern double fmod(double, double); | |
| 13 | +extern double pow(double, double); | |
| 14 | +#endif | |
| 15 | + | |
| 16 | +/* Special free list -- see comments for same code in intobject.c. */ | |
| 17 | +#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */ | |
| 18 | +#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */ | |
| 19 | +#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject)) | |
| 20 | + | |
| 21 | +struct _floatblock { | |
| 22 | + struct _floatblock *next; | |
| 23 | + PyFloatObject objects[N_FLOATOBJECTS]; | |
| 24 | +}; | |
| 25 | + | |
| 26 | +typedef struct _floatblock PyFloatBlock; | |
| 27 | + | |
| 28 | +static PyFloatBlock *block_list = NULL; | |
| 29 | +static PyFloatObject *free_list = NULL; | |
| 30 | + | |
| 31 | +static PyFloatObject * | |
| 32 | +fill_free_list(void) | |
| 33 | +{ | |
| 34 | + PyFloatObject *p, *q; | |
| 35 | + /* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */ | |
| 36 | + p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock)); | |
| 37 | + if (p == NULL) | |
| 38 | + return (PyFloatObject *) PyErr_NoMemory(); | |
| 39 | + ((PyFloatBlock *)p)->next = block_list; | |
| 40 | + block_list = (PyFloatBlock *)p; | |
| 41 | + p = &((PyFloatBlock *)p)->objects[0]; | |
| 42 | + q = p + N_FLOATOBJECTS; | |
| 43 | + while (--q > p) | |
| 44 | + q->ob_type = (struct _typeobject *)(q-1); | |
| 45 | + q->ob_type = NULL; | |
| 46 | + return p + N_FLOATOBJECTS - 1; | |
| 47 | +} | |
| 48 | + | |
| 49 | +PyObject * | |
| 50 | +PyFloat_FromDouble(double fval) | |
| 51 | +{ | |
| 52 | + register PyFloatObject *op; | |
| 53 | + if (free_list == NULL) { | |
| 54 | + if ((free_list = fill_free_list()) == NULL) | |
| 55 | + return NULL; | |
| 56 | + } | |
| 57 | + /* Inline PyObject_New */ | |
| 58 | + op = free_list; | |
| 59 | + free_list = (PyFloatObject *)op->ob_type; | |
| 60 | + PyObject_INIT(op, &PyFloat_Type); | |
| 61 | + op->ob_fval = fval; | |
| 62 | + return (PyObject *) op; | |
| 63 | +} | |
| 64 | + | |
| 65 | +/************************************************************************** | |
| 66 | +RED_FLAG 22-Sep-2000 tim | |
| 67 | +PyFloat_FromString's pend argument is braindead. Prior to this RED_FLAG, | |
| 68 | + | |
| 69 | +1. If v was a regular string, *pend was set to point to its terminating | |
| 70 | + null byte. That's useless (the caller can find that without any | |
| 71 | + help from this function!). | |
| 72 | + | |
| 73 | +2. If v was a Unicode string, or an object convertible to a character | |
| 74 | + buffer, *pend was set to point into stack trash (the auto temp | |
| 75 | + vector holding the character buffer). That was downright dangerous. | |
| 76 | + | |
| 77 | +Since we can't change the interface of a public API function, pend is | |
| 78 | +still supported but now *officially* useless: if pend is not NULL, | |
| 79 | +*pend is set to NULL. | |
| 80 | +**************************************************************************/ | |
| 81 | +PyObject * | |
| 82 | +PyFloat_FromString(PyObject *v, char **pend) | |
| 83 | +{ | |
| 84 | + const char *s, *last, *end; | |
| 85 | + double x; | |
| 86 | + char buffer[256]; /* for errors */ | |
| 87 | +#ifdef Py_USING_UNICODE | |
| 88 | + char s_buffer[256]; /* for objects convertible to a char buffer */ | |
| 89 | +#endif | |
| 90 | + Py_ssize_t len; | |
| 91 | + | |
| 92 | + if (pend) | |
| 93 | + *pend = NULL; | |
| 94 | + if (PyString_Check(v)) { | |
| 95 | + s = PyString_AS_STRING(v); | |
| 96 | + len = PyString_GET_SIZE(v); | |
| 97 | + } | |
| 98 | +#ifdef Py_USING_UNICODE | |
| 99 | + else if (PyUnicode_Check(v)) { | |
| 100 | + if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) { | |
| 101 | + PyErr_SetString(PyExc_ValueError, | |
| 102 | + "Unicode float() literal too long to convert"); | |
| 103 | + return NULL; | |
| 104 | + } | |
| 105 | + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), | |
| 106 | + PyUnicode_GET_SIZE(v), | |
| 107 | + s_buffer, | |
| 108 | + NULL)) | |
| 109 | + return NULL; | |
| 110 | + s = s_buffer; | |
| 111 | + len = strlen(s); | |
| 112 | + } | |
| 113 | +#endif | |
| 114 | + else if (PyObject_AsCharBuffer(v, &s, &len)) { | |
| 115 | + PyErr_SetString(PyExc_TypeError, | |
| 116 | + "float() argument must be a string or a number"); | |
| 117 | + return NULL; | |
| 118 | + } | |
| 119 | + | |
| 120 | + last = s + len; | |
| 121 | + while (*s && isspace(Py_CHARMASK(*s))) | |
| 122 | + s++; | |
| 123 | + if (*s == '\0') { | |
| 124 | + PyErr_SetString(PyExc_ValueError, "empty string for float()"); | |
| 125 | + return NULL; | |
| 126 | + } | |
| 127 | + /* We don't care about overflow or underflow. If the platform supports | |
| 128 | + * them, infinities and signed zeroes (on underflow) are fine. | |
| 129 | + * However, strtod can return 0 for denormalized numbers, where atof | |
| 130 | + * does not. So (alas!) we special-case a zero result. Note that | |
| 131 | + * whether strtod sets errno on underflow is not defined, so we can't | |
| 132 | + * key off errno. | |
| 133 | + */ | |
| 134 | + PyFPE_START_PROTECT("strtod", return NULL) | |
| 135 | + x = PyOS_ascii_strtod(s, (char **)&end); | |
| 136 | + PyFPE_END_PROTECT(x) | |
| 137 | + errno = 0; | |
| 138 | + /* Believe it or not, Solaris 2.6 can move end *beyond* the null | |
| 139 | + byte at the end of the string, when the input is inf(inity). */ | |
| 140 | + if (end > last) | |
| 141 | + end = last; | |
| 142 | + if (end == s) { | |
| 143 | + PyOS_snprintf(buffer, sizeof(buffer), | |
| 144 | + "invalid literal for float(): %.200s", s); | |
| 145 | + PyErr_SetString(PyExc_ValueError, buffer); | |
| 146 | + return NULL; | |
| 147 | + } | |
| 148 | + /* Since end != s, the platform made *some* kind of sense out | |
| 149 | + of the input. Trust it. */ | |
| 150 | + while (*end && isspace(Py_CHARMASK(*end))) | |
| 151 | + end++; | |
| 152 | + if (*end != '\0') { | |
| 153 | + PyOS_snprintf(buffer, sizeof(buffer), | |
| 154 | + "invalid literal for float(): %.200s", s); | |
| 155 | + PyErr_SetString(PyExc_ValueError, buffer); | |
| 156 | + return NULL; | |
| 157 | + } | |
| 158 | + else if (end != last) { | |
| 159 | + PyErr_SetString(PyExc_ValueError, | |
| 160 | + "null byte in argument for float()"); | |
| 161 | + return NULL; | |
| 162 | + } | |
| 163 | + if (x == 0.0) { | |
| 164 | + /* See above -- may have been strtod being anal | |
| 165 | + about denorms. */ | |
| 166 | + PyFPE_START_PROTECT("atof", return NULL) | |
| 167 | + x = PyOS_ascii_atof(s); | |
| 168 | + PyFPE_END_PROTECT(x) | |
| 169 | + errno = 0; /* whether atof ever set errno is undefined */ | |
| 170 | + } | |
| 171 | + return PyFloat_FromDouble(x); | |
| 172 | +} | |
| 173 | + | |
| 174 | +static void | |
| 175 | +float_dealloc(PyFloatObject *op) | |
| 176 | +{ | |
| 177 | + if (PyFloat_CheckExact(op)) { | |
| 178 | + op->ob_type = (struct _typeobject *)free_list; | |
| 179 | + free_list = op; | |
| 180 | + } | |
| 181 | + else | |
| 182 | + op->ob_type->tp_free((PyObject *)op); | |
| 183 | +} | |
| 184 | + | |
| 185 | +double | |
| 186 | +PyFloat_AsDouble(PyObject *op) | |
| 187 | +{ | |
| 188 | + PyNumberMethods *nb; | |
| 189 | + PyFloatObject *fo; | |
| 190 | + double val; | |
| 191 | + | |
| 192 | + if (op && PyFloat_Check(op)) | |
| 193 | + return PyFloat_AS_DOUBLE((PyFloatObject*) op); | |
| 194 | + | |
| 195 | + if (op == NULL) { | |
| 196 | + PyErr_BadArgument(); | |
| 197 | + return -1; | |
| 198 | + } | |
| 199 | + | |
| 200 | + if ((nb = op->ob_type->tp_as_number) == NULL || nb->nb_float == NULL) { | |
| 201 | + PyErr_SetString(PyExc_TypeError, "a float is required"); | |
| 202 | + return -1; | |
| 203 | + } | |
| 204 | + | |
| 205 | + fo = (PyFloatObject*) (*nb->nb_float) (op); | |
| 206 | + if (fo == NULL) | |
| 207 | + return -1; | |
| 208 | + if (!PyFloat_Check(fo)) { | |
| 209 | + PyErr_SetString(PyExc_TypeError, | |
| 210 | + "nb_float should return float object"); | |
| 211 | + return -1; | |
| 212 | + } | |
| 213 | + | |
| 214 | + val = PyFloat_AS_DOUBLE(fo); | |
| 215 | + Py_DECREF(fo); | |
| 216 | + | |
| 217 | + return val; | |
| 218 | +} | |
| 219 | + | |
| 220 | +/* Methods */ | |
| 221 | + | |
| 222 | +static void | |
| 223 | +format_float(char *buf, size_t buflen, PyFloatObject *v, int precision) | |
| 224 | +{ | |
| 225 | + register char *cp; | |
| 226 | + char format[32]; | |
| 227 | + /* Subroutine for float_repr and float_print. | |
| 228 | + We want float numbers to be recognizable as such, | |
| 229 | + i.e., they should contain a decimal point or an exponent. | |
| 230 | + However, %g may print the number as an integer; | |
| 231 | + in such cases, we append ".0" to the string. */ | |
| 232 | + | |
| 233 | + assert(PyFloat_Check(v)); | |
| 234 | + PyOS_snprintf(format, 32, "%%.%ig", precision); | |
| 235 | + PyOS_ascii_formatd(buf, buflen, format, v->ob_fval); | |
| 236 | + cp = buf; | |
| 237 | + if (*cp == '-') | |
| 238 | + cp++; | |
| 239 | + for (; *cp != '\0'; cp++) { | |
| 240 | + /* Any non-digit means it's not an integer; | |
| 241 | + this takes care of NAN and INF as well. */ | |
| 242 | + if (!isdigit(Py_CHARMASK(*cp))) | |
| 243 | + break; | |
| 244 | + } | |
| 245 | + if (*cp == '\0') { | |
| 246 | + *cp++ = '.'; | |
| 247 | + *cp++ = '0'; | |
| 248 | + *cp++ = '\0'; | |
| 249 | + } | |
| 250 | +} | |
| 251 | + | |
| 252 | +/* XXX PyFloat_AsStringEx should not be a public API function (for one | |
| 253 | + XXX thing, its signature passes a buffer without a length; for another, | |
| 254 | + XXX it isn't useful outside this file). | |
| 255 | +*/ | |
| 256 | +void | |
| 257 | +PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision) | |
| 258 | +{ | |
| 259 | + format_float(buf, 100, v, precision); | |
| 260 | +} | |
| 261 | + | |
| 262 | +/* Macro and helper that convert PyObject obj to a C double and store | |
| 263 | + the value in dbl; this replaces the functionality of the coercion | |
| 264 | + slot function. If conversion to double raises an exception, obj is | |
| 265 | + set to NULL, and the function invoking this macro returns NULL. If | |
| 266 | + obj is not of float, int or long type, Py_NotImplemented is incref'ed, | |
| 267 | + stored in obj, and returned from the function invoking this macro. | |
| 268 | +*/ | |
| 269 | +#define CONVERT_TO_DOUBLE(obj, dbl) \ | |
| 270 | + if (PyFloat_Check(obj)) \ | |
| 271 | + dbl = PyFloat_AS_DOUBLE(obj); \ | |
| 272 | + else if (convert_to_double(&(obj), &(dbl)) < 0) \ | |
| 273 | + return obj; | |
| 274 | + | |
| 275 | +static int | |
| 276 | +convert_to_double(PyObject **v, double *dbl) | |
| 277 | +{ | |
| 278 | + register PyObject *obj = *v; | |
| 279 | + | |
| 280 | + if (PyInt_Check(obj)) { | |
| 281 | + *dbl = (double)PyInt_AS_LONG(obj); | |
| 282 | + } | |
| 283 | + else if (PyLong_Check(obj)) { | |
| 284 | + *dbl = PyLong_AsDouble(obj); | |
| 285 | + if (*dbl == -1.0 && PyErr_Occurred()) { | |
| 286 | + *v = NULL; | |
| 287 | + return -1; | |
| 288 | + } | |
| 289 | + } | |
| 290 | + else { | |
| 291 | + Py_INCREF(Py_NotImplemented); | |
| 292 | + *v = Py_NotImplemented; | |
| 293 | + return -1; | |
| 294 | + } | |
| 295 | + return 0; | |
| 296 | +} | |
| 297 | + | |
| 298 | +/* Precisions used by repr() and str(), respectively. | |
| 299 | + | |
| 300 | + The repr() precision (17 significant decimal digits) is the minimal number | |
| 301 | + that is guaranteed to have enough precision so that if the number is read | |
| 302 | + back in the exact same binary value is recreated. This is true for IEEE | |
| 303 | + floating point by design, and also happens to work for all other modern | |
| 304 | + hardware. | |
| 305 | + | |
| 306 | + The str() precision is chosen so that in most cases, the rounding noise | |
| 307 | + created by various operations is suppressed, while giving plenty of | |
| 308 | + precision for practical use. | |
| 309 | + | |
| 310 | +*/ | |
| 311 | + | |
| 312 | +#define PREC_REPR 17 | |
| 313 | +#define PREC_STR 12 | |
| 314 | + | |
| 315 | +/* XXX PyFloat_AsString and PyFloat_AsReprString should be deprecated: | |
| 316 | + XXX they pass a char buffer without passing a length. | |
| 317 | +*/ | |
| 318 | +void | |
| 319 | +PyFloat_AsString(char *buf, PyFloatObject *v) | |
| 320 | +{ | |
| 321 | + format_float(buf, 100, v, PREC_STR); | |
| 322 | +} | |
| 323 | + | |
| 324 | +void | |
| 325 | +PyFloat_AsReprString(char *buf, PyFloatObject *v) | |
| 326 | +{ | |
| 327 | + format_float(buf, 100, v, PREC_REPR); | |
| 328 | +} | |
| 329 | + | |
| 330 | +/* ARGSUSED */ | |
| 331 | +static int | |
| 332 | +float_print(PyFloatObject *v, FILE *fp, int flags) | |
| 333 | +{ | |
| 334 | + char buf[100]; | |
| 335 | + format_float(buf, sizeof(buf), v, | |
| 336 | + (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR); | |
| 337 | + fputs(buf, fp); | |
| 338 | + return 0; | |
| 339 | +} | |
| 340 | + | |
| 341 | +static PyObject * | |
| 342 | +float_repr(PyFloatObject *v) | |
| 343 | +{ | |
| 344 | + char buf[100]; | |
| 345 | + format_float(buf, sizeof(buf), v, PREC_REPR); | |
| 346 | + return PyString_FromString(buf); | |
| 347 | +} | |
| 348 | + | |
| 349 | +static PyObject * | |
| 350 | +float_str(PyFloatObject *v) | |
| 351 | +{ | |
| 352 | + char buf[100]; | |
| 353 | + format_float(buf, sizeof(buf), v, PREC_STR); | |
| 354 | + return PyString_FromString(buf); | |
| 355 | +} | |
| 356 | + | |
| 357 | +/* Comparison is pretty much a nightmare. When comparing float to float, | |
| 358 | + * we do it as straightforwardly (and long-windedly) as conceivable, so | |
| 359 | + * that, e.g., Python x == y delivers the same result as the platform | |
| 360 | + * C x == y when x and/or y is a NaN. | |
| 361 | + * When mixing float with an integer type, there's no good *uniform* approach. | |
| 362 | + * Converting the double to an integer obviously doesn't work, since we | |
| 363 | + * may lose info from fractional bits. Converting the integer to a double | |
| 364 | + * also has two failure modes: (1) a long int may trigger overflow (too | |
| 365 | + * large to fit in the dynamic range of a C double); (2) even a C long may have | |
| 366 | + * more bits than fit in a C double (e.g., on a a 64-bit box long may have | |
| 367 | + * 63 bits of precision, but a C double probably has only 53), and then | |
| 368 | + * we can falsely claim equality when low-order integer bits are lost by | |
| 369 | + * coercion to double. So this part is painful too. | |
| 370 | + */ | |
| 371 | + | |
| 372 | +static PyObject* | |
| 373 | +float_richcompare(PyObject *v, PyObject *w, int op) | |
| 374 | +{ | |
| 375 | + double i, j; | |
| 376 | + int r = 0; | |
| 377 | + | |
| 378 | + assert(PyFloat_Check(v)); | |
| 379 | + i = PyFloat_AS_DOUBLE(v); | |
| 380 | + | |
| 381 | + /* Switch on the type of w. Set i and j to doubles to be compared, | |
| 382 | + * and op to the richcomp to use. | |
| 383 | + */ | |
| 384 | + if (PyFloat_Check(w)) | |
| 385 | + j = PyFloat_AS_DOUBLE(w); | |
| 386 | + | |
| 387 | + else if (!Py_IS_FINITE(i)) { | |
| 388 | + if (PyInt_Check(w) || PyLong_Check(w)) | |
| 389 | + /* If i is an infinity, its magnitude exceeds any | |
| 390 | + * finite integer, so it doesn't matter which int we | |
| 391 | + * compare i with. If i is a NaN, similarly. | |
| 392 | + */ | |
| 393 | + j = 0.0; | |
| 394 | + else | |
| 395 | + goto Unimplemented; | |
| 396 | + } | |
| 397 | + | |
| 398 | + else if (PyInt_Check(w)) { | |
| 399 | + long jj = PyInt_AS_LONG(w); | |
| 400 | + /* In the worst realistic case I can imagine, C double is a | |
| 401 | + * Cray single with 48 bits of precision, and long has 64 | |
| 402 | + * bits. | |
| 403 | + */ | |
| 404 | +#if SIZEOF_LONG > 6 | |
| 405 | + unsigned long abs = (unsigned long)(jj < 0 ? -jj : jj); | |
| 406 | + if (abs >> 48) { | |
| 407 | + /* Needs more than 48 bits. Make it take the | |
| 408 | + * PyLong path. | |
| 409 | + */ | |
| 410 | + PyObject *result; | |
| 411 | + PyObject *ww = PyLong_FromLong(jj); | |
| 412 | + | |
| 413 | + if (ww == NULL) | |
| 414 | + return NULL; | |
| 415 | + result = float_richcompare(v, ww, op); | |
| 416 | + Py_DECREF(ww); | |
| 417 | + return result; | |
| 418 | + } | |
| 419 | +#endif | |
| 420 | + j = (double)jj; | |
| 421 | + assert((long)j == jj); | |
| 422 | + } | |
| 423 | + | |
| 424 | + else if (PyLong_Check(w)) { | |
| 425 | + int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1; | |
| 426 | + int wsign = _PyLong_Sign(w); | |
| 427 | + size_t nbits; | |
| 428 | + int exponent; | |
| 429 | + | |
| 430 | + if (vsign != wsign) { | |
| 431 | + /* Magnitudes are irrelevant -- the signs alone | |
| 432 | + * determine the outcome. | |
| 433 | + */ | |
| 434 | + i = (double)vsign; | |
| 435 | + j = (double)wsign; | |
| 436 | + goto Compare; | |
| 437 | + } | |
| 438 | + /* The signs are the same. */ | |
| 439 | + /* Convert w to a double if it fits. In particular, 0 fits. */ | |
| 440 | + nbits = _PyLong_NumBits(w); | |
| 441 | + if (nbits == (size_t)-1 && PyErr_Occurred()) { | |
| 442 | + /* This long is so large that size_t isn't big enough | |
| 443 | + * to hold the # of bits. Replace with little doubles | |
| 444 | + * that give the same outcome -- w is so large that | |
| 445 | + * its magnitude must exceed the magnitude of any | |
| 446 | + * finite float. | |
| 447 | + */ | |
| 448 | + PyErr_Clear(); | |
| 449 | + i = (double)vsign; | |
| 450 | + assert(wsign != 0); | |
| 451 | + j = wsign * 2.0; | |
| 452 | + goto Compare; | |
| 453 | + } | |
| 454 | + if (nbits <= 48) { | |
| 455 | + j = PyLong_AsDouble(w); | |
| 456 | + /* It's impossible that <= 48 bits overflowed. */ | |
| 457 | + assert(j != -1.0 || ! PyErr_Occurred()); | |
| 458 | + goto Compare; | |
| 459 | + } | |
| 460 | + assert(wsign != 0); /* else nbits was 0 */ | |
| 461 | + assert(vsign != 0); /* if vsign were 0, then since wsign is | |
| 462 | + * not 0, we would have taken the | |
| 463 | + * vsign != wsign branch at the start */ | |
| 464 | + /* We want to work with non-negative numbers. */ | |
| 465 | + if (vsign < 0) { | |
| 466 | + /* "Multiply both sides" by -1; this also swaps the | |
| 467 | + * comparator. | |
| 468 | + */ | |
| 469 | + i = -i; | |
| 470 | + op = _Py_SwappedOp[op]; | |
| 471 | + } | |
| 472 | + assert(i > 0.0); | |
| 473 | + (void) frexp(i, &exponent); | |
| 474 | + /* exponent is the # of bits in v before the radix point; | |
| 475 | + * we know that nbits (the # of bits in w) > 48 at this point | |
| 476 | + */ | |
| 477 | + if (exponent < 0 || (size_t)exponent < nbits) { | |
| 478 | + i = 1.0; | |
| 479 | + j = 2.0; | |
| 480 | + goto Compare; | |
| 481 | + } | |
| 482 | + if ((size_t)exponent > nbits) { | |
| 483 | + i = 2.0; | |
| 484 | + j = 1.0; | |
| 485 | + goto Compare; | |
| 486 | + } | |
| 487 | + /* v and w have the same number of bits before the radix | |
| 488 | + * point. Construct two longs that have the same comparison | |
| 489 | + * outcome. | |
| 490 | + */ | |
| 491 | + { | |
| 492 | + double fracpart; | |
| 493 | + double intpart; | |
| 494 | + PyObject *result = NULL; | |
| 495 | + PyObject *one = NULL; | |
| 496 | + PyObject *vv = NULL; | |
| 497 | + PyObject *ww = w; | |
| 498 | + | |
| 499 | + if (wsign < 0) { | |
| 500 | + ww = PyNumber_Negative(w); | |
| 501 | + if (ww == NULL) | |
| 502 | + goto Error; | |
| 503 | + } | |
| 504 | + else | |
| 505 | + Py_INCREF(ww); | |
| 506 | + | |
| 507 | + fracpart = modf(i, &intpart); | |
| 508 | + vv = PyLong_FromDouble(intpart); | |
| 509 | + if (vv == NULL) | |
| 510 | + goto Error; | |
| 511 | + | |
| 512 | + if (fracpart != 0.0) { | |
| 513 | + /* Shift left, and or a 1 bit into vv | |
| 514 | + * to represent the lost fraction. | |
| 515 | + */ | |
| 516 | + PyObject *temp; | |
| 517 | + | |
| 518 | + one = PyInt_FromLong(1); | |
| 519 | + if (one == NULL) | |
| 520 | + goto Error; | |
| 521 | + | |
| 522 | + temp = PyNumber_Lshift(ww, one); | |
| 523 | + if (temp == NULL) | |
| 524 | + goto Error; | |
| 525 | + Py_DECREF(ww); | |
| 526 | + ww = temp; | |
| 527 | + | |
| 528 | + temp = PyNumber_Lshift(vv, one); | |
| 529 | + if (temp == NULL) | |
| 530 | + goto Error; | |
| 531 | + Py_DECREF(vv); | |
| 532 | + vv = temp; | |
| 533 | + | |
| 534 | + temp = PyNumber_Or(vv, one); | |
| 535 | + if (temp == NULL) | |
| 536 | + goto Error; | |
| 537 | + Py_DECREF(vv); | |
| 538 | + vv = temp; | |
| 539 | + } | |
| 540 | + | |
| 541 | + r = PyObject_RichCompareBool(vv, ww, op); | |
| 542 | + if (r < 0) | |
| 543 | + goto Error; | |
| 544 | + result = PyBool_FromLong(r); | |
| 545 | + Error: | |
| 546 | + Py_XDECREF(vv); | |
| 547 | + Py_XDECREF(ww); | |
| 548 | + Py_XDECREF(one); | |
| 549 | + return result; | |
| 550 | + } | |
| 551 | + } /* else if (PyLong_Check(w)) */ | |
| 552 | + | |
| 553 | + else /* w isn't float, int, or long */ | |
| 554 | + goto Unimplemented; | |
| 555 | + | |
| 556 | + Compare: | |
| 557 | + PyFPE_START_PROTECT("richcompare", return NULL) | |
| 558 | + switch (op) { | |
| 559 | + case Py_EQ: | |
| 560 | + r = i == j; | |
| 561 | + break; | |
| 562 | + case Py_NE: | |
| 563 | + r = i != j; | |
| 564 | + break; | |
| 565 | + case Py_LE: | |
| 566 | + r = i <= j; | |
| 567 | + break; | |
| 568 | + case Py_GE: | |
| 569 | + r = i >= j; | |
| 570 | + break; | |
| 571 | + case Py_LT: | |
| 572 | + r = i < j; | |
| 573 | + break; | |
| 574 | + case Py_GT: | |
| 575 | + r = i > j; | |
| 576 | + break; | |
| 577 | + } | |
| 578 | + PyFPE_END_PROTECT(r) | |
| 579 | + return PyBool_FromLong(r); | |
| 580 | + | |
| 581 | + Unimplemented: | |
| 582 | + Py_INCREF(Py_NotImplemented); | |
| 583 | + return Py_NotImplemented; | |
| 584 | +} | |
| 585 | + | |
| 586 | +static long | |
| 587 | +float_hash(PyFloatObject *v) | |
| 588 | +{ | |
| 589 | + return _Py_HashDouble(v->ob_fval); | |
| 590 | +} | |
| 591 | + | |
| 592 | +static PyObject * | |
| 593 | +float_add(PyObject *v, PyObject *w) | |
| 594 | +{ | |
| 595 | + double a,b; | |
| 596 | + CONVERT_TO_DOUBLE(v, a); | |
| 597 | + CONVERT_TO_DOUBLE(w, b); | |
| 598 | + PyFPE_START_PROTECT("add", return 0) | |
| 599 | + a = a + b; | |
| 600 | + PyFPE_END_PROTECT(a) | |
| 601 | + return PyFloat_FromDouble(a); | |
| 602 | +} | |
| 603 | + | |
| 604 | +static PyObject * | |
| 605 | +float_sub(PyObject *v, PyObject *w) | |
| 606 | +{ | |
| 607 | + double a,b; | |
| 608 | + CONVERT_TO_DOUBLE(v, a); | |
| 609 | + CONVERT_TO_DOUBLE(w, b); | |
| 610 | + PyFPE_START_PROTECT("subtract", return 0) | |
| 611 | + a = a - b; | |
| 612 | + PyFPE_END_PROTECT(a) | |
| 613 | + return PyFloat_FromDouble(a); | |
| 614 | +} | |
| 615 | + | |
| 616 | +static PyObject * | |
| 617 | +float_mul(PyObject *v, PyObject *w) | |
| 618 | +{ | |
| 619 | + double a,b; | |
| 620 | + CONVERT_TO_DOUBLE(v, a); | |
| 621 | + CONVERT_TO_DOUBLE(w, b); | |
| 622 | + PyFPE_START_PROTECT("multiply", return 0) | |
| 623 | + a = a * b; | |
| 624 | + PyFPE_END_PROTECT(a) | |
| 625 | + return PyFloat_FromDouble(a); | |
| 626 | +} | |
| 627 | + | |
| 628 | +static PyObject * | |
| 629 | +float_div(PyObject *v, PyObject *w) | |
| 630 | +{ | |
| 631 | + double a,b; | |
| 632 | + CONVERT_TO_DOUBLE(v, a); | |
| 633 | + CONVERT_TO_DOUBLE(w, b); | |
| 634 | + if (b == 0.0) { | |
| 635 | + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); | |
| 636 | + return NULL; | |
| 637 | + } | |
| 638 | + PyFPE_START_PROTECT("divide", return 0) | |
| 639 | + a = a / b; | |
| 640 | + PyFPE_END_PROTECT(a) | |
| 641 | + return PyFloat_FromDouble(a); | |
| 642 | +} | |
| 643 | + | |
| 644 | +static PyObject * | |
| 645 | +float_classic_div(PyObject *v, PyObject *w) | |
| 646 | +{ | |
| 647 | + double a,b; | |
| 648 | + CONVERT_TO_DOUBLE(v, a); | |
| 649 | + CONVERT_TO_DOUBLE(w, b); | |
| 650 | + if (Py_DivisionWarningFlag >= 2 && | |
| 651 | + PyErr_Warn(PyExc_DeprecationWarning, "classic float division") < 0) | |
| 652 | + return NULL; | |
| 653 | + if (b == 0.0) { | |
| 654 | + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); | |
| 655 | + return NULL; | |
| 656 | + } | |
| 657 | + PyFPE_START_PROTECT("divide", return 0) | |
| 658 | + a = a / b; | |
| 659 | + PyFPE_END_PROTECT(a) | |
| 660 | + return PyFloat_FromDouble(a); | |
| 661 | +} | |
| 662 | + | |
| 663 | +static PyObject * | |
| 664 | +float_rem(PyObject *v, PyObject *w) | |
| 665 | +{ | |
| 666 | + double vx, wx; | |
| 667 | + double mod; | |
| 668 | + CONVERT_TO_DOUBLE(v, vx); | |
| 669 | + CONVERT_TO_DOUBLE(w, wx); | |
| 670 | + if (wx == 0.0) { | |
| 671 | + PyErr_SetString(PyExc_ZeroDivisionError, "float modulo"); | |
| 672 | + return NULL; | |
| 673 | + } | |
| 674 | + PyFPE_START_PROTECT("modulo", return 0) | |
| 675 | + mod = fmod(vx, wx); | |
| 676 | + /* note: checking mod*wx < 0 is incorrect -- underflows to | |
| 677 | + 0 if wx < sqrt(smallest nonzero double) */ | |
| 678 | + if (mod && ((wx < 0) != (mod < 0))) { | |
| 679 | + mod += wx; | |
| 680 | + } | |
| 681 | + PyFPE_END_PROTECT(mod) | |
| 682 | + return PyFloat_FromDouble(mod); | |
| 683 | +} | |
| 684 | + | |
| 685 | +static PyObject * | |
| 686 | +float_divmod(PyObject *v, PyObject *w) | |
| 687 | +{ | |
| 688 | + double vx, wx; | |
| 689 | + double div, mod, floordiv; | |
| 690 | + CONVERT_TO_DOUBLE(v, vx); | |
| 691 | + CONVERT_TO_DOUBLE(w, wx); | |
| 692 | + if (wx == 0.0) { | |
| 693 | + PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()"); | |
| 694 | + return NULL; | |
| 695 | + } | |
| 696 | + PyFPE_START_PROTECT("divmod", return 0) | |
| 697 | + mod = fmod(vx, wx); | |
| 698 | + /* fmod is typically exact, so vx-mod is *mathematically* an | |
| 699 | + exact multiple of wx. But this is fp arithmetic, and fp | |
| 700 | + vx - mod is an approximation; the result is that div may | |
| 701 | + not be an exact integral value after the division, although | |
| 702 | + it will always be very close to one. | |
| 703 | + */ | |
| 704 | + div = (vx - mod) / wx; | |
| 705 | + if (mod) { | |
| 706 | + /* ensure the remainder has the same sign as the denominator */ | |
| 707 | + if ((wx < 0) != (mod < 0)) { | |
| 708 | + mod += wx; | |
| 709 | + div -= 1.0; | |
| 710 | + } | |
| 711 | + } | |
| 712 | + else { | |
| 713 | + /* the remainder is zero, and in the presence of signed zeroes | |
| 714 | + fmod returns different results across platforms; ensure | |
| 715 | + it has the same sign as the denominator; we'd like to do | |
| 716 | + "mod = wx * 0.0", but that may get optimized away */ | |
| 717 | + mod *= mod; /* hide "mod = +0" from optimizer */ | |
| 718 | + if (wx < 0.0) | |
| 719 | + mod = -mod; | |
| 720 | + } | |
| 721 | + /* snap quotient to nearest integral value */ | |
| 722 | + if (div) { | |
| 723 | + floordiv = floor(div); | |
| 724 | + if (div - floordiv > 0.5) | |
| 725 | + floordiv += 1.0; | |
| 726 | + } | |
| 727 | + else { | |
| 728 | + /* div is zero - get the same sign as the true quotient */ | |
| 729 | + div *= div; /* hide "div = +0" from optimizers */ | |
| 730 | + floordiv = div * vx / wx; /* zero w/ sign of vx/wx */ | |
| 731 | + } | |
| 732 | + PyFPE_END_PROTECT(floordiv) | |
| 733 | + return Py_BuildValue("(dd)", floordiv, mod); | |
| 734 | +} | |
| 735 | + | |
| 736 | +static PyObject * | |
| 737 | +float_floor_div(PyObject *v, PyObject *w) | |
| 738 | +{ | |
| 739 | + PyObject *t, *r; | |
| 740 | + | |
| 741 | + t = float_divmod(v, w); | |
| 742 | + if (t == NULL || t == Py_NotImplemented) | |
| 743 | + return t; | |
| 744 | + assert(PyTuple_CheckExact(t)); | |
| 745 | + r = PyTuple_GET_ITEM(t, 0); | |
| 746 | + Py_INCREF(r); | |
| 747 | + Py_DECREF(t); | |
| 748 | + return r; | |
| 749 | +} | |
| 750 | + | |
| 751 | +static PyObject * | |
| 752 | +float_pow(PyObject *v, PyObject *w, PyObject *z) | |
| 753 | +{ | |
| 754 | + double iv, iw, ix; | |
| 755 | + | |
| 756 | + if ((PyObject *)z != Py_None) { | |
| 757 | + PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not " | |
| 758 | + "allowed unless all arguments are integers"); | |
| 759 | + return NULL; | |
| 760 | + } | |
| 761 | + | |
| 762 | + CONVERT_TO_DOUBLE(v, iv); | |
| 763 | + CONVERT_TO_DOUBLE(w, iw); | |
| 764 | + | |
| 765 | + /* Sort out special cases here instead of relying on pow() */ | |
| 766 | + if (iw == 0) { /* v**0 is 1, even 0**0 */ | |
| 767 | + PyFPE_START_PROTECT("pow", return NULL) | |
| 768 | + if ((PyObject *)z != Py_None) { | |
| 769 | + double iz; | |
| 770 | + CONVERT_TO_DOUBLE(z, iz); | |
| 771 | + ix = fmod(1.0, iz); | |
| 772 | + if (ix != 0 && iz < 0) | |
| 773 | + ix += iz; | |
| 774 | + } | |
| 775 | + else | |
| 776 | + ix = 1.0; | |
| 777 | + PyFPE_END_PROTECT(ix) | |
| 778 | + return PyFloat_FromDouble(ix); | |
| 779 | + } | |
| 780 | + if (iv == 0.0) { /* 0**w is error if w<0, else 1 */ | |
| 781 | + if (iw < 0.0) { | |
| 782 | + PyErr_SetString(PyExc_ZeroDivisionError, | |
| 783 | + "0.0 cannot be raised to a negative power"); | |
| 784 | + return NULL; | |
| 785 | + } | |
| 786 | + return PyFloat_FromDouble(0.0); | |
| 787 | + } | |
| 788 | + if (iv < 0.0) { | |
| 789 | + /* Whether this is an error is a mess, and bumps into libm | |
| 790 | + * bugs so we have to figure it out ourselves. | |
| 791 | + */ | |
| 792 | + if (iw != floor(iw)) { | |
| 793 | + PyErr_SetString(PyExc_ValueError, "negative number " | |
| 794 | + "cannot be raised to a fractional power"); | |
| 795 | + return NULL; | |
| 796 | + } | |
| 797 | + /* iw is an exact integer, albeit perhaps a very large one. | |
| 798 | + * -1 raised to an exact integer should never be exceptional. | |
| 799 | + * Alas, some libms (chiefly glibc as of early 2003) return | |
| 800 | + * NaN and set EDOM on pow(-1, large_int) if the int doesn't | |
| 801 | + * happen to be representable in a *C* integer. That's a | |
| 802 | + * bug; we let that slide in math.pow() (which currently | |
| 803 | + * reflects all platform accidents), but not for Python's **. | |
| 804 | + */ | |
| 805 | + if (iv == -1.0 && Py_IS_FINITE(iw)) { | |
| 806 | + /* Return 1 if iw is even, -1 if iw is odd; there's | |
| 807 | + * no guarantee that any C integral type is big | |
| 808 | + * enough to hold iw, so we have to check this | |
| 809 | + * indirectly. | |
| 810 | + */ | |
| 811 | + ix = floor(iw * 0.5) * 2.0; | |
| 812 | + return PyFloat_FromDouble(ix == iw ? 1.0 : -1.0); | |
| 813 | + } | |
| 814 | + /* Else iv != -1.0, and overflow or underflow are possible. | |
| 815 | + * Unless we're to write pow() ourselves, we have to trust | |
| 816 | + * the platform to do this correctly. | |
| 817 | + */ | |
| 818 | + } | |
| 819 | + errno = 0; | |
| 820 | + PyFPE_START_PROTECT("pow", return NULL) | |
| 821 | + ix = pow(iv, iw); | |
| 822 | + PyFPE_END_PROTECT(ix) | |
| 823 | + Py_ADJUST_ERANGE1(ix); | |
| 824 | + if (errno != 0) { | |
| 825 | + /* We don't expect any errno value other than ERANGE, but | |
| 826 | + * the range of libm bugs appears unbounded. | |
| 827 | + */ | |
| 828 | + PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError : | |
| 829 | + PyExc_ValueError); | |
| 830 | + return NULL; | |
| 831 | + } | |
| 832 | + return PyFloat_FromDouble(ix); | |
| 833 | +} | |
| 834 | + | |
| 835 | +static PyObject * | |
| 836 | +float_neg(PyFloatObject *v) | |
| 837 | +{ | |
| 838 | + return PyFloat_FromDouble(-v->ob_fval); | |
| 839 | +} | |
| 840 | + | |
| 841 | +static PyObject * | |
| 842 | +float_pos(PyFloatObject *v) | |
| 843 | +{ | |
| 844 | + if (PyFloat_CheckExact(v)) { | |
| 845 | + Py_INCREF(v); | |
| 846 | + return (PyObject *)v; | |
| 847 | + } | |
| 848 | + else | |
| 849 | + return PyFloat_FromDouble(v->ob_fval); | |
| 850 | +} | |
| 851 | + | |
| 852 | +static PyObject * | |
| 853 | +float_abs(PyFloatObject *v) | |
| 854 | +{ | |
| 855 | + return PyFloat_FromDouble(fabs(v->ob_fval)); | |
| 856 | +} | |
| 857 | + | |
| 858 | +static int | |
| 859 | +float_nonzero(PyFloatObject *v) | |
| 860 | +{ | |
| 861 | + return v->ob_fval != 0.0; | |
| 862 | +} | |
| 863 | + | |
| 864 | +static int | |
| 865 | +float_coerce(PyObject **pv, PyObject **pw) | |
| 866 | +{ | |
| 867 | + if (PyInt_Check(*pw)) { | |
| 868 | + long x = PyInt_AsLong(*pw); | |
| 869 | + *pw = PyFloat_FromDouble((double)x); | |
| 870 | + Py_INCREF(*pv); | |
| 871 | + return 0; | |
| 872 | + } | |
| 873 | + else if (PyLong_Check(*pw)) { | |
| 874 | + double x = PyLong_AsDouble(*pw); | |
| 875 | + if (x == -1.0 && PyErr_Occurred()) | |
| 876 | + return -1; | |
| 877 | + *pw = PyFloat_FromDouble(x); | |
| 878 | + Py_INCREF(*pv); | |
| 879 | + return 0; | |
| 880 | + } | |
| 881 | + else if (PyFloat_Check(*pw)) { | |
| 882 | + Py_INCREF(*pv); | |
| 883 | + Py_INCREF(*pw); | |
| 884 | + return 0; | |
| 885 | + } | |
| 886 | + return 1; /* Can't do it */ | |
| 887 | +} | |
| 888 | + | |
| 889 | +static PyObject * | |
| 890 | +float_long(PyObject *v) | |
| 891 | +{ | |
| 892 | + double x = PyFloat_AsDouble(v); | |
| 893 | + return PyLong_FromDouble(x); | |
| 894 | +} | |
| 895 | + | |
| 896 | +static PyObject * | |
| 897 | +float_int(PyObject *v) | |
| 898 | +{ | |
| 899 | + double x = PyFloat_AsDouble(v); | |
| 900 | + double wholepart; /* integral portion of x, rounded toward 0 */ | |
| 901 | + | |
| 902 | + (void)modf(x, &wholepart); | |
| 903 | + /* Try to get out cheap if this fits in a Python int. The attempt | |
| 904 | + * to cast to long must be protected, as C doesn't define what | |
| 905 | + * happens if the double is too big to fit in a long. Some rare | |
| 906 | + * systems raise an exception then (RISCOS was mentioned as one, | |
| 907 | + * and someone using a non-default option on Sun also bumped into | |
| 908 | + * that). Note that checking for >= and <= LONG_{MIN,MAX} would | |
| 909 | + * still be vulnerable: if a long has more bits of precision than | |
| 910 | + * a double, casting MIN/MAX to double may yield an approximation, | |
| 911 | + * and if that's rounded up, then, e.g., wholepart=LONG_MAX+1 would | |
| 912 | + * yield true from the C expression wholepart<=LONG_MAX, despite | |
| 913 | + * that wholepart is actually greater than LONG_MAX. | |
| 914 | + */ | |
| 915 | + if (LONG_MIN < wholepart && wholepart < LONG_MAX) { | |
| 916 | + const long aslong = (long)wholepart; | |
| 917 | + return PyInt_FromLong(aslong); | |
| 918 | + } | |
| 919 | + return PyLong_FromDouble(wholepart); | |
| 920 | +} | |
| 921 | + | |
| 922 | +static PyObject * | |
| 923 | +float_float(PyObject *v) | |
| 924 | +{ | |
| 925 | + if (PyFloat_CheckExact(v)) | |
| 926 | + Py_INCREF(v); | |
| 927 | + else | |
| 928 | + v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); | |
| 929 | + return v; | |
| 930 | +} | |
| 931 | + | |
| 932 | + | |
| 933 | +static PyObject * | |
| 934 | +float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); | |
| 935 | + | |
| 936 | +static PyObject * | |
| 937 | +float_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 938 | +{ | |
| 939 | + PyObject *x = Py_False; /* Integer zero */ | |
| 940 | + static char *kwlist[] = {"x", 0}; | |
| 941 | + | |
| 942 | + if (type != &PyFloat_Type) | |
| 943 | + return float_subtype_new(type, args, kwds); /* Wimp out */ | |
| 944 | + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x)) | |
| 945 | + return NULL; | |
| 946 | + if (PyString_Check(x)) | |
| 947 | + return PyFloat_FromString(x, NULL); | |
| 948 | + return PyNumber_Float(x); | |
| 949 | +} | |
| 950 | + | |
| 951 | +/* Wimpy, slow approach to tp_new calls for subtypes of float: | |
| 952 | + first create a regular float from whatever arguments we got, | |
| 953 | + then allocate a subtype instance and initialize its ob_fval | |
| 954 | + from the regular float. The regular float is then thrown away. | |
| 955 | +*/ | |
| 956 | +static PyObject * | |
| 957 | +float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 958 | +{ | |
| 959 | + PyObject *tmp, *newobj; | |
| 960 | + | |
| 961 | + assert(PyType_IsSubtype(type, &PyFloat_Type)); | |
| 962 | + tmp = float_new(&PyFloat_Type, args, kwds); | |
| 963 | + if (tmp == NULL) | |
| 964 | + return NULL; | |
| 965 | + assert(PyFloat_CheckExact(tmp)); | |
| 966 | + newobj = type->tp_alloc(type, 0); | |
| 967 | + if (newobj == NULL) { | |
| 968 | + Py_DECREF(tmp); | |
| 969 | + return NULL; | |
| 970 | + } | |
| 971 | + ((PyFloatObject *)newobj)->ob_fval = ((PyFloatObject *)tmp)->ob_fval; | |
| 972 | + Py_DECREF(tmp); | |
| 973 | + return newobj; | |
| 974 | +} | |
| 975 | + | |
| 976 | +static PyObject * | |
| 977 | +float_getnewargs(PyFloatObject *v) | |
| 978 | +{ | |
| 979 | + return Py_BuildValue("(d)", v->ob_fval); | |
| 980 | +} | |
| 981 | + | |
| 982 | +/* this is for the benefit of the pack/unpack routines below */ | |
| 983 | + | |
| 984 | +typedef enum { | |
| 985 | + unknown_format, ieee_big_endian_format, ieee_little_endian_format | |
| 986 | +} float_format_type; | |
| 987 | + | |
| 988 | +static float_format_type double_format, float_format; | |
| 989 | +static float_format_type detected_double_format, detected_float_format; | |
| 990 | + | |
| 991 | +static PyObject * | |
| 992 | +float_getformat(PyTypeObject *v, PyObject* arg) | |
| 993 | +{ | |
| 994 | + char* s; | |
| 995 | + float_format_type r; | |
| 996 | + | |
| 997 | + if (!PyString_Check(arg)) { | |
| 998 | + PyErr_Format(PyExc_TypeError, | |
| 999 | + "__getformat__() argument must be string, not %.500s", | |
| 1000 | + arg->ob_type->tp_name); | |
| 1001 | + return NULL; | |
| 1002 | + } | |
| 1003 | + s = PyString_AS_STRING(arg); | |
| 1004 | + if (strcmp(s, "double") == 0) { | |
| 1005 | + r = double_format; | |
| 1006 | + } | |
| 1007 | + else if (strcmp(s, "float") == 0) { | |
| 1008 | + r = float_format; | |
| 1009 | + } | |
| 1010 | + else { | |
| 1011 | + PyErr_SetString(PyExc_ValueError, | |
| 1012 | + "__getformat__() argument 1 must be " | |
| 1013 | + "'double' or 'float'"); | |
| 1014 | + return NULL; | |
| 1015 | + } | |
| 1016 | + | |
| 1017 | + switch (r) { | |
| 1018 | + case unknown_format: | |
| 1019 | + return PyString_FromString("unknown"); | |
| 1020 | + case ieee_little_endian_format: | |
| 1021 | + return PyString_FromString("IEEE, little-endian"); | |
| 1022 | + case ieee_big_endian_format: | |
| 1023 | + return PyString_FromString("IEEE, big-endian"); | |
| 1024 | + default: | |
| 1025 | + Py_FatalError("insane float_format or double_format"); | |
| 1026 | + return NULL; | |
| 1027 | + } | |
| 1028 | +} | |
| 1029 | + | |
| 1030 | +PyDoc_STRVAR(float_getformat_doc, | |
| 1031 | +"float.__getformat__(tstr) -> string\n" | |
| 1032 | +"\n" | |
| 1033 | +"You probably don't want to use this function. It exists mainly to be\n" | |
| 1034 | +"used in Python's test suite.\n" | |
| 1035 | +"\n" | |
| 1036 | +"tstr must be 'double' or 'float'. This function returns whichever of\n" | |
| 1037 | +"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n" | |
| 1038 | +"format of floating point numbers used by the C type named by tstr."); | |
| 1039 | + | |
| 1040 | +static PyObject * | |
| 1041 | +float_setformat(PyTypeObject *v, PyObject* args) | |
| 1042 | +{ | |
| 1043 | + char* tstr; | |
| 1044 | + char* format; | |
| 1045 | + float_format_type f; | |
| 1046 | + float_format_type detected; | |
| 1047 | + float_format_type *p; | |
| 1048 | + | |
| 1049 | + if (!PyArg_ParseTuple(args, "ss:__setformat__", &tstr, &format)) | |
| 1050 | + return NULL; | |
| 1051 | + | |
| 1052 | + if (strcmp(tstr, "double") == 0) { | |
| 1053 | + p = &double_format; | |
| 1054 | + detected = detected_double_format; | |
| 1055 | + } | |
| 1056 | + else if (strcmp(tstr, "float") == 0) { | |
| 1057 | + p = &float_format; | |
| 1058 | + detected = detected_float_format; | |
| 1059 | + } | |
| 1060 | + else { | |
| 1061 | + PyErr_SetString(PyExc_ValueError, | |
| 1062 | + "__setformat__() argument 1 must " | |
| 1063 | + "be 'double' or 'float'"); | |
| 1064 | + return NULL; | |
| 1065 | + } | |
| 1066 | + | |
| 1067 | + if (strcmp(format, "unknown") == 0) { | |
| 1068 | + f = unknown_format; | |
| 1069 | + } | |
| 1070 | + else if (strcmp(format, "IEEE, little-endian") == 0) { | |
| 1071 | + f = ieee_little_endian_format; | |
| 1072 | + } | |
| 1073 | + else if (strcmp(format, "IEEE, big-endian") == 0) { | |
| 1074 | + f = ieee_big_endian_format; | |
| 1075 | + } | |
| 1076 | + else { | |
| 1077 | + PyErr_SetString(PyExc_ValueError, | |
| 1078 | + "__setformat__() argument 2 must be " | |
| 1079 | + "'unknown', 'IEEE, little-endian' or " | |
| 1080 | + "'IEEE, big-endian'"); | |
| 1081 | + return NULL; | |
| 1082 | + | |
| 1083 | + } | |
| 1084 | + | |
| 1085 | + if (f != unknown_format && f != detected) { | |
| 1086 | + PyErr_Format(PyExc_ValueError, | |
| 1087 | + "can only set %s format to 'unknown' or the " | |
| 1088 | + "detected platform value", tstr); | |
| 1089 | + return NULL; | |
| 1090 | + } | |
| 1091 | + | |
| 1092 | + *p = f; | |
| 1093 | + Py_RETURN_NONE; | |
| 1094 | +} | |
| 1095 | + | |
| 1096 | +PyDoc_STRVAR(float_setformat_doc, | |
| 1097 | +"float.__setformat__(tstr, fmt) -> None\n" | |
| 1098 | +"\n" | |
| 1099 | +"You probably don't want to use this function. It exists mainly to be\n" | |
| 1100 | +"used in Python's test suite.\n" | |
| 1101 | +"\n" | |
| 1102 | +"tstr must be 'double' or 'float'. fmt must be one of 'unknown',\n" | |
| 1103 | +"'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n" | |
| 1104 | +"one of the latter two if it appears to match the underlying C reality.\n" | |
| 1105 | +"\n" | |
| 1106 | +"Overrides the automatic determination of C-level floating point type.\n" | |
| 1107 | +"This affects how floats are converted to and from binary strings."); | |
| 1108 | + | |
| 1109 | +static PyMethodDef float_methods[] = { | |
| 1110 | + {"__getnewargs__", (PyCFunction)float_getnewargs, METH_NOARGS}, | |
| 1111 | + {"__getformat__", (PyCFunction)float_getformat, | |
| 1112 | + METH_O|METH_CLASS, float_getformat_doc}, | |
| 1113 | + {"__setformat__", (PyCFunction)float_setformat, | |
| 1114 | + METH_VARARGS|METH_CLASS, float_setformat_doc}, | |
| 1115 | + {NULL, NULL} /* sentinel */ | |
| 1116 | +}; | |
| 1117 | + | |
| 1118 | +PyDoc_STRVAR(float_doc, | |
| 1119 | +"float(x) -> floating point number\n\ | |
| 1120 | +\n\ | |
| 1121 | +Convert a string or number to a floating point number, if possible."); | |
| 1122 | + | |
| 1123 | + | |
| 1124 | +static PyNumberMethods float_as_number = { | |
| 1125 | + float_add, /*nb_add*/ | |
| 1126 | + float_sub, /*nb_subtract*/ | |
| 1127 | + float_mul, /*nb_multiply*/ | |
| 1128 | + float_classic_div, /*nb_divide*/ | |
| 1129 | + float_rem, /*nb_remainder*/ | |
| 1130 | + float_divmod, /*nb_divmod*/ | |
| 1131 | + float_pow, /*nb_power*/ | |
| 1132 | + (unaryfunc)float_neg, /*nb_negative*/ | |
| 1133 | + (unaryfunc)float_pos, /*nb_positive*/ | |
| 1134 | + (unaryfunc)float_abs, /*nb_absolute*/ | |
| 1135 | + (inquiry)float_nonzero, /*nb_nonzero*/ | |
| 1136 | + 0, /*nb_invert*/ | |
| 1137 | + 0, /*nb_lshift*/ | |
| 1138 | + 0, /*nb_rshift*/ | |
| 1139 | + 0, /*nb_and*/ | |
| 1140 | + 0, /*nb_xor*/ | |
| 1141 | + 0, /*nb_or*/ | |
| 1142 | + float_coerce, /*nb_coerce*/ | |
| 1143 | + float_int, /*nb_int*/ | |
| 1144 | + float_long, /*nb_long*/ | |
| 1145 | + float_float, /*nb_float*/ | |
| 1146 | + 0, /* nb_oct */ | |
| 1147 | + 0, /* nb_hex */ | |
| 1148 | + 0, /* nb_inplace_add */ | |
| 1149 | + 0, /* nb_inplace_subtract */ | |
| 1150 | + 0, /* nb_inplace_multiply */ | |
| 1151 | + 0, /* nb_inplace_divide */ | |
| 1152 | + 0, /* nb_inplace_remainder */ | |
| 1153 | + 0, /* nb_inplace_power */ | |
| 1154 | + 0, /* nb_inplace_lshift */ | |
| 1155 | + 0, /* nb_inplace_rshift */ | |
| 1156 | + 0, /* nb_inplace_and */ | |
| 1157 | + 0, /* nb_inplace_xor */ | |
| 1158 | + 0, /* nb_inplace_or */ | |
| 1159 | + float_floor_div, /* nb_floor_divide */ | |
| 1160 | + float_div, /* nb_true_divide */ | |
| 1161 | + 0, /* nb_inplace_floor_divide */ | |
| 1162 | + 0, /* nb_inplace_true_divide */ | |
| 1163 | +}; | |
| 1164 | + | |
| 1165 | +PyTypeObject PyFloat_Type = { | |
| 1166 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 1167 | + 0, | |
| 1168 | + "float", | |
| 1169 | + sizeof(PyFloatObject), | |
| 1170 | + 0, | |
| 1171 | + (destructor)float_dealloc, /* tp_dealloc */ | |
| 1172 | + (printfunc)float_print, /* tp_print */ | |
| 1173 | + 0, /* tp_getattr */ | |
| 1174 | + 0, /* tp_setattr */ | |
| 1175 | + 0, /* tp_compare */ | |
| 1176 | + (reprfunc)float_repr, /* tp_repr */ | |
| 1177 | + &float_as_number, /* tp_as_number */ | |
| 1178 | + 0, /* tp_as_sequence */ | |
| 1179 | + 0, /* tp_as_mapping */ | |
| 1180 | + (hashfunc)float_hash, /* tp_hash */ | |
| 1181 | + 0, /* tp_call */ | |
| 1182 | + (reprfunc)float_str, /* tp_str */ | |
| 1183 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 1184 | + 0, /* tp_setattro */ | |
| 1185 | + 0, /* tp_as_buffer */ | |
| 1186 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | | |
| 1187 | + Py_TPFLAGS_BASETYPE, /* tp_flags */ | |
| 1188 | + float_doc, /* tp_doc */ | |
| 1189 | + 0, /* tp_traverse */ | |
| 1190 | + 0, /* tp_clear */ | |
| 1191 | + float_richcompare, /* tp_richcompare */ | |
| 1192 | + 0, /* tp_weaklistoffset */ | |
| 1193 | + 0, /* tp_iter */ | |
| 1194 | + 0, /* tp_iternext */ | |
| 1195 | + float_methods, /* tp_methods */ | |
| 1196 | + 0, /* tp_members */ | |
| 1197 | + 0, /* tp_getset */ | |
| 1198 | + 0, /* tp_base */ | |
| 1199 | + 0, /* tp_dict */ | |
| 1200 | + 0, /* tp_descr_get */ | |
| 1201 | + 0, /* tp_descr_set */ | |
| 1202 | + 0, /* tp_dictoffset */ | |
| 1203 | + 0, /* tp_init */ | |
| 1204 | + 0, /* tp_alloc */ | |
| 1205 | + float_new, /* tp_new */ | |
| 1206 | +}; | |
| 1207 | + | |
| 1208 | +void | |
| 1209 | +_PyFloat_Init(void) | |
| 1210 | +{ | |
| 1211 | + /* We attempt to determine if this machine is using IEEE | |
| 1212 | + floating point formats by peering at the bits of some | |
| 1213 | + carefully chosen values. If it looks like we are on an | |
| 1214 | + IEEE platform, the float packing/unpacking routines can | |
| 1215 | + just copy bits, if not they resort to arithmetic & shifts | |
| 1216 | + and masks. The shifts & masks approach works on all finite | |
| 1217 | + values, but what happens to infinities, NaNs and signed | |
| 1218 | + zeroes on packing is an accident, and attempting to unpack | |
| 1219 | + a NaN or an infinity will raise an exception. | |
| 1220 | + | |
| 1221 | + Note that if we're on some whacked-out platform which uses | |
| 1222 | + IEEE formats but isn't strictly little-endian or big- | |
| 1223 | + endian, we will fall back to the portable shifts & masks | |
| 1224 | + method. */ | |
| 1225 | + | |
| 1226 | +#if SIZEOF_DOUBLE == 8 | |
| 1227 | + { | |
| 1228 | + double x = 9006104071832581.0; | |
| 1229 | + if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) | |
| 1230 | + detected_double_format = ieee_big_endian_format; | |
| 1231 | + else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) | |
| 1232 | + detected_double_format = ieee_little_endian_format; | |
| 1233 | + else | |
| 1234 | + detected_double_format = unknown_format; | |
| 1235 | + } | |
| 1236 | +#else | |
| 1237 | + detected_double_format = unknown_format; | |
| 1238 | +#endif | |
| 1239 | + | |
| 1240 | +#if SIZEOF_FLOAT == 4 | |
| 1241 | + { | |
| 1242 | + float y = 16711938.0; | |
| 1243 | + if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0) | |
| 1244 | + detected_float_format = ieee_big_endian_format; | |
| 1245 | + else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0) | |
| 1246 | + detected_float_format = ieee_little_endian_format; | |
| 1247 | + else | |
| 1248 | + detected_float_format = unknown_format; | |
| 1249 | + } | |
| 1250 | +#else | |
| 1251 | + detected_float_format = unknown_format; | |
| 1252 | +#endif | |
| 1253 | + | |
| 1254 | + double_format = detected_double_format; | |
| 1255 | + float_format = detected_float_format; | |
| 1256 | +} | |
| 1257 | + | |
| 1258 | +void | |
| 1259 | +PyFloat_Fini(void) | |
| 1260 | +{ | |
| 1261 | + PyFloatObject *p; | |
| 1262 | + PyFloatBlock *list, *next; | |
| 1263 | + unsigned i; | |
| 1264 | + int bc, bf; /* block count, number of freed blocks */ | |
| 1265 | + int frem, fsum; /* remaining unfreed floats per block, total */ | |
| 1266 | + | |
| 1267 | + bc = 0; | |
| 1268 | + bf = 0; | |
| 1269 | + fsum = 0; | |
| 1270 | + list = block_list; | |
| 1271 | + block_list = NULL; | |
| 1272 | + free_list = NULL; | |
| 1273 | + while (list != NULL) { | |
| 1274 | + bc++; | |
| 1275 | + frem = 0; | |
| 1276 | + for (i = 0, p = &list->objects[0]; | |
| 1277 | + i < N_FLOATOBJECTS; | |
| 1278 | + i++, p++) { | |
| 1279 | + if (PyFloat_CheckExact(p) && p->ob_refcnt != 0) | |
| 1280 | + frem++; | |
| 1281 | + } | |
| 1282 | + next = list->next; | |
| 1283 | + if (frem) { | |
| 1284 | + list->next = block_list; | |
| 1285 | + block_list = list; | |
| 1286 | + for (i = 0, p = &list->objects[0]; | |
| 1287 | + i < N_FLOATOBJECTS; | |
| 1288 | + i++, p++) { | |
| 1289 | + if (!PyFloat_CheckExact(p) || | |
| 1290 | + p->ob_refcnt == 0) { | |
| 1291 | + p->ob_type = (struct _typeobject *) | |
| 1292 | + free_list; | |
| 1293 | + free_list = p; | |
| 1294 | + } | |
| 1295 | + } | |
| 1296 | + } | |
| 1297 | + else { | |
| 1298 | + PyMem_FREE(list); /* XXX PyObject_FREE ??? */ | |
| 1299 | + bf++; | |
| 1300 | + } | |
| 1301 | + fsum += frem; | |
| 1302 | + list = next; | |
| 1303 | + } | |
| 1304 | + if (!Py_VerboseFlag) | |
| 1305 | + return; | |
| 1306 | + fprintf(stderr, "# cleanup floats"); | |
| 1307 | + if (!fsum) { | |
| 1308 | + fprintf(stderr, "\n"); | |
| 1309 | + } | |
| 1310 | + else { | |
| 1311 | + fprintf(stderr, | |
| 1312 | + ": %d unfreed float%s in %d out of %d block%s\n", | |
| 1313 | + fsum, fsum == 1 ? "" : "s", | |
| 1314 | + bc - bf, bc, bc == 1 ? "" : "s"); | |
| 1315 | + } | |
| 1316 | + if (Py_VerboseFlag > 1) { | |
| 1317 | + list = block_list; | |
| 1318 | + while (list != NULL) { | |
| 1319 | + for (i = 0, p = &list->objects[0]; | |
| 1320 | + i < N_FLOATOBJECTS; | |
| 1321 | + i++, p++) { | |
| 1322 | + if (PyFloat_CheckExact(p) && | |
| 1323 | + p->ob_refcnt != 0) { | |
| 1324 | + char buf[100]; | |
| 1325 | + PyFloat_AsString(buf, p); | |
| 1326 | + /* XXX(twouters) cast refcount to | |
| 1327 | + long until %zd is universally | |
| 1328 | + available | |
| 1329 | + */ | |
| 1330 | + fprintf(stderr, | |
| 1331 | + "# <float at %p, refcnt=%ld, val=%s>\n", | |
| 1332 | + p, (long)p->ob_refcnt, buf); | |
| 1333 | + } | |
| 1334 | + } | |
| 1335 | + list = list->next; | |
| 1336 | + } | |
| 1337 | + } | |
| 1338 | +} | |
| 1339 | + | |
| 1340 | +/*---------------------------------------------------------------------------- | |
| 1341 | + * _PyFloat_{Pack,Unpack}{4,8}. See floatobject.h. | |
| 1342 | + * | |
| 1343 | + * TODO: On platforms that use the standard IEEE-754 single and double | |
| 1344 | + * formats natively, these routines could simply copy the bytes. | |
| 1345 | + */ | |
| 1346 | +int | |
| 1347 | +_PyFloat_Pack4(double x, unsigned char *p, int le) | |
| 1348 | +{ | |
| 1349 | + if (float_format == unknown_format) { | |
| 1350 | + unsigned char sign; | |
| 1351 | + int e; | |
| 1352 | + double f; | |
| 1353 | + unsigned int fbits; | |
| 1354 | + int incr = 1; | |
| 1355 | + | |
| 1356 | + if (le) { | |
| 1357 | + p += 3; | |
| 1358 | + incr = -1; | |
| 1359 | + } | |
| 1360 | + | |
| 1361 | + if (x < 0) { | |
| 1362 | + sign = 1; | |
| 1363 | + x = -x; | |
| 1364 | + } | |
| 1365 | + else | |
| 1366 | + sign = 0; | |
| 1367 | + | |
| 1368 | + f = frexp(x, &e); | |
| 1369 | + | |
| 1370 | + /* Normalize f to be in the range [1.0, 2.0) */ | |
| 1371 | + if (0.5 <= f && f < 1.0) { | |
| 1372 | + f *= 2.0; | |
| 1373 | + e--; | |
| 1374 | + } | |
| 1375 | + else if (f == 0.0) | |
| 1376 | + e = 0; | |
| 1377 | + else { | |
| 1378 | + PyErr_SetString(PyExc_SystemError, | |
| 1379 | + "frexp() result out of range"); | |
| 1380 | + return -1; | |
| 1381 | + } | |
| 1382 | + | |
| 1383 | + if (e >= 128) | |
| 1384 | + goto Overflow; | |
| 1385 | + else if (e < -126) { | |
| 1386 | + /* Gradual underflow */ | |
| 1387 | + f = ldexp(f, 126 + e); | |
| 1388 | + e = 0; | |
| 1389 | + } | |
| 1390 | + else if (!(e == 0 && f == 0.0)) { | |
| 1391 | + e += 127; | |
| 1392 | + f -= 1.0; /* Get rid of leading 1 */ | |
| 1393 | + } | |
| 1394 | + | |
| 1395 | + f *= 8388608.0; /* 2**23 */ | |
| 1396 | + fbits = (unsigned int)(f + 0.5); /* Round */ | |
| 1397 | + assert(fbits <= 8388608); | |
| 1398 | + if (fbits >> 23) { | |
| 1399 | + /* The carry propagated out of a string of 23 1 bits. */ | |
| 1400 | + fbits = 0; | |
| 1401 | + ++e; | |
| 1402 | + if (e >= 255) | |
| 1403 | + goto Overflow; | |
| 1404 | + } | |
| 1405 | + | |
| 1406 | + /* First byte */ | |
| 1407 | + *p = (sign << 7) | (e >> 1); | |
| 1408 | + p += incr; | |
| 1409 | + | |
| 1410 | + /* Second byte */ | |
| 1411 | + *p = (char) (((e & 1) << 7) | (fbits >> 16)); | |
| 1412 | + p += incr; | |
| 1413 | + | |
| 1414 | + /* Third byte */ | |
| 1415 | + *p = (fbits >> 8) & 0xFF; | |
| 1416 | + p += incr; | |
| 1417 | + | |
| 1418 | + /* Fourth byte */ | |
| 1419 | + *p = fbits & 0xFF; | |
| 1420 | + | |
| 1421 | + /* Done */ | |
| 1422 | + return 0; | |
| 1423 | + | |
| 1424 | + Overflow: | |
| 1425 | + PyErr_SetString(PyExc_OverflowError, | |
| 1426 | + "float too large to pack with f format"); | |
| 1427 | + return -1; | |
| 1428 | + } | |
| 1429 | + else { | |
| 1430 | + float y = (float)x; | |
| 1431 | + const char *s = (char*)&y; | |
| 1432 | + int i, incr = 1; | |
| 1433 | + | |
| 1434 | + if ((float_format == ieee_little_endian_format && !le) | |
| 1435 | + || (float_format == ieee_big_endian_format && le)) { | |
| 1436 | + p += 3; | |
| 1437 | + incr = -1; | |
| 1438 | + } | |
| 1439 | + | |
| 1440 | + for (i = 0; i < 4; i++) { | |
| 1441 | + *p = *s++; | |
| 1442 | + p += incr; | |
| 1443 | + } | |
| 1444 | + return 0; | |
| 1445 | + } | |
| 1446 | +} | |
| 1447 | + | |
| 1448 | +int | |
| 1449 | +_PyFloat_Pack8(double x, unsigned char *p, int le) | |
| 1450 | +{ | |
| 1451 | + if (double_format == unknown_format) { | |
| 1452 | + unsigned char sign; | |
| 1453 | + int e; | |
| 1454 | + double f; | |
| 1455 | + unsigned int fhi, flo; | |
| 1456 | + int incr = 1; | |
| 1457 | + | |
| 1458 | + if (le) { | |
| 1459 | + p += 7; | |
| 1460 | + incr = -1; | |
| 1461 | + } | |
| 1462 | + | |
| 1463 | + if (x < 0) { | |
| 1464 | + sign = 1; | |
| 1465 | + x = -x; | |
| 1466 | + } | |
| 1467 | + else | |
| 1468 | + sign = 0; | |
| 1469 | + | |
| 1470 | + f = frexp(x, &e); | |
| 1471 | + | |
| 1472 | + /* Normalize f to be in the range [1.0, 2.0) */ | |
| 1473 | + if (0.5 <= f && f < 1.0) { | |
| 1474 | + f *= 2.0; | |
| 1475 | + e--; | |
| 1476 | + } | |
| 1477 | + else if (f == 0.0) | |
| 1478 | + e = 0; | |
| 1479 | + else { | |
| 1480 | + PyErr_SetString(PyExc_SystemError, | |
| 1481 | + "frexp() result out of range"); | |
| 1482 | + return -1; | |
| 1483 | + } | |
| 1484 | + | |
| 1485 | + if (e >= 1024) | |
| 1486 | + goto Overflow; | |
| 1487 | + else if (e < -1022) { | |
| 1488 | + /* Gradual underflow */ | |
| 1489 | + f = ldexp(f, 1022 + e); | |
| 1490 | + e = 0; | |
| 1491 | + } | |
| 1492 | + else if (!(e == 0 && f == 0.0)) { | |
| 1493 | + e += 1023; | |
| 1494 | + f -= 1.0; /* Get rid of leading 1 */ | |
| 1495 | + } | |
| 1496 | + | |
| 1497 | + /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ | |
| 1498 | + f *= 268435456.0; /* 2**28 */ | |
| 1499 | + fhi = (unsigned int)f; /* Truncate */ | |
| 1500 | + assert(fhi < 268435456); | |
| 1501 | + | |
| 1502 | + f -= (double)fhi; | |
| 1503 | + f *= 16777216.0; /* 2**24 */ | |
| 1504 | + flo = (unsigned int)(f + 0.5); /* Round */ | |
| 1505 | + assert(flo <= 16777216); | |
| 1506 | + if (flo >> 24) { | |
| 1507 | + /* The carry propagated out of a string of 24 1 bits. */ | |
| 1508 | + flo = 0; | |
| 1509 | + ++fhi; | |
| 1510 | + if (fhi >> 28) { | |
| 1511 | + /* And it also progagated out of the next 28 bits. */ | |
| 1512 | + fhi = 0; | |
| 1513 | + ++e; | |
| 1514 | + if (e >= 2047) | |
| 1515 | + goto Overflow; | |
| 1516 | + } | |
| 1517 | + } | |
| 1518 | + | |
| 1519 | + /* First byte */ | |
| 1520 | + *p = (sign << 7) | (e >> 4); | |
| 1521 | + p += incr; | |
| 1522 | + | |
| 1523 | + /* Second byte */ | |
| 1524 | + *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24)); | |
| 1525 | + p += incr; | |
| 1526 | + | |
| 1527 | + /* Third byte */ | |
| 1528 | + *p = (fhi >> 16) & 0xFF; | |
| 1529 | + p += incr; | |
| 1530 | + | |
| 1531 | + /* Fourth byte */ | |
| 1532 | + *p = (fhi >> 8) & 0xFF; | |
| 1533 | + p += incr; | |
| 1534 | + | |
| 1535 | + /* Fifth byte */ | |
| 1536 | + *p = fhi & 0xFF; | |
| 1537 | + p += incr; | |
| 1538 | + | |
| 1539 | + /* Sixth byte */ | |
| 1540 | + *p = (flo >> 16) & 0xFF; | |
| 1541 | + p += incr; | |
| 1542 | + | |
| 1543 | + /* Seventh byte */ | |
| 1544 | + *p = (flo >> 8) & 0xFF; | |
| 1545 | + p += incr; | |
| 1546 | + | |
| 1547 | + /* Eighth byte */ | |
| 1548 | + *p = flo & 0xFF; | |
| 1549 | + p += incr; | |
| 1550 | + | |
| 1551 | + /* Done */ | |
| 1552 | + return 0; | |
| 1553 | + | |
| 1554 | + Overflow: | |
| 1555 | + PyErr_SetString(PyExc_OverflowError, | |
| 1556 | + "float too large to pack with d format"); | |
| 1557 | + return -1; | |
| 1558 | + } | |
| 1559 | + else { | |
| 1560 | + const char *s = (char*)&x; | |
| 1561 | + int i, incr = 1; | |
| 1562 | + | |
| 1563 | + if ((double_format == ieee_little_endian_format && !le) | |
| 1564 | + || (double_format == ieee_big_endian_format && le)) { | |
| 1565 | + p += 7; | |
| 1566 | + incr = -1; | |
| 1567 | + } | |
| 1568 | + | |
| 1569 | + for (i = 0; i < 8; i++) { | |
| 1570 | + *p = *s++; | |
| 1571 | + p += incr; | |
| 1572 | + } | |
| 1573 | + return 0; | |
| 1574 | + } | |
| 1575 | +} | |
| 1576 | + | |
| 1577 | +double | |
| 1578 | +_PyFloat_Unpack4(const unsigned char *p, int le) | |
| 1579 | +{ | |
| 1580 | + if (float_format == unknown_format) { | |
| 1581 | + unsigned char sign; | |
| 1582 | + int e; | |
| 1583 | + unsigned int f; | |
| 1584 | + double x; | |
| 1585 | + int incr = 1; | |
| 1586 | + | |
| 1587 | + if (le) { | |
| 1588 | + p += 3; | |
| 1589 | + incr = -1; | |
| 1590 | + } | |
| 1591 | + | |
| 1592 | + /* First byte */ | |
| 1593 | + sign = (*p >> 7) & 1; | |
| 1594 | + e = (*p & 0x7F) << 1; | |
| 1595 | + p += incr; | |
| 1596 | + | |
| 1597 | + /* Second byte */ | |
| 1598 | + e |= (*p >> 7) & 1; | |
| 1599 | + f = (*p & 0x7F) << 16; | |
| 1600 | + p += incr; | |
| 1601 | + | |
| 1602 | + if (e == 255) { | |
| 1603 | + PyErr_SetString( | |
| 1604 | + PyExc_ValueError, | |
| 1605 | + "can't unpack IEEE 754 special value " | |
| 1606 | + "on non-IEEE platform"); | |
| 1607 | + return -1; | |
| 1608 | + } | |
| 1609 | + | |
| 1610 | + /* Third byte */ | |
| 1611 | + f |= *p << 8; | |
| 1612 | + p += incr; | |
| 1613 | + | |
| 1614 | + /* Fourth byte */ | |
| 1615 | + f |= *p; | |
| 1616 | + | |
| 1617 | + x = (double)f / 8388608.0; | |
| 1618 | + | |
| 1619 | + /* XXX This sadly ignores Inf/NaN issues */ | |
| 1620 | + if (e == 0) | |
| 1621 | + e = -126; | |
| 1622 | + else { | |
| 1623 | + x += 1.0; | |
| 1624 | + e -= 127; | |
| 1625 | + } | |
| 1626 | + x = ldexp(x, e); | |
| 1627 | + | |
| 1628 | + if (sign) | |
| 1629 | + x = -x; | |
| 1630 | + | |
| 1631 | + return x; | |
| 1632 | + } | |
| 1633 | + else { | |
| 1634 | + float x; | |
| 1635 | + | |
| 1636 | + if ((float_format == ieee_little_endian_format && !le) | |
| 1637 | + || (float_format == ieee_big_endian_format && le)) { | |
| 1638 | + char buf[4]; | |
| 1639 | + char *d = &buf[3]; | |
| 1640 | + int i; | |
| 1641 | + | |
| 1642 | + for (i = 0; i < 4; i++) { | |
| 1643 | + *d-- = *p++; | |
| 1644 | + } | |
| 1645 | + memcpy(&x, buf, 4); | |
| 1646 | + } | |
| 1647 | + else { | |
| 1648 | + memcpy(&x, p, 4); | |
| 1649 | + } | |
| 1650 | + | |
| 1651 | + return x; | |
| 1652 | + } | |
| 1653 | +} | |
| 1654 | + | |
| 1655 | +double | |
| 1656 | +_PyFloat_Unpack8(const unsigned char *p, int le) | |
| 1657 | +{ | |
| 1658 | + if (double_format == unknown_format) { | |
| 1659 | + unsigned char sign; | |
| 1660 | + int e; | |
| 1661 | + unsigned int fhi, flo; | |
| 1662 | + double x; | |
| 1663 | + int incr = 1; | |
| 1664 | + | |
| 1665 | + if (le) { | |
| 1666 | + p += 7; | |
| 1667 | + incr = -1; | |
| 1668 | + } | |
| 1669 | + | |
| 1670 | + /* First byte */ | |
| 1671 | + sign = (*p >> 7) & 1; | |
| 1672 | + e = (*p & 0x7F) << 4; | |
| 1673 | + | |
| 1674 | + p += incr; | |
| 1675 | + | |
| 1676 | + /* Second byte */ | |
| 1677 | + e |= (*p >> 4) & 0xF; | |
| 1678 | + fhi = (*p & 0xF) << 24; | |
| 1679 | + p += incr; | |
| 1680 | + | |
| 1681 | + if (e == 2047) { | |
| 1682 | + PyErr_SetString( | |
| 1683 | + PyExc_ValueError, | |
| 1684 | + "can't unpack IEEE 754 special value " | |
| 1685 | + "on non-IEEE platform"); | |
| 1686 | + return -1.0; | |
| 1687 | + } | |
| 1688 | + | |
| 1689 | + /* Third byte */ | |
| 1690 | + fhi |= *p << 16; | |
| 1691 | + p += incr; | |
| 1692 | + | |
| 1693 | + /* Fourth byte */ | |
| 1694 | + fhi |= *p << 8; | |
| 1695 | + p += incr; | |
| 1696 | + | |
| 1697 | + /* Fifth byte */ | |
| 1698 | + fhi |= *p; | |
| 1699 | + p += incr; | |
| 1700 | + | |
| 1701 | + /* Sixth byte */ | |
| 1702 | + flo = *p << 16; | |
| 1703 | + p += incr; | |
| 1704 | + | |
| 1705 | + /* Seventh byte */ | |
| 1706 | + flo |= *p << 8; | |
| 1707 | + p += incr; | |
| 1708 | + | |
| 1709 | + /* Eighth byte */ | |
| 1710 | + flo |= *p; | |
| 1711 | + | |
| 1712 | + x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ | |
| 1713 | + x /= 268435456.0; /* 2**28 */ | |
| 1714 | + | |
| 1715 | + if (e == 0) | |
| 1716 | + e = -1022; | |
| 1717 | + else { | |
| 1718 | + x += 1.0; | |
| 1719 | + e -= 1023; | |
| 1720 | + } | |
| 1721 | + x = ldexp(x, e); | |
| 1722 | + | |
| 1723 | + if (sign) | |
| 1724 | + x = -x; | |
| 1725 | + | |
| 1726 | + return x; | |
| 1727 | + } | |
| 1728 | + else { | |
| 1729 | + double x; | |
| 1730 | + | |
| 1731 | + if ((double_format == ieee_little_endian_format && !le) | |
| 1732 | + || (double_format == ieee_big_endian_format && le)) { | |
| 1733 | + char buf[8]; | |
| 1734 | + char *d = &buf[7]; | |
| 1735 | + int i; | |
| 1736 | + | |
| 1737 | + for (i = 0; i < 8; i++) { | |
| 1738 | + *d-- = *p++; | |
| 1739 | + } | |
| 1740 | + memcpy(&x, buf, 8); | |
| 1741 | + } | |
| 1742 | + else { | |
| 1743 | + memcpy(&x, p, 8); | |
| 1744 | + } | |
| 1745 | + | |
| 1746 | + return x; | |
| 1747 | + } | |
| 1748 | +} | |
| @@ -0,0 +1,849 @@ | ||
| 1 | +/* Frame object implementation */ | |
| 2 | + | |
| 3 | +#include "Python.h" | |
| 4 | + | |
| 5 | +#include "code.h" | |
| 6 | +#include "frameobject.h" | |
| 7 | +#include "opcode.h" | |
| 8 | +#include "structmember.h" | |
| 9 | + | |
| 10 | +#undef MIN | |
| 11 | +#undef MAX | |
| 12 | +#define MIN(a, b) ((a) < (b) ? (a) : (b)) | |
| 13 | +#define MAX(a, b) ((a) > (b) ? (a) : (b)) | |
| 14 | + | |
| 15 | +#define OFF(x) offsetof(PyFrameObject, x) | |
| 16 | + | |
| 17 | +static PyMemberDef frame_memberlist[] = { | |
| 18 | + {"f_back", T_OBJECT, OFF(f_back), RO}, | |
| 19 | + {"f_code", T_OBJECT, OFF(f_code), RO}, | |
| 20 | + {"f_builtins", T_OBJECT, OFF(f_builtins),RO}, | |
| 21 | + {"f_globals", T_OBJECT, OFF(f_globals), RO}, | |
| 22 | + {"f_lasti", T_INT, OFF(f_lasti), RO}, | |
| 23 | + {"f_exc_type", T_OBJECT, OFF(f_exc_type)}, | |
| 24 | + {"f_exc_value", T_OBJECT, OFF(f_exc_value)}, | |
| 25 | + {"f_exc_traceback", T_OBJECT, OFF(f_exc_traceback)}, | |
| 26 | + {NULL} /* Sentinel */ | |
| 27 | +}; | |
| 28 | + | |
| 29 | +static PyObject * | |
| 30 | +frame_getlocals(PyFrameObject *f, void *closure) | |
| 31 | +{ | |
| 32 | + PyFrame_FastToLocals(f); | |
| 33 | + Py_INCREF(f->f_locals); | |
| 34 | + return f->f_locals; | |
| 35 | +} | |
| 36 | + | |
| 37 | +static PyObject * | |
| 38 | +frame_getlineno(PyFrameObject *f, void *closure) | |
| 39 | +{ | |
| 40 | + int lineno; | |
| 41 | + | |
| 42 | + if (f->f_trace) | |
| 43 | + lineno = f->f_lineno; | |
| 44 | + else | |
| 45 | + lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); | |
| 46 | + | |
| 47 | + return PyInt_FromLong(lineno); | |
| 48 | +} | |
| 49 | + | |
| 50 | +/* Setter for f_lineno - you can set f_lineno from within a trace function in | |
| 51 | + * order to jump to a given line of code, subject to some restrictions. Most | |
| 52 | + * lines are OK to jump to because they don't make any assumptions about the | |
| 53 | + * state of the stack (obvious because you could remove the line and the code | |
| 54 | + * would still work without any stack errors), but there are some constructs | |
| 55 | + * that limit jumping: | |
| 56 | + * | |
| 57 | + * o Lines with an 'except' statement on them can't be jumped to, because | |
| 58 | + * they expect an exception to be on the top of the stack. | |
| 59 | + * o Lines that live in a 'finally' block can't be jumped from or to, since | |
| 60 | + * the END_FINALLY expects to clean up the stack after the 'try' block. | |
| 61 | + * o 'try'/'for'/'while' blocks can't be jumped into because the blockstack | |
| 62 | + * needs to be set up before their code runs, and for 'for' loops the | |
| 63 | + * iterator needs to be on the stack. | |
| 64 | + */ | |
| 65 | +static int | |
| 66 | +frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) | |
| 67 | +{ | |
| 68 | + int new_lineno = 0; /* The new value of f_lineno */ | |
| 69 | + int new_lasti = 0; /* The new value of f_lasti */ | |
| 70 | + int new_iblock = 0; /* The new value of f_iblock */ | |
| 71 | + char *code = NULL; /* The bytecode for the frame... */ | |
| 72 | + Py_ssize_t code_len = 0; /* ...and its length */ | |
| 73 | + char *lnotab = NULL; /* Iterating over co_lnotab */ | |
| 74 | + Py_ssize_t lnotab_len = 0; /* (ditto) */ | |
| 75 | + int offset = 0; /* (ditto) */ | |
| 76 | + int line = 0; /* (ditto) */ | |
| 77 | + int addr = 0; /* (ditto) */ | |
| 78 | + int min_addr = 0; /* Scanning the SETUPs and POPs */ | |
| 79 | + int max_addr = 0; /* (ditto) */ | |
| 80 | + int delta_iblock = 0; /* (ditto) */ | |
| 81 | + int min_delta_iblock = 0; /* (ditto) */ | |
| 82 | + int min_iblock = 0; /* (ditto) */ | |
| 83 | + int f_lasti_setup_addr = 0; /* Policing no-jump-into-finally */ | |
| 84 | + int new_lasti_setup_addr = 0; /* (ditto) */ | |
| 85 | + int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */ | |
| 86 | + int in_finally[CO_MAXBLOCKS]; /* (ditto) */ | |
| 87 | + int blockstack_top = 0; /* (ditto) */ | |
| 88 | + int setup_op = 0; /* (ditto) */ | |
| 89 | + | |
| 90 | + /* f_lineno must be an integer. */ | |
| 91 | + if (!PyInt_Check(p_new_lineno)) { | |
| 92 | + PyErr_SetString(PyExc_ValueError, | |
| 93 | + "lineno must be an integer"); | |
| 94 | + return -1; | |
| 95 | + } | |
| 96 | + | |
| 97 | + /* You can only do this from within a trace function, not via | |
| 98 | + * _getframe or similar hackery. */ | |
| 99 | + if (!f->f_trace) | |
| 100 | + { | |
| 101 | + PyErr_Format(PyExc_ValueError, | |
| 102 | + "f_lineno can only be set by a trace function"); | |
| 103 | + return -1; | |
| 104 | + } | |
| 105 | + | |
| 106 | + /* Fail if the line comes before the start of the code block. */ | |
| 107 | + new_lineno = (int) PyInt_AsLong(p_new_lineno); | |
| 108 | + if (new_lineno < f->f_code->co_firstlineno) { | |
| 109 | + PyErr_Format(PyExc_ValueError, | |
| 110 | + "line %d comes before the current code block", | |
| 111 | + new_lineno); | |
| 112 | + return -1; | |
| 113 | + } | |
| 114 | + | |
| 115 | + /* Find the bytecode offset for the start of the given line, or the | |
| 116 | + * first code-owning line after it. */ | |
| 117 | + PyString_AsStringAndSize(f->f_code->co_lnotab, &lnotab, &lnotab_len); | |
| 118 | + addr = 0; | |
| 119 | + line = f->f_code->co_firstlineno; | |
| 120 | + new_lasti = -1; | |
| 121 | + for (offset = 0; offset < lnotab_len; offset += 2) { | |
| 122 | + addr += lnotab[offset]; | |
| 123 | + line += lnotab[offset+1]; | |
| 124 | + if (line >= new_lineno) { | |
| 125 | + new_lasti = addr; | |
| 126 | + new_lineno = line; | |
| 127 | + break; | |
| 128 | + } | |
| 129 | + } | |
| 130 | + | |
| 131 | + /* If we didn't reach the requested line, return an error. */ | |
| 132 | + if (new_lasti == -1) { | |
| 133 | + PyErr_Format(PyExc_ValueError, | |
| 134 | + "line %d comes after the current code block", | |
| 135 | + new_lineno); | |
| 136 | + return -1; | |
| 137 | + } | |
| 138 | + | |
| 139 | + /* We're now ready to look at the bytecode. */ | |
| 140 | + PyString_AsStringAndSize(f->f_code->co_code, &code, &code_len); | |
| 141 | + min_addr = MIN(new_lasti, f->f_lasti); | |
| 142 | + max_addr = MAX(new_lasti, f->f_lasti); | |
| 143 | + | |
| 144 | + /* You can't jump onto a line with an 'except' statement on it - | |
| 145 | + * they expect to have an exception on the top of the stack, which | |
| 146 | + * won't be true if you jump to them. They always start with code | |
| 147 | + * that either pops the exception using POP_TOP (plain 'except:' | |
| 148 | + * lines do this) or duplicates the exception on the stack using | |
| 149 | + * DUP_TOP (if there's an exception type specified). See compile.c, | |
| 150 | + * 'com_try_except' for the full details. There aren't any other | |
| 151 | + * cases (AFAIK) where a line's code can start with DUP_TOP or | |
| 152 | + * POP_TOP, but if any ever appear, they'll be subject to the same | |
| 153 | + * restriction (but with a different error message). */ | |
| 154 | + if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) { | |
| 155 | + PyErr_SetString(PyExc_ValueError, | |
| 156 | + "can't jump to 'except' line as there's no exception"); | |
| 157 | + return -1; | |
| 158 | + } | |
| 159 | + | |
| 160 | + /* You can't jump into or out of a 'finally' block because the 'try' | |
| 161 | + * block leaves something on the stack for the END_FINALLY to clean | |
| 162 | + * up. So we walk the bytecode, maintaining a simulated blockstack. | |
| 163 | + * When we reach the old or new address and it's in a 'finally' block | |
| 164 | + * we note the address of the corresponding SETUP_FINALLY. The jump | |
| 165 | + * is only legal if neither address is in a 'finally' block or | |
| 166 | + * they're both in the same one. 'blockstack' is a stack of the | |
| 167 | + * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks | |
| 168 | + * whether we're in a 'finally' block at each blockstack level. */ | |
| 169 | + f_lasti_setup_addr = -1; | |
| 170 | + new_lasti_setup_addr = -1; | |
| 171 | + memset(blockstack, '\0', sizeof(blockstack)); | |
| 172 | + memset(in_finally, '\0', sizeof(in_finally)); | |
| 173 | + blockstack_top = 0; | |
| 174 | + for (addr = 0; addr < code_len; addr++) { | |
| 175 | + unsigned char op = code[addr]; | |
| 176 | + switch (op) { | |
| 177 | + case SETUP_LOOP: | |
| 178 | + case SETUP_EXCEPT: | |
| 179 | + case SETUP_FINALLY: | |
| 180 | + blockstack[blockstack_top++] = addr; | |
| 181 | + in_finally[blockstack_top-1] = 0; | |
| 182 | + break; | |
| 183 | + | |
| 184 | + case POP_BLOCK: | |
| 185 | + assert(blockstack_top > 0); | |
| 186 | + setup_op = code[blockstack[blockstack_top-1]]; | |
| 187 | + if (setup_op == SETUP_FINALLY) { | |
| 188 | + in_finally[blockstack_top-1] = 1; | |
| 189 | + } | |
| 190 | + else { | |
| 191 | + blockstack_top--; | |
| 192 | + } | |
| 193 | + break; | |
| 194 | + | |
| 195 | + case END_FINALLY: | |
| 196 | + /* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist | |
| 197 | + * in the bytecode but don't correspond to an actual | |
| 198 | + * 'finally' block. (If blockstack_top is 0, we must | |
| 199 | + * be seeing such an END_FINALLY.) */ | |
| 200 | + if (blockstack_top > 0) { | |
| 201 | + setup_op = code[blockstack[blockstack_top-1]]; | |
| 202 | + if (setup_op == SETUP_FINALLY) { | |
| 203 | + blockstack_top--; | |
| 204 | + } | |
| 205 | + } | |
| 206 | + break; | |
| 207 | + } | |
| 208 | + | |
| 209 | + /* For the addresses we're interested in, see whether they're | |
| 210 | + * within a 'finally' block and if so, remember the address | |
| 211 | + * of the SETUP_FINALLY. */ | |
| 212 | + if (addr == new_lasti || addr == f->f_lasti) { | |
| 213 | + int i = 0; | |
| 214 | + int setup_addr = -1; | |
| 215 | + for (i = blockstack_top-1; i >= 0; i--) { | |
| 216 | + if (in_finally[i]) { | |
| 217 | + setup_addr = blockstack[i]; | |
| 218 | + break; | |
| 219 | + } | |
| 220 | + } | |
| 221 | + | |
| 222 | + if (setup_addr != -1) { | |
| 223 | + if (addr == new_lasti) { | |
| 224 | + new_lasti_setup_addr = setup_addr; | |
| 225 | + } | |
| 226 | + | |
| 227 | + if (addr == f->f_lasti) { | |
| 228 | + f_lasti_setup_addr = setup_addr; | |
| 229 | + } | |
| 230 | + } | |
| 231 | + } | |
| 232 | + | |
| 233 | + if (op >= HAVE_ARGUMENT) { | |
| 234 | + addr += 2; | |
| 235 | + } | |
| 236 | + } | |
| 237 | + | |
| 238 | + /* Verify that the blockstack tracking code didn't get lost. */ | |
| 239 | + assert(blockstack_top == 0); | |
| 240 | + | |
| 241 | + /* After all that, are we jumping into / out of a 'finally' block? */ | |
| 242 | + if (new_lasti_setup_addr != f_lasti_setup_addr) { | |
| 243 | + PyErr_SetString(PyExc_ValueError, | |
| 244 | + "can't jump into or out of a 'finally' block"); | |
| 245 | + return -1; | |
| 246 | + } | |
| 247 | + | |
| 248 | + | |
| 249 | + /* Police block-jumping (you can't jump into the middle of a block) | |
| 250 | + * and ensure that the blockstack finishes up in a sensible state (by | |
| 251 | + * popping any blocks we're jumping out of). We look at all the | |
| 252 | + * blockstack operations between the current position and the new | |
| 253 | + * one, and keep track of how many blocks we drop out of on the way. | |
| 254 | + * By also keeping track of the lowest blockstack position we see, we | |
| 255 | + * can tell whether the jump goes into any blocks without coming out | |
| 256 | + * again - in that case we raise an exception below. */ | |
| 257 | + delta_iblock = 0; | |
| 258 | + for (addr = min_addr; addr < max_addr; addr++) { | |
| 259 | + unsigned char op = code[addr]; | |
| 260 | + switch (op) { | |
| 261 | + case SETUP_LOOP: | |
| 262 | + case SETUP_EXCEPT: | |
| 263 | + case SETUP_FINALLY: | |
| 264 | + delta_iblock++; | |
| 265 | + break; | |
| 266 | + | |
| 267 | + case POP_BLOCK: | |
| 268 | + delta_iblock--; | |
| 269 | + break; | |
| 270 | + } | |
| 271 | + | |
| 272 | + min_delta_iblock = MIN(min_delta_iblock, delta_iblock); | |
| 273 | + | |
| 274 | + if (op >= HAVE_ARGUMENT) { | |
| 275 | + addr += 2; | |
| 276 | + } | |
| 277 | + } | |
| 278 | + | |
| 279 | + /* Derive the absolute iblock values from the deltas. */ | |
| 280 | + min_iblock = f->f_iblock + min_delta_iblock; | |
| 281 | + if (new_lasti > f->f_lasti) { | |
| 282 | + /* Forwards jump. */ | |
| 283 | + new_iblock = f->f_iblock + delta_iblock; | |
| 284 | + } | |
| 285 | + else { | |
| 286 | + /* Backwards jump. */ | |
| 287 | + new_iblock = f->f_iblock - delta_iblock; | |
| 288 | + } | |
| 289 | + | |
| 290 | + /* Are we jumping into a block? */ | |
| 291 | + if (new_iblock > min_iblock) { | |
| 292 | + PyErr_SetString(PyExc_ValueError, | |
| 293 | + "can't jump into the middle of a block"); | |
| 294 | + return -1; | |
| 295 | + } | |
| 296 | + | |
| 297 | + /* Pop any blocks that we're jumping out of. */ | |
| 298 | + while (f->f_iblock > new_iblock) { | |
| 299 | + PyTryBlock *b = &f->f_blockstack[--f->f_iblock]; | |
| 300 | + while ((f->f_stacktop - f->f_valuestack) > b->b_level) { | |
| 301 | + PyObject *v = (*--f->f_stacktop); | |
| 302 | + Py_DECREF(v); | |
| 303 | + } | |
| 304 | + } | |
| 305 | + | |
| 306 | + /* Finally set the new f_lineno and f_lasti and return OK. */ | |
| 307 | + f->f_lineno = new_lineno; | |
| 308 | + f->f_lasti = new_lasti; | |
| 309 | + return 0; | |
| 310 | +} | |
| 311 | + | |
| 312 | +static PyObject * | |
| 313 | +frame_gettrace(PyFrameObject *f, void *closure) | |
| 314 | +{ | |
| 315 | + PyObject* trace = f->f_trace; | |
| 316 | + | |
| 317 | + if (trace == NULL) | |
| 318 | + trace = Py_None; | |
| 319 | + | |
| 320 | + Py_INCREF(trace); | |
| 321 | + | |
| 322 | + return trace; | |
| 323 | +} | |
| 324 | + | |
| 325 | +static int | |
| 326 | +frame_settrace(PyFrameObject *f, PyObject* v, void *closure) | |
| 327 | +{ | |
| 328 | + /* We rely on f_lineno being accurate when f_trace is set. */ | |
| 329 | + | |
| 330 | + PyObject* old_value = f->f_trace; | |
| 331 | + | |
| 332 | + Py_XINCREF(v); | |
| 333 | + f->f_trace = v; | |
| 334 | + | |
| 335 | + if (v != NULL) | |
| 336 | + f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); | |
| 337 | + | |
| 338 | + Py_XDECREF(old_value); | |
| 339 | + | |
| 340 | + return 0; | |
| 341 | +} | |
| 342 | + | |
| 343 | +static PyObject * | |
| 344 | +frame_getrestricted(PyFrameObject *f, void *closure) | |
| 345 | +{ | |
| 346 | + return PyBool_FromLong(PyFrame_IsRestricted(f)); | |
| 347 | +} | |
| 348 | + | |
| 349 | +static PyGetSetDef frame_getsetlist[] = { | |
| 350 | + {"f_locals", (getter)frame_getlocals, NULL, NULL}, | |
| 351 | + {"f_lineno", (getter)frame_getlineno, | |
| 352 | + (setter)frame_setlineno, NULL}, | |
| 353 | + {"f_trace", (getter)frame_gettrace, (setter)frame_settrace, NULL}, | |
| 354 | + {"f_restricted",(getter)frame_getrestricted,NULL, NULL}, | |
| 355 | + {0} | |
| 356 | +}; | |
| 357 | + | |
| 358 | +/* Stack frames are allocated and deallocated at a considerable rate. | |
| 359 | + In an attempt to improve the speed of function calls, we: | |
| 360 | + | |
| 361 | + 1. Hold a single "zombie" frame on each code object. This retains | |
| 362 | + the allocated and initialised frame object from an invocation of | |
| 363 | + the code object. The zombie is reanimated the next time we need a | |
| 364 | + frame object for that code object. Doing this saves the malloc/ | |
| 365 | + realloc required when using a free_list frame that isn't the | |
| 366 | + correct size. It also saves some field initialisation. | |
| 367 | + | |
| 368 | + In zombie mode, no field of PyFrameObject holds a reference, but | |
| 369 | + the following fields are still valid: | |
| 370 | + | |
| 371 | + * ob_type, ob_size, f_code, f_valuestack; | |
| 372 | + | |
| 373 | + * f_locals, f_trace, | |
| 374 | + f_exc_type, f_exc_value, f_exc_traceback are NULL; | |
| 375 | + | |
| 376 | + * f_localsplus does not require re-allocation and | |
| 377 | + the local variables in f_localsplus are NULL. | |
| 378 | + | |
| 379 | + 2. We also maintain a separate free list of stack frames (just like | |
| 380 | + integers are allocated in a special way -- see intobject.c). When | |
| 381 | + a stack frame is on the free list, only the following members have | |
| 382 | + a meaning: | |
| 383 | + ob_type == &Frametype | |
| 384 | + f_back next item on free list, or NULL | |
| 385 | + f_stacksize size of value stack | |
| 386 | + ob_size size of localsplus | |
| 387 | + Note that the value and block stacks are preserved -- this can save | |
| 388 | + another malloc() call or two (and two free() calls as well!). | |
| 389 | + Also note that, unlike for integers, each frame object is a | |
| 390 | + malloc'ed object in its own right -- it is only the actual calls to | |
| 391 | + malloc() that we are trying to save here, not the administration. | |
| 392 | + After all, while a typical program may make millions of calls, a | |
| 393 | + call depth of more than 20 or 30 is probably already exceptional | |
| 394 | + unless the program contains run-away recursion. I hope. | |
| 395 | + | |
| 396 | + Later, MAXFREELIST was added to bound the # of frames saved on | |
| 397 | + free_list. Else programs creating lots of cyclic trash involving | |
| 398 | + frames could provoke free_list into growing without bound. | |
| 399 | +*/ | |
| 400 | + | |
| 401 | +static PyFrameObject *free_list = NULL; | |
| 402 | +static int numfree = 0; /* number of frames currently in free_list */ | |
| 403 | +#define MAXFREELIST 200 /* max value for numfree */ | |
| 404 | + | |
| 405 | +static void | |
| 406 | +frame_dealloc(PyFrameObject *f) | |
| 407 | +{ | |
| 408 | + PyObject **p, **valuestack; | |
| 409 | + PyCodeObject *co; | |
| 410 | + | |
| 411 | + PyObject_GC_UnTrack(f); | |
| 412 | + Py_TRASHCAN_SAFE_BEGIN(f) | |
| 413 | + /* Kill all local variables */ | |
| 414 | + valuestack = f->f_valuestack; | |
| 415 | + for (p = f->f_localsplus; p < valuestack; p++) | |
| 416 | + Py_CLEAR(*p); | |
| 417 | + | |
| 418 | + /* Free stack */ | |
| 419 | + if (f->f_stacktop != NULL) { | |
| 420 | + for (p = valuestack; p < f->f_stacktop; p++) | |
| 421 | + Py_XDECREF(*p); | |
| 422 | + } | |
| 423 | + | |
| 424 | + Py_XDECREF(f->f_back); | |
| 425 | + Py_DECREF(f->f_builtins); | |
| 426 | + Py_DECREF(f->f_globals); | |
| 427 | + Py_CLEAR(f->f_locals); | |
| 428 | + Py_CLEAR(f->f_trace); | |
| 429 | + Py_CLEAR(f->f_exc_type); | |
| 430 | + Py_CLEAR(f->f_exc_value); | |
| 431 | + Py_CLEAR(f->f_exc_traceback); | |
| 432 | + | |
| 433 | + co = f->f_code; | |
| 434 | + if (co->co_zombieframe == NULL) | |
| 435 | + co->co_zombieframe = f; | |
| 436 | + else if (numfree < MAXFREELIST) { | |
| 437 | + ++numfree; | |
| 438 | + f->f_back = free_list; | |
| 439 | + free_list = f; | |
| 440 | + } | |
| 441 | + else | |
| 442 | + PyObject_GC_Del(f); | |
| 443 | + | |
| 444 | + Py_DECREF(co); | |
| 445 | + Py_TRASHCAN_SAFE_END(f) | |
| 446 | +} | |
| 447 | + | |
| 448 | +static int | |
| 449 | +frame_traverse(PyFrameObject *f, visitproc visit, void *arg) | |
| 450 | +{ | |
| 451 | + PyObject **fastlocals, **p; | |
| 452 | + int i, slots; | |
| 453 | + | |
| 454 | + Py_VISIT(f->f_back); | |
| 455 | + Py_VISIT(f->f_code); | |
| 456 | + Py_VISIT(f->f_builtins); | |
| 457 | + Py_VISIT(f->f_globals); | |
| 458 | + Py_VISIT(f->f_locals); | |
| 459 | + Py_VISIT(f->f_trace); | |
| 460 | + Py_VISIT(f->f_exc_type); | |
| 461 | + Py_VISIT(f->f_exc_value); | |
| 462 | + Py_VISIT(f->f_exc_traceback); | |
| 463 | + | |
| 464 | + /* locals */ | |
| 465 | + slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars); | |
| 466 | + fastlocals = f->f_localsplus; | |
| 467 | + for (i = slots; --i >= 0; ++fastlocals) | |
| 468 | + Py_VISIT(*fastlocals); | |
| 469 | + | |
| 470 | + /* stack */ | |
| 471 | + if (f->f_stacktop != NULL) { | |
| 472 | + for (p = f->f_valuestack; p < f->f_stacktop; p++) | |
| 473 | + Py_VISIT(*p); | |
| 474 | + } | |
| 475 | + return 0; | |
| 476 | +} | |
| 477 | + | |
| 478 | +static void | |
| 479 | +frame_clear(PyFrameObject *f) | |
| 480 | +{ | |
| 481 | + PyObject **fastlocals, **p, **oldtop; | |
| 482 | + int i, slots; | |
| 483 | + | |
| 484 | + /* Before anything else, make sure that this frame is clearly marked | |
| 485 | + * as being defunct! Else, e.g., a generator reachable from this | |
| 486 | + * frame may also point to this frame, believe itself to still be | |
| 487 | + * active, and try cleaning up this frame again. | |
| 488 | + */ | |
| 489 | + oldtop = f->f_stacktop; | |
| 490 | + f->f_stacktop = NULL; | |
| 491 | + | |
| 492 | + Py_CLEAR(f->f_exc_type); | |
| 493 | + Py_CLEAR(f->f_exc_value); | |
| 494 | + Py_CLEAR(f->f_exc_traceback); | |
| 495 | + Py_CLEAR(f->f_trace); | |
| 496 | + | |
| 497 | + /* locals */ | |
| 498 | + slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars); | |
| 499 | + fastlocals = f->f_localsplus; | |
| 500 | + for (i = slots; --i >= 0; ++fastlocals) | |
| 501 | + Py_CLEAR(*fastlocals); | |
| 502 | + | |
| 503 | + /* stack */ | |
| 504 | + if (oldtop != NULL) { | |
| 505 | + for (p = f->f_valuestack; p < oldtop; p++) | |
| 506 | + Py_CLEAR(*p); | |
| 507 | + } | |
| 508 | +} | |
| 509 | + | |
| 510 | + | |
| 511 | +PyTypeObject PyFrame_Type = { | |
| 512 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 513 | + 0, | |
| 514 | + "frame", | |
| 515 | + sizeof(PyFrameObject), | |
| 516 | + sizeof(PyObject *), | |
| 517 | + (destructor)frame_dealloc, /* tp_dealloc */ | |
| 518 | + 0, /* tp_print */ | |
| 519 | + 0, /* tp_getattr */ | |
| 520 | + 0, /* tp_setattr */ | |
| 521 | + 0, /* tp_compare */ | |
| 522 | + 0, /* tp_repr */ | |
| 523 | + 0, /* tp_as_number */ | |
| 524 | + 0, /* tp_as_sequence */ | |
| 525 | + 0, /* tp_as_mapping */ | |
| 526 | + 0, /* tp_hash */ | |
| 527 | + 0, /* tp_call */ | |
| 528 | + 0, /* tp_str */ | |
| 529 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 530 | + PyObject_GenericSetAttr, /* tp_setattro */ | |
| 531 | + 0, /* tp_as_buffer */ | |
| 532 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | |
| 533 | + 0, /* tp_doc */ | |
| 534 | + (traverseproc)frame_traverse, /* tp_traverse */ | |
| 535 | + (inquiry)frame_clear, /* tp_clear */ | |
| 536 | + 0, /* tp_richcompare */ | |
| 537 | + 0, /* tp_weaklistoffset */ | |
| 538 | + 0, /* tp_iter */ | |
| 539 | + 0, /* tp_iternext */ | |
| 540 | + 0, /* tp_methods */ | |
| 541 | + frame_memberlist, /* tp_members */ | |
| 542 | + frame_getsetlist, /* tp_getset */ | |
| 543 | + 0, /* tp_base */ | |
| 544 | + 0, /* tp_dict */ | |
| 545 | +}; | |
| 546 | + | |
| 547 | +static PyObject *builtin_object; | |
| 548 | + | |
| 549 | +int _PyFrame_Init() | |
| 550 | +{ | |
| 551 | + builtin_object = PyString_InternFromString("__builtins__"); | |
| 552 | + return (builtin_object != NULL); | |
| 553 | +} | |
| 554 | + | |
| 555 | +PyFrameObject * | |
| 556 | +PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, | |
| 557 | + PyObject *locals) | |
| 558 | +{ | |
| 559 | + PyFrameObject *back = tstate->frame; | |
| 560 | + PyFrameObject *f; | |
| 561 | + PyObject *builtins; | |
| 562 | + Py_ssize_t i; | |
| 563 | + | |
| 564 | +#ifdef Py_DEBUG | |
| 565 | + if (code == NULL || globals == NULL || !PyDict_Check(globals) || | |
| 566 | + (locals != NULL && !PyMapping_Check(locals))) { | |
| 567 | + PyErr_BadInternalCall(); | |
| 568 | + return NULL; | |
| 569 | + } | |
| 570 | +#endif | |
| 571 | + if (back == NULL || back->f_globals != globals) { | |
| 572 | + builtins = PyDict_GetItem(globals, builtin_object); | |
| 573 | + if (builtins) { | |
| 574 | + if (PyModule_Check(builtins)) { | |
| 575 | + builtins = PyModule_GetDict(builtins); | |
| 576 | + assert(!builtins || PyDict_Check(builtins)); | |
| 577 | + } | |
| 578 | + else if (!PyDict_Check(builtins)) | |
| 579 | + builtins = NULL; | |
| 580 | + } | |
| 581 | + if (builtins == NULL) { | |
| 582 | + /* No builtins! Make up a minimal one | |
| 583 | + Give them 'None', at least. */ | |
| 584 | + builtins = PyDict_New(); | |
| 585 | + if (builtins == NULL || | |
| 586 | + PyDict_SetItemString( | |
| 587 | + builtins, "None", Py_None) < 0) | |
| 588 | + return NULL; | |
| 589 | + } | |
| 590 | + else | |
| 591 | + Py_INCREF(builtins); | |
| 592 | + | |
| 593 | + } | |
| 594 | + else { | |
| 595 | + /* If we share the globals, we share the builtins. | |
| 596 | + Save a lookup and a call. */ | |
| 597 | + builtins = back->f_builtins; | |
| 598 | + assert(builtins != NULL && PyDict_Check(builtins)); | |
| 599 | + Py_INCREF(builtins); | |
| 600 | + } | |
| 601 | + if (code->co_zombieframe != NULL) { | |
| 602 | + f = code->co_zombieframe; | |
| 603 | + code->co_zombieframe = NULL; | |
| 604 | + _Py_NewReference((PyObject *)f); | |
| 605 | + assert(f->f_code == code); | |
| 606 | + } | |
| 607 | + else { | |
| 608 | + Py_ssize_t extras, ncells, nfrees; | |
| 609 | + ncells = PyTuple_GET_SIZE(code->co_cellvars); | |
| 610 | + nfrees = PyTuple_GET_SIZE(code->co_freevars); | |
| 611 | + extras = code->co_stacksize + code->co_nlocals + ncells + | |
| 612 | + nfrees; | |
| 613 | + if (free_list == NULL) { | |
| 614 | + f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, | |
| 615 | + extras); | |
| 616 | + if (f == NULL) { | |
| 617 | + Py_DECREF(builtins); | |
| 618 | + return NULL; | |
| 619 | + } | |
| 620 | + } | |
| 621 | + else { | |
| 622 | + assert(numfree > 0); | |
| 623 | + --numfree; | |
| 624 | + f = free_list; | |
| 625 | + free_list = free_list->f_back; | |
| 626 | + if (f->ob_size < extras) { | |
| 627 | + f = PyObject_GC_Resize(PyFrameObject, f, extras); | |
| 628 | + if (f == NULL) { | |
| 629 | + Py_DECREF(builtins); | |
| 630 | + return NULL; | |
| 631 | + } | |
| 632 | + } | |
| 633 | + _Py_NewReference((PyObject *)f); | |
| 634 | + } | |
| 635 | + | |
| 636 | + f->f_code = code; | |
| 637 | + extras = code->co_nlocals + ncells + nfrees; | |
| 638 | + f->f_valuestack = f->f_localsplus + extras; | |
| 639 | + for (i=0; i<extras; i++) | |
| 640 | + f->f_localsplus[i] = NULL; | |
| 641 | + f->f_locals = NULL; | |
| 642 | + f->f_trace = NULL; | |
| 643 | + f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL; | |
| 644 | + } | |
| 645 | + f->f_stacktop = f->f_valuestack; | |
| 646 | + f->f_builtins = builtins; | |
| 647 | + Py_XINCREF(back); | |
| 648 | + f->f_back = back; | |
| 649 | + Py_INCREF(code); | |
| 650 | + Py_INCREF(globals); | |
| 651 | + f->f_globals = globals; | |
| 652 | + /* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */ | |
| 653 | + if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) == | |
| 654 | + (CO_NEWLOCALS | CO_OPTIMIZED)) | |
| 655 | + ; /* f_locals = NULL; will be set by PyFrame_FastToLocals() */ | |
| 656 | + else if (code->co_flags & CO_NEWLOCALS) { | |
| 657 | + locals = PyDict_New(); | |
| 658 | + if (locals == NULL) { | |
| 659 | + Py_DECREF(f); | |
| 660 | + return NULL; | |
| 661 | + } | |
| 662 | + f->f_locals = locals; | |
| 663 | + } | |
| 664 | + else { | |
| 665 | + if (locals == NULL) | |
| 666 | + locals = globals; | |
| 667 | + Py_INCREF(locals); | |
| 668 | + f->f_locals = locals; | |
| 669 | + } | |
| 670 | + f->f_tstate = tstate; | |
| 671 | + | |
| 672 | + f->f_lasti = -1; | |
| 673 | + f->f_lineno = code->co_firstlineno; | |
| 674 | + f->f_iblock = 0; | |
| 675 | + | |
| 676 | + _PyObject_GC_TRACK(f); | |
| 677 | + return f; | |
| 678 | +} | |
| 679 | + | |
| 680 | +/* Block management */ | |
| 681 | + | |
| 682 | +void | |
| 683 | +PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level) | |
| 684 | +{ | |
| 685 | + PyTryBlock *b; | |
| 686 | + if (f->f_iblock >= CO_MAXBLOCKS) | |
| 687 | + Py_FatalError("XXX block stack overflow"); | |
| 688 | + b = &f->f_blockstack[f->f_iblock++]; | |
| 689 | + b->b_type = type; | |
| 690 | + b->b_level = level; | |
| 691 | + b->b_handler = handler; | |
| 692 | +} | |
| 693 | + | |
| 694 | +PyTryBlock * | |
| 695 | +PyFrame_BlockPop(PyFrameObject *f) | |
| 696 | +{ | |
| 697 | + PyTryBlock *b; | |
| 698 | + if (f->f_iblock <= 0) | |
| 699 | + Py_FatalError("XXX block stack underflow"); | |
| 700 | + b = &f->f_blockstack[--f->f_iblock]; | |
| 701 | + return b; | |
| 702 | +} | |
| 703 | + | |
| 704 | +/* Convert between "fast" version of locals and dictionary version */ | |
| 705 | + | |
| 706 | +static void | |
| 707 | +map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, | |
| 708 | + Py_ssize_t deref) | |
| 709 | +{ | |
| 710 | + Py_ssize_t j; | |
| 711 | + for (j = nmap; --j >= 0; ) { | |
| 712 | + PyObject *key = PyTuple_GET_ITEM(map, j); | |
| 713 | + PyObject *value = values[j]; | |
| 714 | + if (deref) | |
| 715 | + value = PyCell_GET(value); | |
| 716 | + if (value == NULL) { | |
| 717 | + if (PyObject_DelItem(dict, key) != 0) | |
| 718 | + PyErr_Clear(); | |
| 719 | + } | |
| 720 | + else { | |
| 721 | + if (PyObject_SetItem(dict, key, value) != 0) | |
| 722 | + PyErr_Clear(); | |
| 723 | + } | |
| 724 | + } | |
| 725 | +} | |
| 726 | + | |
| 727 | +static void | |
| 728 | +dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, | |
| 729 | + Py_ssize_t deref, int clear) | |
| 730 | +{ | |
| 731 | + Py_ssize_t j; | |
| 732 | + for (j = nmap; --j >= 0; ) { | |
| 733 | + PyObject *key = PyTuple_GET_ITEM(map, j); | |
| 734 | + PyObject *value = PyObject_GetItem(dict, key); | |
| 735 | + if (value == NULL) | |
| 736 | + PyErr_Clear(); | |
| 737 | + if (deref) { | |
| 738 | + if (value || clear) { | |
| 739 | + if (PyCell_GET(values[j]) != value) { | |
| 740 | + if (PyCell_Set(values[j], value) < 0) | |
| 741 | + PyErr_Clear(); | |
| 742 | + } | |
| 743 | + } | |
| 744 | + } else if (value != NULL || clear) { | |
| 745 | + if (values[j] != value) { | |
| 746 | + Py_XINCREF(value); | |
| 747 | + Py_XDECREF(values[j]); | |
| 748 | + values[j] = value; | |
| 749 | + } | |
| 750 | + } | |
| 751 | + Py_XDECREF(value); | |
| 752 | + } | |
| 753 | +} | |
| 754 | + | |
| 755 | +void | |
| 756 | +PyFrame_FastToLocals(PyFrameObject *f) | |
| 757 | +{ | |
| 758 | + /* Merge fast locals into f->f_locals */ | |
| 759 | + PyObject *locals, *map; | |
| 760 | + PyObject **fast; | |
| 761 | + PyObject *error_type, *error_value, *error_traceback; | |
| 762 | + PyCodeObject *co; | |
| 763 | + Py_ssize_t j; | |
| 764 | + int ncells, nfreevars; | |
| 765 | + if (f == NULL) | |
| 766 | + return; | |
| 767 | + locals = f->f_locals; | |
| 768 | + if (locals == NULL) { | |
| 769 | + locals = f->f_locals = PyDict_New(); | |
| 770 | + if (locals == NULL) { | |
| 771 | + PyErr_Clear(); /* Can't report it :-( */ | |
| 772 | + return; | |
| 773 | + } | |
| 774 | + } | |
| 775 | + co = f->f_code; | |
| 776 | + map = co->co_varnames; | |
| 777 | + if (!PyTuple_Check(map)) | |
| 778 | + return; | |
| 779 | + PyErr_Fetch(&error_type, &error_value, &error_traceback); | |
| 780 | + fast = f->f_localsplus; | |
| 781 | + j = PyTuple_GET_SIZE(map); | |
| 782 | + if (j > co->co_nlocals) | |
| 783 | + j = co->co_nlocals; | |
| 784 | + if (co->co_nlocals) | |
| 785 | + map_to_dict(map, j, locals, fast, 0); | |
| 786 | + ncells = PyTuple_GET_SIZE(co->co_cellvars); | |
| 787 | + nfreevars = PyTuple_GET_SIZE(co->co_freevars); | |
| 788 | + if (ncells || nfreevars) { | |
| 789 | + map_to_dict(co->co_cellvars, ncells, | |
| 790 | + locals, fast + co->co_nlocals, 1); | |
| 791 | + map_to_dict(co->co_freevars, nfreevars, | |
| 792 | + locals, fast + co->co_nlocals + ncells, 1); | |
| 793 | + } | |
| 794 | + PyErr_Restore(error_type, error_value, error_traceback); | |
| 795 | +} | |
| 796 | + | |
| 797 | +void | |
| 798 | +PyFrame_LocalsToFast(PyFrameObject *f, int clear) | |
| 799 | +{ | |
| 800 | + /* Merge f->f_locals into fast locals */ | |
| 801 | + PyObject *locals, *map; | |
| 802 | + PyObject **fast; | |
| 803 | + PyObject *error_type, *error_value, *error_traceback; | |
| 804 | + PyCodeObject *co; | |
| 805 | + Py_ssize_t j; | |
| 806 | + int ncells, nfreevars; | |
| 807 | + if (f == NULL) | |
| 808 | + return; | |
| 809 | + locals = f->f_locals; | |
| 810 | + co = f->f_code; | |
| 811 | + map = co->co_varnames; | |
| 812 | + if (locals == NULL) | |
| 813 | + return; | |
| 814 | + if (!PyTuple_Check(map)) | |
| 815 | + return; | |
| 816 | + PyErr_Fetch(&error_type, &error_value, &error_traceback); | |
| 817 | + fast = f->f_localsplus; | |
| 818 | + j = PyTuple_GET_SIZE(map); | |
| 819 | + if (j > co->co_nlocals) | |
| 820 | + j = co->co_nlocals; | |
| 821 | + if (co->co_nlocals) | |
| 822 | + dict_to_map(co->co_varnames, j, locals, fast, 0, clear); | |
| 823 | + ncells = PyTuple_GET_SIZE(co->co_cellvars); | |
| 824 | + nfreevars = PyTuple_GET_SIZE(co->co_freevars); | |
| 825 | + if (ncells || nfreevars) { | |
| 826 | + dict_to_map(co->co_cellvars, ncells, | |
| 827 | + locals, fast + co->co_nlocals, 1, clear); | |
| 828 | + dict_to_map(co->co_freevars, nfreevars, | |
| 829 | + locals, fast + co->co_nlocals + ncells, 1, | |
| 830 | + clear); | |
| 831 | + } | |
| 832 | + PyErr_Restore(error_type, error_value, error_traceback); | |
| 833 | +} | |
| 834 | + | |
| 835 | +/* Clear out the free list */ | |
| 836 | + | |
| 837 | +void | |
| 838 | +PyFrame_Fini(void) | |
| 839 | +{ | |
| 840 | + while (free_list != NULL) { | |
| 841 | + PyFrameObject *f = free_list; | |
| 842 | + free_list = free_list->f_back; | |
| 843 | + PyObject_GC_Del(f); | |
| 844 | + --numfree; | |
| 845 | + } | |
| 846 | + assert(numfree == 0); | |
| 847 | + Py_XDECREF(builtin_object); | |
| 848 | + builtin_object = NULL; | |
| 849 | +} | |
| @@ -0,0 +1,888 @@ | ||
| 1 | + | |
| 2 | +/* Function object implementation */ | |
| 3 | + | |
| 4 | +#include "Python.h" | |
| 5 | +#include "code.h" | |
| 6 | +#include "eval.h" | |
| 7 | +#include "structmember.h" | |
| 8 | + | |
| 9 | +PyObject * | |
| 10 | +PyFunction_New(PyObject *code, PyObject *globals) | |
| 11 | +{ | |
| 12 | + PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, | |
| 13 | + &PyFunction_Type); | |
| 14 | + static PyObject *__name__ = 0; | |
| 15 | + if (op != NULL) { | |
| 16 | + PyObject *doc; | |
| 17 | + PyObject *consts; | |
| 18 | + PyObject *module; | |
| 19 | + op->func_weakreflist = NULL; | |
| 20 | + Py_INCREF(code); | |
| 21 | + op->func_code = code; | |
| 22 | + Py_INCREF(globals); | |
| 23 | + op->func_globals = globals; | |
| 24 | + op->func_name = ((PyCodeObject *)code)->co_name; | |
| 25 | + Py_INCREF(op->func_name); | |
| 26 | + op->func_defaults = NULL; /* No default arguments */ | |
| 27 | + op->func_closure = NULL; | |
| 28 | + consts = ((PyCodeObject *)code)->co_consts; | |
| 29 | + if (PyTuple_Size(consts) >= 1) { | |
| 30 | + doc = PyTuple_GetItem(consts, 0); | |
| 31 | + if (!PyString_Check(doc) && !PyUnicode_Check(doc)) | |
| 32 | + doc = Py_None; | |
| 33 | + } | |
| 34 | + else | |
| 35 | + doc = Py_None; | |
| 36 | + Py_INCREF(doc); | |
| 37 | + op->func_doc = doc; | |
| 38 | + op->func_dict = NULL; | |
| 39 | + op->func_module = NULL; | |
| 40 | + | |
| 41 | + /* __module__: If module name is in globals, use it. | |
| 42 | + Otherwise, use None. | |
| 43 | + */ | |
| 44 | + if (!__name__) { | |
| 45 | + __name__ = PyString_InternFromString("__name__"); | |
| 46 | + if (!__name__) { | |
| 47 | + Py_DECREF(op); | |
| 48 | + return NULL; | |
| 49 | + } | |
| 50 | + } | |
| 51 | + module = PyDict_GetItem(globals, __name__); | |
| 52 | + if (module) { | |
| 53 | + Py_INCREF(module); | |
| 54 | + op->func_module = module; | |
| 55 | + } | |
| 56 | + } | |
| 57 | + else | |
| 58 | + return NULL; | |
| 59 | + _PyObject_GC_TRACK(op); | |
| 60 | + return (PyObject *)op; | |
| 61 | +} | |
| 62 | + | |
| 63 | +PyObject * | |
| 64 | +PyFunction_GetCode(PyObject *op) | |
| 65 | +{ | |
| 66 | + if (!PyFunction_Check(op)) { | |
| 67 | + PyErr_BadInternalCall(); | |
| 68 | + return NULL; | |
| 69 | + } | |
| 70 | + return ((PyFunctionObject *) op) -> func_code; | |
| 71 | +} | |
| 72 | + | |
| 73 | +PyObject * | |
| 74 | +PyFunction_GetGlobals(PyObject *op) | |
| 75 | +{ | |
| 76 | + if (!PyFunction_Check(op)) { | |
| 77 | + PyErr_BadInternalCall(); | |
| 78 | + return NULL; | |
| 79 | + } | |
| 80 | + return ((PyFunctionObject *) op) -> func_globals; | |
| 81 | +} | |
| 82 | + | |
| 83 | +PyObject * | |
| 84 | +PyFunction_GetModule(PyObject *op) | |
| 85 | +{ | |
| 86 | + if (!PyFunction_Check(op)) { | |
| 87 | + PyErr_BadInternalCall(); | |
| 88 | + return NULL; | |
| 89 | + } | |
| 90 | + return ((PyFunctionObject *) op) -> func_module; | |
| 91 | +} | |
| 92 | + | |
| 93 | +PyObject * | |
| 94 | +PyFunction_GetDefaults(PyObject *op) | |
| 95 | +{ | |
| 96 | + if (!PyFunction_Check(op)) { | |
| 97 | + PyErr_BadInternalCall(); | |
| 98 | + return NULL; | |
| 99 | + } | |
| 100 | + return ((PyFunctionObject *) op) -> func_defaults; | |
| 101 | +} | |
| 102 | + | |
| 103 | +int | |
| 104 | +PyFunction_SetDefaults(PyObject *op, PyObject *defaults) | |
| 105 | +{ | |
| 106 | + if (!PyFunction_Check(op)) { | |
| 107 | + PyErr_BadInternalCall(); | |
| 108 | + return -1; | |
| 109 | + } | |
| 110 | + if (defaults == Py_None) | |
| 111 | + defaults = NULL; | |
| 112 | + else if (defaults && PyTuple_Check(defaults)) { | |
| 113 | + Py_INCREF(defaults); | |
| 114 | + } | |
| 115 | + else { | |
| 116 | + PyErr_SetString(PyExc_SystemError, "non-tuple default args"); | |
| 117 | + return -1; | |
| 118 | + } | |
| 119 | + Py_XDECREF(((PyFunctionObject *) op) -> func_defaults); | |
| 120 | + ((PyFunctionObject *) op) -> func_defaults = defaults; | |
| 121 | + return 0; | |
| 122 | +} | |
| 123 | + | |
| 124 | +PyObject * | |
| 125 | +PyFunction_GetClosure(PyObject *op) | |
| 126 | +{ | |
| 127 | + if (!PyFunction_Check(op)) { | |
| 128 | + PyErr_BadInternalCall(); | |
| 129 | + return NULL; | |
| 130 | + } | |
| 131 | + return ((PyFunctionObject *) op) -> func_closure; | |
| 132 | +} | |
| 133 | + | |
| 134 | +int | |
| 135 | +PyFunction_SetClosure(PyObject *op, PyObject *closure) | |
| 136 | +{ | |
| 137 | + if (!PyFunction_Check(op)) { | |
| 138 | + PyErr_BadInternalCall(); | |
| 139 | + return -1; | |
| 140 | + } | |
| 141 | + if (closure == Py_None) | |
| 142 | + closure = NULL; | |
| 143 | + else if (PyTuple_Check(closure)) { | |
| 144 | + Py_INCREF(closure); | |
| 145 | + } | |
| 146 | + else { | |
| 147 | + PyErr_Format(PyExc_SystemError, | |
| 148 | + "expected tuple for closure, got '%.100s'", | |
| 149 | + closure->ob_type->tp_name); | |
| 150 | + return -1; | |
| 151 | + } | |
| 152 | + Py_XDECREF(((PyFunctionObject *) op) -> func_closure); | |
| 153 | + ((PyFunctionObject *) op) -> func_closure = closure; | |
| 154 | + return 0; | |
| 155 | +} | |
| 156 | + | |
| 157 | +/* Methods */ | |
| 158 | + | |
| 159 | +#define OFF(x) offsetof(PyFunctionObject, x) | |
| 160 | + | |
| 161 | +static PyMemberDef func_memberlist[] = { | |
| 162 | + {"func_closure", T_OBJECT, OFF(func_closure), | |
| 163 | + RESTRICTED|READONLY}, | |
| 164 | + {"func_doc", T_OBJECT, OFF(func_doc), WRITE_RESTRICTED}, | |
| 165 | + {"__doc__", T_OBJECT, OFF(func_doc), WRITE_RESTRICTED}, | |
| 166 | + {"func_globals", T_OBJECT, OFF(func_globals), | |
| 167 | + RESTRICTED|READONLY}, | |
| 168 | + {"__module__", T_OBJECT, OFF(func_module), WRITE_RESTRICTED}, | |
| 169 | + {NULL} /* Sentinel */ | |
| 170 | +}; | |
| 171 | + | |
| 172 | +static int | |
| 173 | +restricted(void) | |
| 174 | +{ | |
| 175 | + if (!PyEval_GetRestricted()) | |
| 176 | + return 0; | |
| 177 | + PyErr_SetString(PyExc_RuntimeError, | |
| 178 | + "function attributes not accessible in restricted mode"); | |
| 179 | + return 1; | |
| 180 | +} | |
| 181 | + | |
| 182 | +static PyObject * | |
| 183 | +func_get_dict(PyFunctionObject *op) | |
| 184 | +{ | |
| 185 | + if (restricted()) | |
| 186 | + return NULL; | |
| 187 | + if (op->func_dict == NULL) { | |
| 188 | + op->func_dict = PyDict_New(); | |
| 189 | + if (op->func_dict == NULL) | |
| 190 | + return NULL; | |
| 191 | + } | |
| 192 | + Py_INCREF(op->func_dict); | |
| 193 | + return op->func_dict; | |
| 194 | +} | |
| 195 | + | |
| 196 | +static int | |
| 197 | +func_set_dict(PyFunctionObject *op, PyObject *value) | |
| 198 | +{ | |
| 199 | + PyObject *tmp; | |
| 200 | + | |
| 201 | + if (restricted()) | |
| 202 | + return -1; | |
| 203 | + /* It is illegal to del f.func_dict */ | |
| 204 | + if (value == NULL) { | |
| 205 | + PyErr_SetString(PyExc_TypeError, | |
| 206 | + "function's dictionary may not be deleted"); | |
| 207 | + return -1; | |
| 208 | + } | |
| 209 | + /* Can only set func_dict to a dictionary */ | |
| 210 | + if (!PyDict_Check(value)) { | |
| 211 | + PyErr_SetString(PyExc_TypeError, | |
| 212 | + "setting function's dictionary to a non-dict"); | |
| 213 | + return -1; | |
| 214 | + } | |
| 215 | + tmp = op->func_dict; | |
| 216 | + Py_INCREF(value); | |
| 217 | + op->func_dict = value; | |
| 218 | + Py_XDECREF(tmp); | |
| 219 | + return 0; | |
| 220 | +} | |
| 221 | + | |
| 222 | +static PyObject * | |
| 223 | +func_get_code(PyFunctionObject *op) | |
| 224 | +{ | |
| 225 | + if (restricted()) | |
| 226 | + return NULL; | |
| 227 | + Py_INCREF(op->func_code); | |
| 228 | + return op->func_code; | |
| 229 | +} | |
| 230 | + | |
| 231 | +static int | |
| 232 | +func_set_code(PyFunctionObject *op, PyObject *value) | |
| 233 | +{ | |
| 234 | + PyObject *tmp; | |
| 235 | + Py_ssize_t nfree, nclosure; | |
| 236 | + | |
| 237 | + if (restricted()) | |
| 238 | + return -1; | |
| 239 | + /* Not legal to del f.func_code or to set it to anything | |
| 240 | + * other than a code object. */ | |
| 241 | + if (value == NULL || !PyCode_Check(value)) { | |
| 242 | + PyErr_SetString(PyExc_TypeError, | |
| 243 | + "func_code must be set to a code object"); | |
| 244 | + return -1; | |
| 245 | + } | |
| 246 | + nfree = PyCode_GetNumFree((PyCodeObject *)value); | |
| 247 | + nclosure = (op->func_closure == NULL ? 0 : | |
| 248 | + PyTuple_GET_SIZE(op->func_closure)); | |
| 249 | + if (nclosure != nfree) { | |
| 250 | + PyErr_Format(PyExc_ValueError, | |
| 251 | + "%s() requires a code object with %zd free vars," | |
| 252 | + " not %zd", | |
| 253 | + PyString_AsString(op->func_name), | |
| 254 | + nclosure, nfree); | |
| 255 | + return -1; | |
| 256 | + } | |
| 257 | + tmp = op->func_code; | |
| 258 | + Py_INCREF(value); | |
| 259 | + op->func_code = value; | |
| 260 | + Py_DECREF(tmp); | |
| 261 | + return 0; | |
| 262 | +} | |
| 263 | + | |
| 264 | +static PyObject * | |
| 265 | +func_get_name(PyFunctionObject *op) | |
| 266 | +{ | |
| 267 | + Py_INCREF(op->func_name); | |
| 268 | + return op->func_name; | |
| 269 | +} | |
| 270 | + | |
| 271 | +static int | |
| 272 | +func_set_name(PyFunctionObject *op, PyObject *value) | |
| 273 | +{ | |
| 274 | + PyObject *tmp; | |
| 275 | + | |
| 276 | + if (restricted()) | |
| 277 | + return -1; | |
| 278 | + /* Not legal to del f.func_name or to set it to anything | |
| 279 | + * other than a string object. */ | |
| 280 | + if (value == NULL || !PyString_Check(value)) { | |
| 281 | + PyErr_SetString(PyExc_TypeError, | |
| 282 | + "func_name must be set to a string object"); | |
| 283 | + return -1; | |
| 284 | + } | |
| 285 | + tmp = op->func_name; | |
| 286 | + Py_INCREF(value); | |
| 287 | + op->func_name = value; | |
| 288 | + Py_DECREF(tmp); | |
| 289 | + return 0; | |
| 290 | +} | |
| 291 | + | |
| 292 | +static PyObject * | |
| 293 | +func_get_defaults(PyFunctionObject *op) | |
| 294 | +{ | |
| 295 | + if (restricted()) | |
| 296 | + return NULL; | |
| 297 | + if (op->func_defaults == NULL) { | |
| 298 | + Py_INCREF(Py_None); | |
| 299 | + return Py_None; | |
| 300 | + } | |
| 301 | + Py_INCREF(op->func_defaults); | |
| 302 | + return op->func_defaults; | |
| 303 | +} | |
| 304 | + | |
| 305 | +static int | |
| 306 | +func_set_defaults(PyFunctionObject *op, PyObject *value) | |
| 307 | +{ | |
| 308 | + PyObject *tmp; | |
| 309 | + | |
| 310 | + if (restricted()) | |
| 311 | + return -1; | |
| 312 | + /* Legal to del f.func_defaults. | |
| 313 | + * Can only set func_defaults to NULL or a tuple. */ | |
| 314 | + if (value == Py_None) | |
| 315 | + value = NULL; | |
| 316 | + if (value != NULL && !PyTuple_Check(value)) { | |
| 317 | + PyErr_SetString(PyExc_TypeError, | |
| 318 | + "func_defaults must be set to a tuple object"); | |
| 319 | + return -1; | |
| 320 | + } | |
| 321 | + tmp = op->func_defaults; | |
| 322 | + Py_XINCREF(value); | |
| 323 | + op->func_defaults = value; | |
| 324 | + Py_XDECREF(tmp); | |
| 325 | + return 0; | |
| 326 | +} | |
| 327 | + | |
| 328 | +static PyGetSetDef func_getsetlist[] = { | |
| 329 | + {"func_code", (getter)func_get_code, (setter)func_set_code}, | |
| 330 | + {"func_defaults", (getter)func_get_defaults, | |
| 331 | + (setter)func_set_defaults}, | |
| 332 | + {"func_dict", (getter)func_get_dict, (setter)func_set_dict}, | |
| 333 | + {"__dict__", (getter)func_get_dict, (setter)func_set_dict}, | |
| 334 | + {"func_name", (getter)func_get_name, (setter)func_set_name}, | |
| 335 | + {"__name__", (getter)func_get_name, (setter)func_set_name}, | |
| 336 | + {NULL} /* Sentinel */ | |
| 337 | +}; | |
| 338 | + | |
| 339 | +PyDoc_STRVAR(func_doc, | |
| 340 | +"function(code, globals[, name[, argdefs[, closure]]])\n\ | |
| 341 | +\n\ | |
| 342 | +Create a function object from a code object and a dictionary.\n\ | |
| 343 | +The optional name string overrides the name from the code object.\n\ | |
| 344 | +The optional argdefs tuple specifies the default argument values.\n\ | |
| 345 | +The optional closure tuple supplies the bindings for free variables."); | |
| 346 | + | |
| 347 | +/* func_new() maintains the following invariants for closures. The | |
| 348 | + closure must correspond to the free variables of the code object. | |
| 349 | + | |
| 350 | + if len(code.co_freevars) == 0: | |
| 351 | + closure = NULL | |
| 352 | + else: | |
| 353 | + len(closure) == len(code.co_freevars) | |
| 354 | + for every elt in closure, type(elt) == cell | |
| 355 | +*/ | |
| 356 | + | |
| 357 | +static PyObject * | |
| 358 | +func_new(PyTypeObject* type, PyObject* args, PyObject* kw) | |
| 359 | +{ | |
| 360 | + PyCodeObject *code; | |
| 361 | + PyObject *globals; | |
| 362 | + PyObject *name = Py_None; | |
| 363 | + PyObject *defaults = Py_None; | |
| 364 | + PyObject *closure = Py_None; | |
| 365 | + PyFunctionObject *newfunc; | |
| 366 | + Py_ssize_t nfree, nclosure; | |
| 367 | + static char *kwlist[] = {"code", "globals", "name", | |
| 368 | + "argdefs", "closure", 0}; | |
| 369 | + | |
| 370 | + if (!PyArg_ParseTupleAndKeywords(args, kw, "O!O!|OOO:function", | |
| 371 | + kwlist, | |
| 372 | + &PyCode_Type, &code, | |
| 373 | + &PyDict_Type, &globals, | |
| 374 | + &name, &defaults, &closure)) | |
| 375 | + return NULL; | |
| 376 | + if (name != Py_None && !PyString_Check(name)) { | |
| 377 | + PyErr_SetString(PyExc_TypeError, | |
| 378 | + "arg 3 (name) must be None or string"); | |
| 379 | + return NULL; | |
| 380 | + } | |
| 381 | + if (defaults != Py_None && !PyTuple_Check(defaults)) { | |
| 382 | + PyErr_SetString(PyExc_TypeError, | |
| 383 | + "arg 4 (defaults) must be None or tuple"); | |
| 384 | + return NULL; | |
| 385 | + } | |
| 386 | + nfree = PyTuple_GET_SIZE(code->co_freevars); | |
| 387 | + if (!PyTuple_Check(closure)) { | |
| 388 | + if (nfree && closure == Py_None) { | |
| 389 | + PyErr_SetString(PyExc_TypeError, | |
| 390 | + "arg 5 (closure) must be tuple"); | |
| 391 | + return NULL; | |
| 392 | + } | |
| 393 | + else if (closure != Py_None) { | |
| 394 | + PyErr_SetString(PyExc_TypeError, | |
| 395 | + "arg 5 (closure) must be None or tuple"); | |
| 396 | + return NULL; | |
| 397 | + } | |
| 398 | + } | |
| 399 | + | |
| 400 | + /* check that the closure is well-formed */ | |
| 401 | + nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure); | |
| 402 | + if (nfree != nclosure) | |
| 403 | + return PyErr_Format(PyExc_ValueError, | |
| 404 | + "%s requires closure of length %zd, not %zd", | |
| 405 | + PyString_AS_STRING(code->co_name), | |
| 406 | + nfree, nclosure); | |
| 407 | + if (nclosure) { | |
| 408 | + Py_ssize_t i; | |
| 409 | + for (i = 0; i < nclosure; i++) { | |
| 410 | + PyObject *o = PyTuple_GET_ITEM(closure, i); | |
| 411 | + if (!PyCell_Check(o)) { | |
| 412 | + return PyErr_Format(PyExc_TypeError, | |
| 413 | + "arg 5 (closure) expected cell, found %s", | |
| 414 | + o->ob_type->tp_name); | |
| 415 | + } | |
| 416 | + } | |
| 417 | + } | |
| 418 | + | |
| 419 | + newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code, | |
| 420 | + globals); | |
| 421 | + if (newfunc == NULL) | |
| 422 | + return NULL; | |
| 423 | + | |
| 424 | + if (name != Py_None) { | |
| 425 | + Py_INCREF(name); | |
| 426 | + Py_DECREF(newfunc->func_name); | |
| 427 | + newfunc->func_name = name; | |
| 428 | + } | |
| 429 | + if (defaults != Py_None) { | |
| 430 | + Py_INCREF(defaults); | |
| 431 | + newfunc->func_defaults = defaults; | |
| 432 | + } | |
| 433 | + if (closure != Py_None) { | |
| 434 | + Py_INCREF(closure); | |
| 435 | + newfunc->func_closure = closure; | |
| 436 | + } | |
| 437 | + | |
| 438 | + return (PyObject *)newfunc; | |
| 439 | +} | |
| 440 | + | |
| 441 | +static void | |
| 442 | +func_dealloc(PyFunctionObject *op) | |
| 443 | +{ | |
| 444 | + _PyObject_GC_UNTRACK(op); | |
| 445 | + if (op->func_weakreflist != NULL) | |
| 446 | + PyObject_ClearWeakRefs((PyObject *) op); | |
| 447 | + Py_DECREF(op->func_code); | |
| 448 | + Py_DECREF(op->func_globals); | |
| 449 | + Py_XDECREF(op->func_module); | |
| 450 | + Py_DECREF(op->func_name); | |
| 451 | + Py_XDECREF(op->func_defaults); | |
| 452 | + Py_XDECREF(op->func_doc); | |
| 453 | + Py_XDECREF(op->func_dict); | |
| 454 | + Py_XDECREF(op->func_closure); | |
| 455 | + PyObject_GC_Del(op); | |
| 456 | +} | |
| 457 | + | |
| 458 | +static PyObject* | |
| 459 | +func_repr(PyFunctionObject *op) | |
| 460 | +{ | |
| 461 | + return PyString_FromFormat("<function %s at %p>", | |
| 462 | + PyString_AsString(op->func_name), | |
| 463 | + op); | |
| 464 | +} | |
| 465 | + | |
| 466 | +static int | |
| 467 | +func_traverse(PyFunctionObject *f, visitproc visit, void *arg) | |
| 468 | +{ | |
| 469 | + Py_VISIT(f->func_code); | |
| 470 | + Py_VISIT(f->func_globals); | |
| 471 | + Py_VISIT(f->func_module); | |
| 472 | + Py_VISIT(f->func_defaults); | |
| 473 | + Py_VISIT(f->func_doc); | |
| 474 | + Py_VISIT(f->func_name); | |
| 475 | + Py_VISIT(f->func_dict); | |
| 476 | + Py_VISIT(f->func_closure); | |
| 477 | + return 0; | |
| 478 | +} | |
| 479 | + | |
| 480 | +static PyObject * | |
| 481 | +function_call(PyObject *func, PyObject *arg, PyObject *kw) | |
| 482 | +{ | |
| 483 | + PyObject *result; | |
| 484 | + PyObject *argdefs; | |
| 485 | + PyObject **d, **k; | |
| 486 | + Py_ssize_t nk, nd; | |
| 487 | + | |
| 488 | + argdefs = PyFunction_GET_DEFAULTS(func); | |
| 489 | + if (argdefs != NULL && PyTuple_Check(argdefs)) { | |
| 490 | + d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0); | |
| 491 | + nd = PyTuple_Size(argdefs); | |
| 492 | + } | |
| 493 | + else { | |
| 494 | + d = NULL; | |
| 495 | + nd = 0; | |
| 496 | + } | |
| 497 | + | |
| 498 | + if (kw != NULL && PyDict_Check(kw)) { | |
| 499 | + Py_ssize_t pos, i; | |
| 500 | + nk = PyDict_Size(kw); | |
| 501 | + k = PyMem_NEW(PyObject *, 2*nk); | |
| 502 | + if (k == NULL) { | |
| 503 | + PyErr_NoMemory(); | |
| 504 | + return NULL; | |
| 505 | + } | |
| 506 | + pos = i = 0; | |
| 507 | + while (PyDict_Next(kw, &pos, &k[i], &k[i+1])) | |
| 508 | + i += 2; | |
| 509 | + nk = i/2; | |
| 510 | + /* XXX This is broken if the caller deletes dict items! */ | |
| 511 | + } | |
| 512 | + else { | |
| 513 | + k = NULL; | |
| 514 | + nk = 0; | |
| 515 | + } | |
| 516 | + | |
| 517 | + result = PyEval_EvalCodeEx( | |
| 518 | + (PyCodeObject *)PyFunction_GET_CODE(func), | |
| 519 | + PyFunction_GET_GLOBALS(func), (PyObject *)NULL, | |
| 520 | + &PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg), | |
| 521 | + k, nk, d, nd, | |
| 522 | + PyFunction_GET_CLOSURE(func)); | |
| 523 | + | |
| 524 | + if (k != NULL) | |
| 525 | + PyMem_DEL(k); | |
| 526 | + | |
| 527 | + return result; | |
| 528 | +} | |
| 529 | + | |
| 530 | +/* Bind a function to an object */ | |
| 531 | +static PyObject * | |
| 532 | +func_descr_get(PyObject *func, PyObject *obj, PyObject *type) | |
| 533 | +{ | |
| 534 | + if (obj == Py_None) | |
| 535 | + obj = NULL; | |
| 536 | + return PyMethod_New(func, obj, type); | |
| 537 | +} | |
| 538 | + | |
| 539 | +PyTypeObject PyFunction_Type = { | |
| 540 | + PyObject_HEAD_INIT(&PyType_Type) | |
| 541 | + 0, | |
| 542 | + "function", | |
| 543 | + sizeof(PyFunctionObject), | |
| 544 | + 0, | |
| 545 | + (destructor)func_dealloc, /* tp_dealloc */ | |
| 546 | + 0, /* tp_print */ | |
| 547 | + 0, /* tp_getattr */ | |
| 548 | + 0, /* tp_setattr */ | |
| 549 | + 0, /* tp_compare */ | |
| 550 | + (reprfunc)func_repr, /* tp_repr */ | |
| 551 | + 0, /* tp_as_number */ | |
| 552 | + 0, /* tp_as_sequence */ | |
| 553 | + 0, /* tp_as_mapping */ | |
| 554 | + 0, /* tp_hash */ | |
| 555 | + function_call, /* tp_call */ | |
| 556 | + 0, /* tp_str */ | |
| 557 | + PyObject_GenericGetAttr, /* tp_getattro */ | |
| 558 | + PyObject_GenericSetAttr, /* tp_setattro */ | |
| 559 | + 0, /* tp_as_buffer */ | |
| 560 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | |
| 561 | + func_doc, /* tp_doc */ | |
| 562 | + (traverseproc)func_traverse, /* tp_traverse */ | |
| 563 | + 0, /* tp_clear */ | |
| 564 | + 0, /* tp_richcompare */ | |
| 565 | + offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */ | |
| 566 | + 0, /* tp_iter */ | |
| 567 | + 0, /* tp_iternext */ | |
| 568 | + 0, /* tp_methods */ | |
| 569 | + func_memberlist, /* tp_members */ | |
| 570 | + func_getsetlist, /* tp_getset */ | |
| 571 | + 0, /* tp_base */ | |
| 572 | + 0, /* tp_dict */ | |
| 573 | + func_descr_get, /* tp_descr_get */ | |
| 574 | + 0, /* tp_descr_set */ | |
| 575 | + offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */ | |
| 576 | + 0, /* tp_init */ | |
| 577 | + 0, /* tp_alloc */ | |
| 578 | + func_new, /* tp_new */ | |
| 579 | +}; | |
| 580 | + | |
| 581 | + | |
| 582 | +/* Class method object */ | |
| 583 | + | |
| 584 | +/* A class method receives the class as implicit first argument, | |
| 585 | + just like an instance method receives the instance. | |
| 586 | + To declare a class method, use this idiom: | |
| 587 | + | |
| 588 | + class C: | |
| 589 | + def f(cls, arg1, arg2, ...): ... | |
| 590 | + f = classmethod(f) | |
| 591 | + | |
| 592 | + It can be called either on the class (e.g. C.f()) or on an instance | |
| 593 | + (e.g. C().f()); the instance is ignored except for its class. | |
| 594 | + If a class method is called for a derived class, the derived class | |
| 595 | + object is passed as the implied first argument. | |
| 596 | + | |
| 597 | + Class methods are different than C++ or Java static methods. | |
| 598 | + If you want those, see static methods below. | |
| 599 | +*/ | |
| 600 | + | |
| 601 | +typedef struct { | |
| 602 | + PyObject_HEAD | |
| 603 | + PyObject *cm_callable; | |
| 604 | +} classmethod; | |
| 605 | + | |
| 606 | +static void | |
| 607 | +cm_dealloc(classmethod *cm) | |
| 608 | +{ | |
| 609 | + _PyObject_GC_UNTRACK((PyObject *)cm); | |
| 610 | + Py_XDECREF(cm->cm_callable); | |
| 611 | + cm->ob_type->tp_free((PyObject *)cm); | |
| 612 | +} | |
| 613 | + | |
| 614 | +static int | |
| 615 | +cm_traverse(classmethod *cm, visitproc visit, void *arg) | |
| 616 | +{ | |
| 617 | + Py_VISIT(cm->cm_callable); | |
| 618 | + return 0; | |
| 619 | +} | |
| 620 | + | |
| 621 | +static int | |
| 622 | +cm_clear(classmethod *cm) | |
| 623 | +{ | |
| 624 | + Py_CLEAR(cm->cm_callable); | |
| 625 | + return 0; | |
| 626 | +} | |
| 627 | + | |
| 628 | + | |
| 629 | +static PyObject * | |
| 630 | +cm_descr_get(PyObject *self, PyObject *obj, PyObject *type) | |
| 631 | +{ | |
| 632 | + classmethod *cm = (classmethod *)self; | |
| 633 | + | |
| 634 | + if (cm->cm_callable == NULL) { | |
| 635 | + PyErr_SetString(PyExc_RuntimeError, | |
| 636 | + "uninitialized classmethod object"); | |
| 637 | + return NULL; | |
| 638 | + } | |
| 639 | + if (type == NULL) | |
| 640 | + type = (PyObject *)(obj->ob_type); | |
| 641 | + return PyMethod_New(cm->cm_callable, | |
| 642 | + type, (PyObject *)(type->ob_type)); | |
| 643 | +} | |
| 644 | + | |
| 645 | +static int | |
| 646 | +cm_init(PyObject *self, PyObject *args, PyObject *kwds) | |
| 647 | +{ | |
| 648 | + classmethod *cm = (classmethod *)self; | |
| 649 | + PyObject *callable; | |
| 650 | + | |
| 651 | + if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable)) | |
| 652 | + return -1; | |
| 653 | + if (!_PyArg_NoKeywords("classmethod", kwds)) | |
| 654 | + return -1; | |
| 655 | + if (!PyCallable_Check(callable)) { | |
233 more lines aren’t shown here.
This diff is large: its 384 lines aren’t shown here.
This diff is large: its 1281 lines aren’t shown here.
This diff is large: its 233 lines aren’t shown here.
This diff is large: its 2931 lines aren’t shown here.
This diff is large: its 678 lines aren’t shown here.
This diff is large: its 3459 lines aren’t shown here.
This diff is large: its 366 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 260 lines aren’t shown here.
This diff is large: its 2140 lines aren’t shown here.
This diff is large: its 1746 lines aren’t shown here.
This diff is large: its 302 lines aren’t shown here.
This diff is large: its 2313 lines aren’t shown here.
This diff is large: its 352 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 5010 lines aren’t shown here.
This diff is large: its 408 lines aren’t shown here.
This diff is large: its 891 lines aren’t shown here.
This diff is large: its 5892 lines aren’t shown here.
This diff is large: its 790 lines aren’t shown here.
This diff is large: its 8068 lines aren’t shown here.
This diff is large: its 1270 lines aren’t shown here.
This diff is large: its 942 lines aren’t shown here.