Changeset 388 for python/vendor/current/Objects/sliceobject.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Objects/sliceobject.c
r2 r388 8 8 */ 9 9 10 /* 10 /* 11 11 Py_Ellipsis encodes the '...' rubber index token. It is similar to 12 12 the Py_NoneStruct in that there is no way to create other objects of … … 20 20 ellipsis_repr(PyObject *op) 21 21 { 22 22 return PyString_FromString("Ellipsis"); 23 23 } 24 24 25 25 PyTypeObject PyEllipsis_Type = { 26 27 "ellipsis",/* tp_name */28 0,/* tp_basicsize */29 0,/* tp_itemsize */30 0, /*never called*//* tp_dealloc */31 0,/* tp_print */32 0,/* tp_getattr */33 0,/* tp_setattr */34 0,/* tp_compare */35 ellipsis_repr,/* tp_repr */36 0,/* tp_as_number */37 0,/* tp_as_sequence */38 0,/* tp_as_mapping */39 0,/* tp_hash */40 0,/* tp_call */41 0,/* tp_str */42 PyObject_GenericGetAttr,/* tp_getattro */43 0,/* tp_setattro */44 0,/* tp_as_buffer */45 Py_TPFLAGS_DEFAULT,/* tp_flags */26 PyVarObject_HEAD_INIT(&PyType_Type, 0) 27 "ellipsis", /* tp_name */ 28 0, /* tp_basicsize */ 29 0, /* tp_itemsize */ 30 0, /*never called*/ /* tp_dealloc */ 31 0, /* tp_print */ 32 0, /* tp_getattr */ 33 0, /* tp_setattr */ 34 0, /* tp_compare */ 35 ellipsis_repr, /* tp_repr */ 36 0, /* tp_as_number */ 37 0, /* tp_as_sequence */ 38 0, /* tp_as_mapping */ 39 0, /* tp_hash */ 40 0, /* tp_call */ 41 0, /* tp_str */ 42 PyObject_GenericGetAttr, /* tp_getattro */ 43 0, /* tp_setattro */ 44 0, /* tp_as_buffer */ 45 Py_TPFLAGS_DEFAULT, /* tp_flags */ 46 46 }; 47 47 48 48 PyObject _Py_EllipsisObject = { 49 50 49 _PyObject_EXTRA_INIT 50 1, &PyEllipsis_Type 51 51 }; 52 52 … … 61 61 PySlice_New(PyObject *start, PyObject *stop, PyObject *step) 62 62 { 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 63 PySliceObject *obj = PyObject_New(PySliceObject, &PySlice_Type); 64 65 if (obj == NULL) 66 return NULL; 67 68 if (step == NULL) step = Py_None; 69 Py_INCREF(step); 70 if (start == NULL) start = Py_None; 71 Py_INCREF(start); 72 if (stop == NULL) stop = Py_None; 73 Py_INCREF(stop); 74 75 obj->step = step; 76 obj->start = start; 77 obj->stop = stop; 78 79 return (PyObject *) obj; 80 80 } 81 81 … … 83 83 _PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop) 84 84 { 85 86 87 88 89 90 91 92 93 94 95 96 97 98 85 PyObject *start, *end, *slice; 86 start = PyInt_FromSsize_t(istart); 87 if (!start) 88 return NULL; 89 end = PyInt_FromSsize_t(istop); 90 if (!end) { 91 Py_DECREF(start); 92 return NULL; 93 } 94 95 slice = PySlice_New(start, end, NULL); 96 Py_DECREF(start); 97 Py_DECREF(end); 98 return slice; 99 99 } 100 100 … … 103 103 Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) 104 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 105 /* XXX support long ints */ 106 if (r->step == Py_None) { 107 *step = 1; 108 } else { 109 if (!PyInt_Check(r->step) && !PyLong_Check(r->step)) return -1; 110 *step = PyInt_AsSsize_t(r->step); 111 } 112 if (r->start == Py_None) { 113 *start = *step < 0 ? length-1 : 0; 114 } else { 115 if (!PyInt_Check(r->start) && !PyLong_Check(r->step)) return -1; 116 *start = PyInt_AsSsize_t(r->start); 117 if (*start < 0) *start += length; 118 } 119 if (r->stop == Py_None) { 120 *stop = *step < 0 ? -1 : length; 121 } else { 122 if (!PyInt_Check(r->stop) && !PyLong_Check(r->step)) return -1; 123 *stop = PyInt_AsSsize_t(r->stop); 124 if (*stop < 0) *stop += length; 125 } 126 if (*stop > length) return -1; 127 if (*start >= length) return -1; 128 if (*step == 0) return -1; 129 return 0; 130 130 } 131 131 132 132 int 133 133 PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, 134 135 { 136 137 138 139 140 141 142 } 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 if (*start >= length) 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 if ((*step < 0 && *stop >= *start) 178 179 180 181 182 183 184 185 186 187 188 134 Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) 135 { 136 /* this is harder to get right than you might think */ 137 138 Py_ssize_t defstart, defstop; 139 140 if (r->step == Py_None) { 141 *step = 1; 142 } 143 else { 144 if (!_PyEval_SliceIndex(r->step, step)) return -1; 145 if (*step == 0) { 146 PyErr_SetString(PyExc_ValueError, 147 "slice step cannot be zero"); 148 return -1; 149 } 150 } 151 152 defstart = *step < 0 ? length-1 : 0; 153 defstop = *step < 0 ? -1 : length; 154 155 if (r->start == Py_None) { 156 *start = defstart; 157 } 158 else { 159 if (!_PyEval_SliceIndex(r->start, start)) return -1; 160 if (*start < 0) *start += length; 161 if (*start < 0) *start = (*step < 0) ? -1 : 0; 162 if (*start >= length) 163 *start = (*step < 0) ? length - 1 : length; 164 } 165 166 if (r->stop == Py_None) { 167 *stop = defstop; 168 } 169 else { 170 if (!_PyEval_SliceIndex(r->stop, stop)) return -1; 171 if (*stop < 0) *stop += length; 172 if (*stop < 0) *stop = (*step < 0) ? -1 : 0; 173 if (*stop >= length) 174 *stop = (*step < 0) ? length - 1 : length; 175 } 176 177 if ((*step < 0 && *stop >= *start) 178 || (*step > 0 && *start >= *stop)) { 179 *slicelength = 0; 180 } 181 else if (*step < 0) { 182 *slicelength = (*stop-*start+1)/(*step)+1; 183 } 184 else { 185 *slicelength = (*stop-*start-1)/(*step)+1; 186 } 187 188 return 0; 189 189 } 190 190 … … 192 192 slice_new(PyTypeObject *type, PyObject *args, PyObject *kw) 193 193 { 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 194 PyObject *start, *stop, *step; 195 196 start = stop = step = NULL; 197 198 if (!_PyArg_NoKeywords("slice()", kw)) 199 return NULL; 200 201 if (!PyArg_UnpackTuple(args, "slice", 1, 3, &start, &stop, &step)) 202 return NULL; 203 204 /* This swapping of stop and start is to maintain similarity with 205 range(). */ 206 if (stop == NULL) { 207 stop = start; 208 start = NULL; 209 } 210 return PySlice_New(start, stop, step); 211 211 } 212 212 213 213 PyDoc_STRVAR(slice_doc, 214 "slice([start,] stop[, step])\n\ 214 "slice(stop)\n\ 215 slice(start, stop[, step])\n\ 215 216 \n\ 216 217 Create a slice object. This is used for extended slicing (e.g. a[0:10:2])."); … … 219 220 slice_dealloc(PySliceObject *r) 220 221 { 221 222 223 224 222 Py_DECREF(r->step); 223 Py_DECREF(r->start); 224 Py_DECREF(r->stop); 225 PyObject_Del(r); 225 226 } 226 227 … … 228 229 slice_repr(PySliceObject *r) 229 230 { 230 231 232 233 234 235 236 237 238 239 240 241 231 PyObject *s, *comma; 232 233 s = PyString_FromString("slice("); 234 comma = PyString_FromString(", "); 235 PyString_ConcatAndDel(&s, PyObject_Repr(r->start)); 236 PyString_Concat(&s, comma); 237 PyString_ConcatAndDel(&s, PyObject_Repr(r->stop)); 238 PyString_Concat(&s, comma); 239 PyString_ConcatAndDel(&s, PyObject_Repr(r->step)); 240 PyString_ConcatAndDel(&s, PyString_FromString(")")); 241 Py_DECREF(comma); 242 return s; 242 243 } 243 244 244 245 static PyMemberDef slice_members[] = { 245 246 247 248 246 {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY}, 247 {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY}, 248 {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY}, 249 {0} 249 250 }; 250 251 … … 252 253 slice_indices(PySliceObject* self, PyObject* len) 253 254 { 254 255 256 257 258 259 260 261 262 if (PySlice_GetIndicesEx(self, ilen, &start, &stop, 263 264 265 266 267 255 Py_ssize_t ilen, start, stop, step, slicelength; 256 257 ilen = PyNumber_AsSsize_t(len, PyExc_OverflowError); 258 259 if (ilen == -1 && PyErr_Occurred()) { 260 return NULL; 261 } 262 263 if (PySlice_GetIndicesEx(self, ilen, &start, &stop, 264 &step, &slicelength) < 0) { 265 return NULL; 266 } 267 268 return Py_BuildValue("(nnn)", start, stop, step); 268 269 } 269 270 … … 279 280 slice_reduce(PySliceObject* self) 280 281 { 281 282 return Py_BuildValue("O(OOO)", Py_TYPE(self), self->start, self->stop, self->step); 282 283 } 283 284 … … 285 286 286 287 static PyMethodDef slice_methods[] = { 287 {"indices",(PyCFunction)slice_indices,288 METH_O,slice_indices_doc},289 {"__reduce__",(PyCFunction)slice_reduce,290 METH_NOARGS,reduce_doc},291 288 {"indices", (PyCFunction)slice_indices, 289 METH_O, slice_indices_doc}, 290 {"__reduce__", (PyCFunction)slice_reduce, 291 METH_NOARGS, reduce_doc}, 292 {NULL, NULL} 292 293 }; 293 294 … … 295 296 slice_compare(PySliceObject *v, PySliceObject *w) 296 297 { 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 298 int result = 0; 299 300 if (v == w) 301 return 0; 302 303 if (PyObject_Cmp(v->start, w->start, &result) < 0) 304 return -2; 305 if (result != 0) 306 return result; 307 if (PyObject_Cmp(v->stop, w->stop, &result) < 0) 308 return -2; 309 if (result != 0) 310 return result; 311 if (PyObject_Cmp(v->step, w->step, &result) < 0) 312 return -2; 313 return result; 313 314 } 314 315 … … 316 317 slice_hash(PySliceObject *v) 317 318 { 318 319 319 PyErr_SetString(PyExc_TypeError, "unhashable type"); 320 return -1L; 320 321 } 321 322 322 323 PyTypeObject PySlice_Type = { 323 324 "slice",/* Name of this type */325 sizeof(PySliceObject),/* Basic object size */326 0,/* Item size for varobject */327 (destructor)slice_dealloc,/* tp_dealloc */328 0,/* tp_print */329 0,/* tp_getattr */330 0,/* tp_setattr */331 (cmpfunc)slice_compare,/* tp_compare */332 (reprfunc)slice_repr,/* tp_repr */333 0,/* tp_as_number */334 0,/* tp_as_sequence */335 0,/* tp_as_mapping */336 (hashfunc)slice_hash,/* tp_hash */337 0,/* tp_call */338 0,/* tp_str */339 PyObject_GenericGetAttr,/* tp_getattro */340 0,/* tp_setattro */341 0,/* tp_as_buffer */342 Py_TPFLAGS_DEFAULT,/* tp_flags */343 slice_doc,/* tp_doc */344 0,/* tp_traverse */345 0,/* tp_clear */346 0,/* tp_richcompare */347 0,/* tp_weaklistoffset */348 0,/* tp_iter */349 0,/* tp_iternext */350 slice_methods,/* tp_methods */351 slice_members,/* tp_members */352 0,/* tp_getset */353 0,/* tp_base */354 0,/* tp_dict */355 0,/* tp_descr_get */356 0,/* tp_descr_set */357 0,/* tp_dictoffset */358 0,/* tp_init */359 0,/* tp_alloc */360 slice_new,/* tp_new */361 }; 324 PyVarObject_HEAD_INIT(&PyType_Type, 0) 325 "slice", /* Name of this type */ 326 sizeof(PySliceObject), /* Basic object size */ 327 0, /* Item size for varobject */ 328 (destructor)slice_dealloc, /* tp_dealloc */ 329 0, /* tp_print */ 330 0, /* tp_getattr */ 331 0, /* tp_setattr */ 332 (cmpfunc)slice_compare, /* tp_compare */ 333 (reprfunc)slice_repr, /* tp_repr */ 334 0, /* tp_as_number */ 335 0, /* tp_as_sequence */ 336 0, /* tp_as_mapping */ 337 (hashfunc)slice_hash, /* tp_hash */ 338 0, /* tp_call */ 339 0, /* tp_str */ 340 PyObject_GenericGetAttr, /* tp_getattro */ 341 0, /* tp_setattro */ 342 0, /* tp_as_buffer */ 343 Py_TPFLAGS_DEFAULT, /* tp_flags */ 344 slice_doc, /* tp_doc */ 345 0, /* tp_traverse */ 346 0, /* tp_clear */ 347 0, /* tp_richcompare */ 348 0, /* tp_weaklistoffset */ 349 0, /* tp_iter */ 350 0, /* tp_iternext */ 351 slice_methods, /* tp_methods */ 352 slice_members, /* tp_members */ 353 0, /* tp_getset */ 354 0, /* tp_base */ 355 0, /* tp_dict */ 356 0, /* tp_descr_get */ 357 0, /* tp_descr_set */ 358 0, /* tp_dictoffset */ 359 0, /* tp_init */ 360 0, /* tp_alloc */ 361 slice_new, /* tp_new */ 362 };
Note:
See TracChangeset
for help on using the changeset viewer.