Changeset 388 for python/vendor/current/Objects/structseq.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Objects/structseq.c
r2 r388 10 10 static char unnamed_fields_key[] = "n_unnamed_fields"; 11 11 12 /* Fields with this name have only a field index, not a field name. 12 /* Fields with this name have only a field index, not a field name. 13 13 They are only allowed for indices < n_visible_fields. */ 14 14 char *PyStructSequence_UnnamedField = "unnamed field"; … … 30 30 PyStructSequence_New(PyTypeObject *type) 31 31 { 32 33 34 35 36 37 38 39 32 PyStructSequence *obj; 33 34 obj = PyObject_New(PyStructSequence, type); 35 if (obj == NULL) 36 return NULL; 37 Py_SIZE(obj) = VISIBLE_SIZE_TP(type); 38 39 return (PyObject*) obj; 40 40 } 41 41 … … 43 43 structseq_dealloc(PyStructSequence *obj) 44 44 { 45 46 47 48 49 50 51 45 Py_ssize_t i, size; 46 47 size = REAL_SIZE(obj); 48 for (i = 0; i < size; ++i) { 49 Py_XDECREF(obj->ob_item[i]); 50 } 51 PyObject_Del(obj); 52 52 } 53 53 … … 55 55 structseq_length(PyStructSequence *obj) 56 56 { 57 57 return VISIBLE_SIZE(obj); 58 58 } 59 59 … … 61 61 structseq_item(PyStructSequence *obj, Py_ssize_t i) 62 62 { 63 64 65 66 67 68 63 if (i < 0 || i >= VISIBLE_SIZE(obj)) { 64 PyErr_SetString(PyExc_IndexError, "tuple index out of range"); 65 return NULL; 66 } 67 Py_INCREF(obj->ob_item[i]); 68 return obj->ob_item[i]; 69 69 } 70 70 … … 72 72 structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high) 73 73 { 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 74 PyTupleObject *np; 75 Py_ssize_t i; 76 77 if (low < 0) 78 low = 0; 79 if (high > VISIBLE_SIZE(obj)) 80 high = VISIBLE_SIZE(obj); 81 if (high < low) 82 high = low; 83 np = (PyTupleObject *)PyTuple_New(high-low); 84 if (np == NULL) 85 return NULL; 86 for(i = low; i < high; ++i) { 87 PyObject *v = obj->ob_item[i]; 88 Py_INCREF(v); 89 PyTuple_SET_ITEM(np, i-low, v); 90 } 91 return (PyObject *) np; 92 92 } 93 93 … … 95 95 structseq_subscript(PyStructSequence *self, PyObject *item) 96 96 { 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 97 if (PyIndex_Check(item)) { 98 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); 99 if (i == -1 && PyErr_Occurred()) 100 return NULL; 101 102 if (i < 0) 103 i += VISIBLE_SIZE(self); 104 105 if (i < 0 || i >= VISIBLE_SIZE(self)) { 106 PyErr_SetString(PyExc_IndexError, 107 "tuple index out of range"); 108 return NULL; 109 } 110 Py_INCREF(self->ob_item[i]); 111 return self->ob_item[i]; 112 } 113 else if (PySlice_Check(item)) { 114 Py_ssize_t start, stop, step, slicelen, cur, i; 115 PyObject *result; 116 117 if (PySlice_GetIndicesEx((PySliceObject *)item, 118 VISIBLE_SIZE(self), &start, &stop, 119 &step, &slicelen) < 0) { 120 return NULL; 121 } 122 if (slicelen <= 0) 123 return PyTuple_New(0); 124 result = PyTuple_New(slicelen); 125 if (result == NULL) 126 return NULL; 127 for (cur = start, i = 0; i < slicelen; 128 cur += step, i++) { 129 PyObject *v = self->ob_item[cur]; 130 Py_INCREF(v); 131 PyTuple_SET_ITEM(result, i, v); 132 } 133 return result; 134 } 135 else { 136 PyErr_SetString(PyExc_TypeError, 137 "structseq index must be integer"); 138 return NULL; 139 } 140 140 } 141 141 … … 143 143 structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 144 144 { 145 PyObject *arg = NULL; 146 PyObject *dict = NULL; 147 PyObject *ob; 148 PyStructSequence *res = NULL; 149 Py_ssize_t len, min_len, max_len, i, n_unnamed_fields; 150 static char *kwlist[] = {"sequence", "dict", 0}; 151 152 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq", 153 kwlist, &arg, &dict)) 154 return NULL; 155 156 arg = PySequence_Fast(arg, "constructor requires a sequence"); 157 158 if (!arg) { 159 return NULL; 160 } 161 162 if (dict && !PyDict_Check(dict)) { 163 PyErr_Format(PyExc_TypeError, 164 "%.500s() takes a dict as second arg, if any", 165 type->tp_name); 166 Py_DECREF(arg); 167 return NULL; 168 } 169 170 len = PySequence_Fast_GET_SIZE(arg); 171 min_len = VISIBLE_SIZE_TP(type); 172 max_len = REAL_SIZE_TP(type); 173 n_unnamed_fields = UNNAMED_FIELDS_TP(type); 174 175 if (min_len != max_len) { 176 if (len < min_len) { 177 PyErr_Format(PyExc_TypeError, 178 "%.500s() takes an at least %zd-sequence (%zd-sequence given)", 179 type->tp_name, min_len, len); 180 Py_DECREF(arg); 181 return NULL; 182 } 183 184 if (len > max_len) { 185 PyErr_Format(PyExc_TypeError, 186 "%.500s() takes an at most %zd-sequence (%zd-sequence given)", 187 type->tp_name, max_len, len); 188 Py_DECREF(arg); 189 return NULL; 190 } 191 } 192 else { 193 if (len != min_len) { 194 PyErr_Format(PyExc_TypeError, 195 "%.500s() takes a %zd-sequence (%zd-sequence given)", 196 type->tp_name, min_len, len); 197 Py_DECREF(arg); 198 return NULL; 199 } 200 } 201 202 res = (PyStructSequence*) PyStructSequence_New(type); 203 if (res == NULL) { 204 return NULL; 205 } 206 for (i = 0; i < len; ++i) { 207 PyObject *v = PySequence_Fast_GET_ITEM(arg, i); 208 Py_INCREF(v); 209 res->ob_item[i] = v; 210 } 211 for (; i < max_len; ++i) { 212 if (dict && (ob = PyDict_GetItemString( 213 dict, type->tp_members[i-n_unnamed_fields].name))) { 214 } 215 else { 216 ob = Py_None; 217 } 218 Py_INCREF(ob); 219 res->ob_item[i] = ob; 220 } 221 222 Py_DECREF(arg); 223 return (PyObject*) res; 145 PyObject *arg = NULL; 146 PyObject *dict = NULL; 147 PyObject *ob; 148 PyStructSequence *res = NULL; 149 Py_ssize_t len, min_len, max_len, i, n_unnamed_fields; 150 static char *kwlist[] = {"sequence", "dict", 0}; 151 152 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq", 153 kwlist, &arg, &dict)) 154 return NULL; 155 156 arg = PySequence_Fast(arg, "constructor requires a sequence"); 157 158 if (!arg) { 159 return NULL; 160 } 161 162 if (dict && !PyDict_Check(dict)) { 163 PyErr_Format(PyExc_TypeError, 164 "%.500s() takes a dict as second arg, if any", 165 type->tp_name); 166 Py_DECREF(arg); 167 return NULL; 168 } 169 170 len = PySequence_Fast_GET_SIZE(arg); 171 min_len = VISIBLE_SIZE_TP(type); 172 max_len = REAL_SIZE_TP(type); 173 n_unnamed_fields = UNNAMED_FIELDS_TP(type); 174 175 if (min_len != max_len) { 176 if (len < min_len) { 177 PyErr_Format(PyExc_TypeError, 178 "%.500s() takes an at least %zd-sequence (%zd-sequence given)", 179 type->tp_name, min_len, len); 180 Py_DECREF(arg); 181 return NULL; 182 } 183 184 if (len > max_len) { 185 PyErr_Format(PyExc_TypeError, 186 "%.500s() takes an at most %zd-sequence (%zd-sequence given)", 187 type->tp_name, max_len, len); 188 Py_DECREF(arg); 189 return NULL; 190 } 191 } 192 else { 193 if (len != min_len) { 194 PyErr_Format(PyExc_TypeError, 195 "%.500s() takes a %zd-sequence (%zd-sequence given)", 196 type->tp_name, min_len, len); 197 Py_DECREF(arg); 198 return NULL; 199 } 200 } 201 202 res = (PyStructSequence*) PyStructSequence_New(type); 203 if (res == NULL) { 204 Py_DECREF(arg); 205 return NULL; 206 } 207 for (i = 0; i < len; ++i) { 208 PyObject *v = PySequence_Fast_GET_ITEM(arg, i); 209 Py_INCREF(v); 210 res->ob_item[i] = v; 211 } 212 for (; i < max_len; ++i) { 213 if (dict && (ob = PyDict_GetItemString( 214 dict, type->tp_members[i-n_unnamed_fields].name))) { 215 } 216 else { 217 ob = Py_None; 218 } 219 Py_INCREF(ob); 220 res->ob_item[i] = ob; 221 } 222 223 Py_DECREF(arg); 224 return (PyObject*) res; 224 225 } 225 226 … … 227 228 make_tuple(PyStructSequence *obj) 228 229 { 229 230 return structseq_slice(obj, 0, VISIBLE_SIZE(obj)); 230 231 } 231 232 … … 233 234 structseq_repr(PyStructSequence *obj) 234 235 { 235 236 /* buffer and type size were chosen well considered. */ 236 237 #define REPR_BUFFER_SIZE 512 237 238 #define TYPE_MAXSIZE 100 238 239 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 240 PyObject *tup; 241 PyTypeObject *typ = Py_TYPE(obj); 242 int i, removelast = 0; 243 Py_ssize_t len; 244 char buf[REPR_BUFFER_SIZE]; 245 char *endofbuf, *pbuf = buf; 246 247 /* pointer to end of writeable buffer; safes space for "...)\0" */ 248 endofbuf= &buf[REPR_BUFFER_SIZE-5]; 249 250 if ((tup = make_tuple(obj)) == NULL) { 251 return NULL; 252 } 253 254 /* "typename(", limited to TYPE_MAXSIZE */ 255 len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE : 256 strlen(typ->tp_name); 257 strncpy(pbuf, typ->tp_name, len); 258 pbuf += len; 259 *pbuf++ = '('; 260 261 for (i=0; i < VISIBLE_SIZE(obj); i++) { 262 PyObject *val, *repr; 263 char *cname, *crepr; 264 265 cname = typ->tp_members[i].name; 266 267 val = PyTuple_GetItem(tup, i); 268 if (cname == NULL || val == NULL) { 269 return NULL; 270 } 271 repr = PyObject_Repr(val); 272 if (repr == NULL) { 273 Py_DECREF(tup); 274 return NULL; 275 } 276 crepr = PyString_AsString(repr); 277 if (crepr == NULL) { 278 Py_DECREF(tup); 279 Py_DECREF(repr); 280 return NULL; 281 } 282 283 /* + 3: keep space for "=" and ", " */ 284 len = strlen(cname) + strlen(crepr) + 3; 285 if ((pbuf+len) <= endofbuf) { 286 strcpy(pbuf, cname); 287 pbuf += strlen(cname); 288 *pbuf++ = '='; 289 strcpy(pbuf, crepr); 290 pbuf += strlen(crepr); 291 *pbuf++ = ','; 292 *pbuf++ = ' '; 293 removelast = 1; 294 Py_DECREF(repr); 295 } 296 else { 297 strcpy(pbuf, "..."); 298 pbuf += 3; 299 removelast = 0; 300 Py_DECREF(repr); 301 break; 302 } 303 } 304 Py_DECREF(tup); 305 if (removelast) { 306 /* overwrite last ", " */ 307 pbuf-=2; 308 } 309 *pbuf++ = ')'; 310 *pbuf = '\0'; 311 312 return PyString_FromString(buf); 312 313 } 313 314 … … 315 316 structseq_concat(PyStructSequence *obj, PyObject *b) 316 317 { 317 318 319 320 321 318 PyObject *tup, *result; 319 tup = make_tuple(obj); 320 result = PySequence_Concat(tup, b); 321 Py_DECREF(tup); 322 return result; 322 323 } 323 324 … … 325 326 structseq_repeat(PyStructSequence *obj, Py_ssize_t n) 326 327 { 327 328 329 330 331 328 PyObject *tup, *result; 329 tup = make_tuple(obj); 330 result = PySequence_Repeat(tup, n); 331 Py_DECREF(tup); 332 return result; 332 333 } 333 334 … … 335 336 structseq_contains(PyStructSequence *obj, PyObject *o) 336 337 { 337 338 339 340 341 342 343 344 338 PyObject *tup; 339 int result; 340 tup = make_tuple(obj); 341 if (!tup) 342 return -1; 343 result = PySequence_Contains(tup, o); 344 Py_DECREF(tup); 345 return result; 345 346 } 346 347 … … 348 349 structseq_hash(PyObject *obj) 349 350 { 350 351 352 353 354 355 356 357 351 PyObject *tup; 352 long result; 353 tup = make_tuple((PyStructSequence*) obj); 354 if (!tup) 355 return -1; 356 result = PyObject_Hash(tup); 357 Py_DECREF(tup); 358 return result; 358 359 } 359 360 … … 361 362 structseq_richcompare(PyObject *obj, PyObject *o2, int op) 362 363 { 363 364 365 366 367 364 PyObject *tup, *result; 365 tup = make_tuple((PyStructSequence*) obj); 366 result = PyObject_RichCompare(tup, o2, op); 367 Py_DECREF(tup); 368 return result; 368 369 } 369 370 … … 371 372 structseq_reduce(PyStructSequence* self) 372 373 { 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 374 PyObject* tup; 375 PyObject* dict; 376 PyObject* result; 377 Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields; 378 int i; 379 380 n_fields = REAL_SIZE(self); 381 n_visible_fields = VISIBLE_SIZE(self); 382 n_unnamed_fields = UNNAMED_FIELDS(self); 383 tup = PyTuple_New(n_visible_fields); 384 if (!tup) { 385 return NULL; 386 } 387 388 dict = PyDict_New(); 389 if (!dict) { 390 Py_DECREF(tup); 391 return NULL; 392 } 393 394 for (i = 0; i < n_visible_fields; i++) { 395 Py_INCREF(self->ob_item[i]); 396 PyTuple_SET_ITEM(tup, i, self->ob_item[i]); 397 } 398 399 for (; i < n_fields; i++) { 400 char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name; 401 PyDict_SetItemString(dict, n, 402 self->ob_item[i]); 403 } 404 405 result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict); 406 407 Py_DECREF(tup); 408 Py_DECREF(dict); 409 410 return result; 410 411 } 411 412 412 413 static PySequenceMethods structseq_as_sequence = { 413 414 415 416 (ssizeargfunc)structseq_item,/* sq_item */417 (ssizessizeargfunc)structseq_slice,/* sq_slice */418 0,/* sq_ass_item */419 0,/* sq_ass_slice */420 (objobjproc)structseq_contains,/* sq_contains */414 (lenfunc)structseq_length, 415 (binaryfunc)structseq_concat, /* sq_concat */ 416 (ssizeargfunc)structseq_repeat, /* sq_repeat */ 417 (ssizeargfunc)structseq_item, /* sq_item */ 418 (ssizessizeargfunc)structseq_slice, /* sq_slice */ 419 0, /* sq_ass_item */ 420 0, /* sq_ass_slice */ 421 (objobjproc)structseq_contains, /* sq_contains */ 421 422 }; 422 423 423 424 static PyMappingMethods structseq_as_mapping = { 424 425 425 (lenfunc)structseq_length, 426 (binaryfunc)structseq_subscript, 426 427 }; 427 428 428 429 static PyMethodDef structseq_methods[] = { 429 {"__reduce__", (PyCFunction)structseq_reduce, 430 431 430 {"__reduce__", (PyCFunction)structseq_reduce, 431 METH_NOARGS, NULL}, 432 {NULL, NULL} 432 433 }; 433 434 434 435 static PyTypeObject _struct_sequence_template = { 435 436 NULL,/* tp_name */437 0,/* tp_basicsize */438 0,/* tp_itemsize */439 (destructor)structseq_dealloc,/* tp_dealloc */440 0,/* tp_print */441 0,/* tp_getattr */442 0,/* tp_setattr */443 0,/* tp_compare */444 (reprfunc)structseq_repr,/* tp_repr */445 0,/* tp_as_number */446 &structseq_as_sequence,/* tp_as_sequence */447 &structseq_as_mapping,/* tp_as_mapping */448 structseq_hash,/* tp_hash */449 0,/* tp_call */450 0,/* tp_str */451 0,/* tp_getattro */452 0,/* tp_setattro */453 0,/* tp_as_buffer */454 455 NULL,/* tp_doc */456 0,/* tp_traverse */457 0,/* tp_clear */458 structseq_richcompare,/* tp_richcompare */459 0,/* tp_weaklistoffset */460 0,/* tp_iter */461 0,/* tp_iternext */462 structseq_methods,/* tp_methods */463 NULL,/* tp_members */464 0,/* tp_getset */465 0,/* tp_base */466 0,/* tp_dict */467 0,/* tp_descr_get */468 0,/* tp_descr_set */469 0,/* tp_dictoffset */470 0,/* tp_init */471 0,/* tp_alloc */472 structseq_new,/* tp_new */436 PyVarObject_HEAD_INIT(&PyType_Type, 0) 437 NULL, /* tp_name */ 438 0, /* tp_basicsize */ 439 0, /* tp_itemsize */ 440 (destructor)structseq_dealloc, /* tp_dealloc */ 441 0, /* tp_print */ 442 0, /* tp_getattr */ 443 0, /* tp_setattr */ 444 0, /* tp_compare */ 445 (reprfunc)structseq_repr, /* tp_repr */ 446 0, /* tp_as_number */ 447 &structseq_as_sequence, /* tp_as_sequence */ 448 &structseq_as_mapping, /* tp_as_mapping */ 449 structseq_hash, /* tp_hash */ 450 0, /* tp_call */ 451 0, /* tp_str */ 452 0, /* tp_getattro */ 453 0, /* tp_setattro */ 454 0, /* tp_as_buffer */ 455 Py_TPFLAGS_DEFAULT, /* tp_flags */ 456 NULL, /* tp_doc */ 457 0, /* tp_traverse */ 458 0, /* tp_clear */ 459 structseq_richcompare, /* tp_richcompare */ 460 0, /* tp_weaklistoffset */ 461 0, /* tp_iter */ 462 0, /* tp_iternext */ 463 structseq_methods, /* tp_methods */ 464 NULL, /* tp_members */ 465 0, /* tp_getset */ 466 0, /* tp_base */ 467 0, /* tp_dict */ 468 0, /* tp_descr_get */ 469 0, /* tp_descr_set */ 470 0, /* tp_dictoffset */ 471 0, /* tp_init */ 472 0, /* tp_alloc */ 473 structseq_new, /* tp_new */ 473 474 }; 474 475 … … 476 477 PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) 477 478 { 478 479 480 479 PyObject *dict; 480 PyMemberDef* members; 481 int n_members, n_unnamed_members, i, k; 481 482 482 483 #ifdef Py_TRACE_REFS 483 484 485 486 487 484 /* if the type object was chained, unchain it first 485 before overwriting its storage */ 486 if (type->_ob_next) { 487 _Py_ForgetReference((PyObject*)type); 488 } 488 489 #endif 489 490 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 #define SET_DICT_FROM_INT(key, value) 528 do {\529 PyObject *v = PyInt_FromLong((long) value);\530 if (v != NULL) {\531 PyDict_SetItemString(dict, key, v);\532 Py_DECREF(v);\533 }\534 535 536 537 538 539 } 491 n_unnamed_members = 0; 492 for (i = 0; desc->fields[i].name != NULL; ++i) 493 if (desc->fields[i].name == PyStructSequence_UnnamedField) 494 n_unnamed_members++; 495 n_members = i; 496 497 memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject)); 498 type->tp_name = desc->name; 499 type->tp_doc = desc->doc; 500 type->tp_basicsize = sizeof(PyStructSequence)+ 501 sizeof(PyObject*)*(n_members-1); 502 type->tp_itemsize = 0; 503 504 members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1); 505 if (members == NULL) 506 return; 507 508 for (i = k = 0; i < n_members; ++i) { 509 if (desc->fields[i].name == PyStructSequence_UnnamedField) 510 continue; 511 members[k].name = desc->fields[i].name; 512 members[k].type = T_OBJECT; 513 members[k].offset = offsetof(PyStructSequence, ob_item) 514 + i * sizeof(PyObject*); 515 members[k].flags = READONLY; 516 members[k].doc = desc->fields[i].doc; 517 k++; 518 } 519 members[k].name = NULL; 520 521 type->tp_members = members; 522 523 if (PyType_Ready(type) < 0) 524 return; 525 Py_INCREF(type); 526 527 dict = type->tp_dict; 528 #define SET_DICT_FROM_INT(key, value) \ 529 do { \ 530 PyObject *v = PyInt_FromLong((long) value); \ 531 if (v != NULL) { \ 532 PyDict_SetItemString(dict, key, v); \ 533 Py_DECREF(v); \ 534 } \ 535 } while (0) 536 537 SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence); 538 SET_DICT_FROM_INT(real_length_key, n_members); 539 SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members); 540 }
Note:
See TracChangeset
for help on using the changeset viewer.