Skip to content

Instantly share code, notes, and snippets.

@ayush-1506
Last active June 25, 2021 08:54
Show Gist options
  • Save ayush-1506/569c2f7a6c9f1d62d35089a984499855 to your computer and use it in GitHub Desktop.
Save ayush-1506/569c2f7a6c9f1d62d35089a984499855 to your computer and use it in GitHub Desktop.
terange is like python's internal range, but each increment happens ten times (hence _terange_). For instance terange(0,100,1) = range(0,100,10). Build instructions: clone cpython, mkdir build, apply this patch, run ./configure --prefix=build --exec_prefix=build, make && make install. Python binary is generated in build/bin/python3.
diff --git a/Include/rangeobject.h b/Include/rangeobject.h
index d6af847..c2b3c4a 100644
--- a/Include/rangeobject.h
+++ b/Include/rangeobject.h
@@ -21,6 +21,17 @@ PyAPI_DATA(PyTypeObject) PyLongRangeIter_Type;
#define PyRange_Check(op) Py_IS_TYPE(op, &PyRange_Type)
+/*
+A completely useless terange, where increment is ten times
+what it should be.
+*/
+
+PyAPI_DATA(PyTypeObject) PyTeRange_Type;
+PyAPI_DATA(PyTypeObject) PyTeRangeIter_Type;
+PyAPI_DATA(PyTypeObject) PyLongTeRangeIter_Type;
+
+#define PyTeRange_Check(op) Py_IS_TYPE(op, &PyTeRange_Type)
+
#ifdef __cplusplus
}
#endif
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index 3e05707..e4e3bcc 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -572,6 +572,23 @@ range_count(rangeobject *r, PyObject *ob)
}
}
+static PyObject *
+terange_count(rangeobject *r, PyObject *ob)
+{
+ if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
+ int result = range_contains_long(r, ob);
+ if (result == -1)
+ return NULL;
+ return PyLong_FromLong(result);
+ } else {
+ Py_ssize_t count;
+ count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
+ if (count == -1)
+ return NULL;
+ return PyLong_FromSsize_t(count);
+ }
+}
+
static PyObject *
range_index(rangeobject *r, PyObject *ob)
{
@@ -610,6 +627,44 @@ range_index(rangeobject *r, PyObject *ob)
return NULL;
}
+static PyObject *
+terange_index(rangeobject *r, PyObject *ob)
+{
+ int contains;
+
+ if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
+ Py_ssize_t index;
+ index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
+ if (index == -1)
+ return NULL;
+ return PyLong_FromSsize_t(index);
+ }
+
+ contains = range_contains_long(r, ob);
+ if (contains == -1)
+ return NULL;
+
+ if (contains) {
+ PyObject *idx = PyNumber_Subtract(ob, r->start);
+ if (idx == NULL) {
+ return NULL;
+ }
+
+ if (r->step == _PyLong_GetOne()) {
+ return idx;
+ }
+
+ /* idx = (ob - r.start) // r.step */
+ PyObject *sidx = PyNumber_FloorDivide(idx, r->step);
+ Py_DECREF(idx);
+ return sidx;
+ }
+
+ /* object is not in the range */
+ PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
+ return NULL;
+}
+
static PySequenceMethods range_as_sequence = {
(lenfunc)range_length, /* sq_length */
0, /* sq_concat */
@@ -641,6 +696,26 @@ range_repr(rangeobject *r)
r->start, r->stop, r->step);
}
+static PyObject *
+terange_repr(rangeobject *r)
+{
+ Py_ssize_t istep;
+
+ /* Check for special case values for printing. We don't always
+ need the step value. We don't care about overflow. */
+ istep = PyNumber_AsSsize_t(r->step, NULL);
+ if (istep == -1 && PyErr_Occurred()) {
+ assert(!PyErr_ExceptionMatches(PyExc_OverflowError));
+ return NULL;
+ }
+
+ if (istep == 1)
+ return PyUnicode_FromFormat("terange(%R, %R)", r->start, r->stop);
+ else
+ return PyUnicode_FromFormat("terange(%R, %R, %R)",
+ r->start, r->stop, r->step);
+}
+
/* Pickling support */
static PyObject *
range_reduce(rangeobject *r, PyObject *args)
@@ -649,6 +724,14 @@ range_reduce(rangeobject *r, PyObject *args)
r->start, r->stop, r->step);
}
+/* Pickling support */
+static PyObject *
+terange_reduce(rangeobject *r, PyObject *args)
+{
+ return Py_BuildValue("(O(OOO))", Py_TYPE(r),
+ r->start, r->stop, r->step);
+}
+
static PyObject *
range_subscript(rangeobject* self, PyObject* item)
{
@@ -688,7 +771,9 @@ static PyNumberMethods range_as_number = {
};
static PyObject * range_iter(PyObject *seq);
+static PyObject * terange_iter(PyObject *seq);
static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored));
+static PyObject * terange_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored));
PyDoc_STRVAR(reverse_doc,
"Return a reverse iterator.");
@@ -715,6 +800,21 @@ static PyMemberDef range_members[] = {
{0}
};
+static PyMethodDef terange_methods[] = {
+ {"__reversed__", terange_reverse, METH_NOARGS, reverse_doc},
+ {"__reduce__", (PyCFunction)terange_reduce, METH_VARARGS},
+ {"count", (PyCFunction)terange_count, METH_O, count_doc},
+ {"index", (PyCFunction)terange_index, METH_O, index_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyMemberDef terange_members[] = {
+ {"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY},
+ {"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY},
+ {"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY},
+ {0}
+};
+
PyTypeObject PyRange_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"range", /* Name of this type */
@@ -757,6 +857,48 @@ PyTypeObject PyRange_Type = {
.tp_vectorcall = (vectorcallfunc)range_vectorcall
};
+PyTypeObject PyTeRange_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "terange", /* Name of this type */
+ sizeof(rangeobject), /* Basic object size */
+ 0, /* Item size for varobject */
+ (destructor)range_dealloc, /* tp_dealloc */
+ 0, /* tp_vectorcall_offset */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_as_async */
+ (reprfunc)terange_repr, /* tp_repr */
+ &range_as_number, /* tp_as_number */
+ &range_as_sequence, /* tp_as_sequence */
+ &range_as_mapping, /* tp_as_mapping */
+ (hashfunc)range_hash, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_SEQUENCE, /* tp_flags */
+ range_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ range_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ terange_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ terange_methods, /* tp_methods */
+ terange_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ range_new, /* tp_new */
+ .tp_vectorcall = (vectorcallfunc)range_vectorcall
+};
+
/*********************** range Iterator **************************/
/* There are 2 types of iterators, one for C longs, the other for
@@ -783,6 +925,17 @@ rangeiter_next(rangeiterobject *r)
return NULL;
}
+static PyObject *
+terangeiter_next(rangeiterobject *r)
+{
+ if (r->index*10 < r->len)
+ /* cast to unsigned to avoid possible signed overflow
+ in intermediate calculations. */
+ return PyLong_FromLong((long)(r->start +
+ (unsigned long)(r->index++) * r->step * 10));
+ return NULL;
+}
+
static PyObject *
rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
{
@@ -822,6 +975,36 @@ rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
return NULL;
}
+static PyObject *
+rangeiter_reduce_terange(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *start=NULL, *stop=NULL, *step=NULL;
+ PyObject *range;
+
+ /* create a range object for pickling */
+ start = PyLong_FromLong(r->start);
+ if (start == NULL)
+ goto err;
+ stop = PyLong_FromLong(r->start + r->len * r->step);
+ if (stop == NULL)
+ goto err;
+ step = PyLong_FromLong(r->step);
+ if (step == NULL)
+ goto err;
+ range = (PyObject*)make_range_object(&PyTeRange_Type,
+ start, stop, step);
+ if (range == NULL)
+ goto err;
+ /* return the result */
+ return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter),
+ range, r->index);
+err:
+ Py_XDECREF(start);
+ Py_XDECREF(stop);
+ Py_XDECREF(step);
+ return NULL;
+}
+
static PyObject *
rangeiter_setstate(rangeiterobject *r, PyObject *state)
{
@@ -883,6 +1066,39 @@ PyTypeObject PyRangeIter_Type = {
0, /* tp_members */
};
+PyTypeObject PyTeRangeIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "range_iterator", /* tp_name */
+ sizeof(rangeiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)PyObject_Del, /* tp_dealloc */
+ 0, /* tp_vectorcall_offset */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_as_async */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)terangeiter_next, /* tp_iternext */
+ rangeiter_methods, /* tp_methods */
+ 0, /* tp_members */
+};
+
/* Return number of items in range (lo, hi, step). step != 0
* required. The result always fits in an unsigned long.
*/
@@ -935,6 +1151,27 @@ fast_range_iter(long start, long stop, long step)
return (PyObject *)it;
}
+static PyObject *
+fast_terange_iter(long start, long stop, long step)
+{
+ rangeiterobject *it = PyObject_New(rangeiterobject, &PyTeRangeIter_Type);
+ unsigned long ulen;
+ if (it == NULL)
+ return NULL;
+ it->start = start;
+ it->step = step;
+ ulen = get_len_of_range(start, stop, step);
+ if (ulen > (unsigned long)LONG_MAX) {
+ Py_DECREF(it);
+ PyErr_SetString(PyExc_OverflowError,
+ "range too large to represent as a range_iterator");
+ return NULL;
+ }
+ it->len = (long)ulen;
+ it->index = 0;
+ return (PyObject *)it;
+}
+
typedef struct {
PyObject_HEAD
PyObject *index;
@@ -943,12 +1180,26 @@ typedef struct {
PyObject *len;
} longrangeiterobject;
+typedef struct {
+ PyObject_HEAD
+ PyObject *index;
+ PyObject *start;
+ PyObject *step;
+ PyObject *len;
+} longterangeiterobject;
+
static PyObject *
longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
{
return PyNumber_Subtract(r->len, r->index);
}
+static PyObject *
+longrangeiter_len_terange(longrangeiterobject *r, PyObject *no_args)
+{
+ return PyNumber_Subtract(r->len, r->index);
+}
+
static PyObject *
longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
{
@@ -979,6 +1230,36 @@ longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
range, r->index);
}
+static PyObject *
+longrangeiter_reduce_terange(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *product, *stop=NULL;
+ PyObject *range;
+
+ /* create a range object for pickling. Must calculate the "stop" value */
+ product = PyNumber_Multiply(r->len, r->step);
+ if (product == NULL)
+ return NULL;
+ stop = PyNumber_Add(r->start, product);
+ Py_DECREF(product);
+ if (stop == NULL)
+ return NULL;
+ Py_INCREF(r->start);
+ Py_INCREF(r->step);
+ range = (PyObject*)make_range_object(&PyTeRange_Type,
+ r->start, stop, r->step);
+ if (range == NULL) {
+ Py_DECREF(r->start);
+ Py_DECREF(stop);
+ Py_DECREF(r->step);
+ return NULL;
+ }
+
+ /* return the result */
+ return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter),
+ range, r->index);
+}
+
static PyObject *
longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
{
@@ -1004,6 +1285,31 @@ longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
Py_RETURN_NONE;
}
+static PyObject *
+longrangeiter_setstate_terange(longrangeiterobject *r, PyObject *state)
+{
+ PyObject *zero = _PyLong_GetZero(); // borrowed reference
+ int cmp;
+
+ /* clip the value */
+ cmp = PyObject_RichCompareBool(state, zero, Py_LT);
+ if (cmp < 0)
+ return NULL;
+ if (cmp > 0) {
+ state = zero;
+ }
+ else {
+ cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
+ if (cmp < 0)
+ return NULL;
+ if (cmp > 0)
+ state = r->len;
+ }
+ Py_INCREF(state);
+ Py_XSETREF(r->index, state);
+ Py_RETURN_NONE;
+}
+
static PyMethodDef longrangeiter_methods[] = {
{"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
length_hint_doc},
@@ -1014,6 +1320,16 @@ static PyMethodDef longrangeiter_methods[] = {
{NULL, NULL} /* sentinel */
};
+static PyMethodDef longrangeiter_terange_methods[] = {
+ {"__length_hint__", (PyCFunction)longrangeiter_len_terange, METH_NOARGS,
+ length_hint_doc},
+ {"__reduce__", (PyCFunction)longrangeiter_reduce_terange, METH_NOARGS,
+ reduce_doc},
+ {"__setstate__", (PyCFunction)longrangeiter_setstate_terange, METH_O,
+ setstate_doc},
+ {NULL, NULL} /* sentinel */
+};
+
static void
longrangeiter_dealloc(longrangeiterobject *r)
{
@@ -1053,6 +1369,38 @@ longrangeiter_next(longrangeiterobject *r)
return result;
}
+static PyObject *
+longterangeiter_next(longrangeiterobject *r)
+{
+ PyObject *product, *new_index, *result;
+ if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
+ return NULL;
+
+ new_index = PyNumber_Add(r->index, _PyLong_GetOne());
+ if (!new_index)
+ return NULL;
+
+ int inc = 10;
+ PyObject* step = PyNumber_Add(r->step, (PyObject*)inc);
+ product = PyNumber_Multiply(r->index, step);
+
+ if (!product) {
+ Py_DECREF(new_index);
+ return NULL;
+ }
+
+ result = PyNumber_Add(r->start, product);
+ Py_DECREF(product);
+ if (result) {
+ Py_SETREF(r->index, new_index);
+ }
+ else {
+ Py_DECREF(new_index);
+ }
+
+ return result;
+}
+
PyTypeObject PyLongRangeIter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"longrange_iterator", /* tp_name */
@@ -1086,6 +1434,89 @@ PyTypeObject PyLongRangeIter_Type = {
0,
};
+PyTypeObject PyLongTeRangeIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "longterange_iterator", /* tp_name */
+ sizeof(longterangeiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)longrangeiter_dealloc, /* tp_dealloc */
+ 0, /* tp_vectorcall_offset */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_as_async */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)longterangeiter_next, /* tp_iternext */
+ longrangeiter_terange_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+terange_iter(PyObject *seq)
+{
+ rangeobject *r = (rangeobject *)seq;
+ longterangeiterobject *it;
+ long lstart, lstop, lstep;
+ PyObject *int_it;
+
+ assert(PyRange_Check(seq));
+
+ /* If all three fields and the length convert to long, use the int
+ * version */
+ lstart = PyLong_AsLong(r->start);
+ if (lstart == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ goto long_range;
+ }
+ lstop = PyLong_AsLong(r->stop);
+ if (lstop == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ goto long_range;
+ }
+ lstep = PyLong_AsLong(r->step);
+ if (lstep == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ goto long_range;
+ }
+ int_it = fast_terange_iter(lstart, lstop, lstep);
+ if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ PyErr_Clear();
+ goto long_range;
+ }
+ return (PyObject *)int_it;
+
+ long_range:
+ it = PyObject_New(longterangeiterobject, &PyLongRangeIter_Type);
+ if (it == NULL)
+ return NULL;
+
+ it->start = r->start;
+ it->step = r->step;
+ it->len = r->length;
+ it->index = _PyLong_GetZero();
+ Py_INCREF(it->start);
+ Py_INCREF(it->step);
+ Py_INCREF(it->len);
+ Py_INCREF(it->index);
+ return (PyObject *)it;
+}
+
static PyObject *
range_iter(PyObject *seq)
{
@@ -1243,3 +1674,111 @@ range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
Py_DECREF(it);
return NULL;
}
+
+static PyObject *
+terange_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
+{
+ rangeobject *range = (rangeobject*) seq;
+ longterangeiterobject *it;
+ PyObject *sum, *diff, *product;
+ long lstart, lstop, lstep, new_start, new_stop;
+ unsigned long ulen;
+
+ assert(PyRange_Check(seq));
+
+ /* reversed(range(start, stop, step)) can be expressed as
+ range(start+(n-1)*step, start-step, -step), where n is the number of
+ integers in the range.
+
+ If each of start, stop, step, -step, start-step, and the length
+ of the iterator is representable as a C long, use the int
+ version. This excludes some cases where the reversed range is
+ representable as a range_iterator, but it's good enough for
+ common cases and it makes the checks simple. */
+
+ lstart = PyLong_AsLong(range->start);
+ if (lstart == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ goto long_range;
+ }
+ lstop = PyLong_AsLong(range->stop);
+ if (lstop == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ goto long_range;
+ }
+ lstep = PyLong_AsLong(range->step);
+ if (lstep == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ goto long_range;
+ }
+ /* check for possible overflow of -lstep */
+ if (lstep == LONG_MIN)
+ goto long_range;
+
+ /* check for overflow of lstart - lstep:
+
+ for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
+ for lstep < 0, need only check whether lstart - lstep > LONG_MAX
+
+ Rearrange these inequalities as:
+
+ lstart - LONG_MIN < lstep (lstep > 0)
+ LONG_MAX - lstart < -lstep (lstep < 0)
+
+ and compute both sides as unsigned longs, to avoid the
+ possibility of undefined behaviour due to signed overflow. */
+
+ if (lstep > 0) {
+ if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
+ goto long_range;
+ }
+ else {
+ if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
+ goto long_range;
+ }
+
+ ulen = get_len_of_range(lstart, lstop, lstep);
+ if (ulen > (unsigned long)LONG_MAX)
+ goto long_range;
+
+ new_stop = lstart - lstep;
+ new_start = (long)(new_stop + ulen * lstep);
+ return fast_terange_iter(new_start, new_stop, -lstep);
+
+long_range:
+ it = PyObject_New(longterangeiterobject, &PyLongRangeIter_Type);
+ if (it == NULL)
+ return NULL;
+ it->index = it->start = it->step = NULL;
+
+ /* start + (len - 1) * step */
+ it->len = range->length;
+ Py_INCREF(it->len);
+
+ diff = PyNumber_Subtract(it->len, _PyLong_GetOne());
+ if (!diff)
+ goto create_failure;
+
+ product = PyNumber_Multiply(diff, range->step);
+ Py_DECREF(diff);
+ if (!product)
+ goto create_failure;
+
+ sum = PyNumber_Add(range->start, product);
+ Py_DECREF(product);
+ it->start = sum;
+ if (!it->start)
+ goto create_failure;
+
+ it->step = PyNumber_Negative(range->step);
+ if (!it->step)
+ goto create_failure;
+
+ it->index = _PyLong_GetZero();
+ Py_INCREF(it->index);
+ return (PyObject *)it;
+
+create_failure:
+ Py_DECREF(it);
+ return NULL;
+}
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 66c5fba..2a55e2e 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -3039,6 +3039,7 @@ _PyBuiltin_Init(PyInterpreterState *interp)
SETBUILTIN("map", &PyMap_Type);
SETBUILTIN("object", &PyBaseObject_Type);
SETBUILTIN("range", &PyRange_Type);
+ SETBUILTIN("terange", &PyTeRange_Type);
SETBUILTIN("reversed", &PyReversed_Type);
SETBUILTIN("set", &PySet_Type);
SETBUILTIN("slice", &PySlice_Type);
@ayush-1506
Copy link
Author

Inspired from geohot's fore loop in clang stream. Link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment