[Python-checkins] r60636 - in python/trunk: Lib/test/seq_tests.py Misc/NEWS Objects/tupleobject.c
raymond.hettinger
python-checkins at python.org
Thu Feb 7 01:54:21 CET 2008
Author: raymond.hettinger
Date: Thu Feb 7 01:54:20 2008
New Revision: 60636
Modified:
python/trunk/Lib/test/seq_tests.py
python/trunk/Misc/NEWS
python/trunk/Objects/tupleobject.c
Log:
Issue 2025: Add tuple.count() and tuple.index() to follow the ABC in collections.Sequence.
Modified: python/trunk/Lib/test/seq_tests.py
==============================================================================
--- python/trunk/Lib/test/seq_tests.py (original)
+++ python/trunk/Lib/test/seq_tests.py Thu Feb 7 01:54:20 2008
@@ -4,6 +4,7 @@
import unittest
from test import test_support
+import sys
# Various iterables
# This is used for checking the constructor (here and in test_deque.py)
@@ -328,3 +329,64 @@
self.assertEqual(a.__getitem__(slice(3,5)), self.type2test([]))
self.assertRaises(ValueError, a.__getitem__, slice(0, 10, 0))
self.assertRaises(TypeError, a.__getitem__, 'x')
+
+ def test_count(self):
+ a = self.type2test([0, 1, 2])*3
+ self.assertEqual(a.count(0), 3)
+ self.assertEqual(a.count(1), 3)
+ self.assertEqual(a.count(3), 0)
+
+ self.assertRaises(TypeError, a.count)
+
+ class BadExc(Exception):
+ pass
+
+ class BadCmp:
+ def __eq__(self, other):
+ if other == 2:
+ raise BadExc()
+ return False
+
+ self.assertRaises(BadExc, a.count, BadCmp())
+
+ def test_index(self):
+ u = self.type2test([0, 1])
+ self.assertEqual(u.index(0), 0)
+ self.assertEqual(u.index(1), 1)
+ self.assertRaises(ValueError, u.index, 2)
+
+ u = self.type2test([-2, -1, 0, 0, 1, 2])
+ self.assertEqual(u.count(0), 2)
+ self.assertEqual(u.index(0), 2)
+ self.assertEqual(u.index(0, 2), 2)
+ self.assertEqual(u.index(-2, -10), 0)
+ self.assertEqual(u.index(0, 3), 3)
+ self.assertEqual(u.index(0, 3, 4), 3)
+ self.assertRaises(ValueError, u.index, 2, 0, -10)
+
+ self.assertRaises(TypeError, u.index)
+
+ class BadExc(Exception):
+ pass
+
+ class BadCmp:
+ def __eq__(self, other):
+ if other == 2:
+ raise BadExc()
+ return False
+
+ a = self.type2test([0, 1, 2, 3])
+ self.assertRaises(BadExc, a.index, BadCmp())
+
+ a = self.type2test([-2, -1, 0, 0, 1, 2])
+ self.assertEqual(a.index(0), 2)
+ self.assertEqual(a.index(0, 2), 2)
+ self.assertEqual(a.index(0, -4), 2)
+ self.assertEqual(a.index(-2, -10), 0)
+ self.assertEqual(a.index(0, 3), 3)
+ self.assertEqual(a.index(0, -3), 3)
+ self.assertEqual(a.index(0, 3, 4), 3)
+ self.assertEqual(a.index(0, -3, -2), 3)
+ self.assertEqual(a.index(0, -4*sys.maxint, 4*sys.maxint), 2)
+ self.assertRaises(ValueError, a.index, 0, 4*sys.maxint,-4*sys.maxint)
+ self.assertRaises(ValueError, a.index, 2, 0, -10)
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Thu Feb 7 01:54:20 2008
@@ -25,6 +25,9 @@
- Issue #1678380: Fix a bug that identifies 0j and -0j when they appear
in the same code unit.
+- Issue #2025 : Add tuple.count() and tuple.index() methods to comply with
+ the collections.Sequence API.
+
- Patch #1970 by Antoine Pitrou: Speedup unicode whitespace and linebreak
detection
Modified: python/trunk/Objects/tupleobject.c
==============================================================================
--- python/trunk/Objects/tupleobject.c (original)
+++ python/trunk/Objects/tupleobject.c Thu Feb 7 01:54:20 2008
@@ -455,6 +455,53 @@
return (PyObject *) np;
}
+static PyObject *
+tupleindex(PyTupleObject *self, PyObject *args)
+{
+ Py_ssize_t i, start=0, stop=Py_SIZE(self);
+ PyObject *v;
+
+ if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
+ _PyEval_SliceIndex, &start,
+ _PyEval_SliceIndex, &stop))
+ return NULL;
+ if (start < 0) {
+ start += Py_SIZE(self);
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0) {
+ stop += Py_SIZE(self);
+ if (stop < 0)
+ stop = 0;
+ }
+ for (i = start; i < stop && i < Py_SIZE(self); i++) {
+ int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+ if (cmp > 0)
+ return PyLong_FromSsize_t(i);
+ else if (cmp < 0)
+ return NULL;
+ }
+ PyErr_SetString(PyExc_ValueError, "tuple.index(x): x not in list");
+ return NULL;
+}
+
+static PyObject *
+tuplecount(PyTupleObject *self, PyObject *v)
+{
+ Py_ssize_t count = 0;
+ Py_ssize_t i;
+
+ for (i = 0; i < Py_SIZE(self); i++) {
+ int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+ if (cmp > 0)
+ count++;
+ else if (cmp < 0)
+ return NULL;
+ }
+ return PyLong_FromSsize_t(count);
+}
+
static int
tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
{
@@ -661,8 +708,15 @@
}
+PyDoc_STRVAR(index_doc,
+"T.index(value, [start, [stop]]) -> integer -- return first index of value");
+PyDoc_STRVAR(count_doc,
+"T.count(value) -> integer -- return number of occurrences of value");
+
static PyMethodDef tuple_methods[] = {
{"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS},
+ {"index", (PyCFunction)tupleindex, METH_VARARGS, index_doc},
+ {"count", (PyCFunction)tuplecount, METH_O, count_doc},
{NULL, NULL} /* sentinel */
};
More information about the Python-checkins
mailing list