Facundo Batista added the comment:
Created the patch, also send a mail to python-dev to see if somebody
wants to review it before me applying it.
----------
assignee: -> facundobatista
Added file: http://bugs.python.org/file8672/string_find.patch
__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1259>
__________________________________
Index: Objects/unicodeobject.c
===================================================================
--- Objects/unicodeobject.c (revisión: 58710)
+++ Objects/unicodeobject.c (copia de trabajo)
@@ -6027,6 +6027,46 @@
return (PyObject*) u;
}
+/*
+This function is a helper for the "find" family (find, rfind, index,
+rindex), because they all have the same behaviour for the arguments.
+
+It does not touch the variables received until it knows everything
+is ok.
+*/
+
+int
+_ParseTupleFinds (PyObject *args, PyObject **substring,
+ Py_ssize_t *start, Py_ssize_t *end) {
+ PyObject *tmp_substring;
+ Py_ssize_t tmp_start = 0;
+ Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
+ PyObject *obj_start=Py_None, *obj_end=Py_None;
+
+ if (!PyArg_ParseTuple(args, "O|OO:find", &tmp_substring,
+ &obj_start, &obj_end))
+ return 0;
+
+ /* To support None in "start" and "end" arguments, meaning
+ the same as if they were not passed.
+ */
+ if (obj_start != Py_None)
+ if (!_PyEval_SliceIndex(obj_start, &tmp_start))
+ return 0;
+ if (obj_end != Py_None)
+ if (!_PyEval_SliceIndex(obj_end, &tmp_end))
+ return 0;
+
+ tmp_substring = PyUnicode_FromObject(tmp_substring);
+ if (!tmp_substring)
+ return 0;
+
+ *start = tmp_start;
+ *end = tmp_end;
+ *substring = tmp_substring;
+ return 1;
+}
+
PyDoc_STRVAR(find__doc__,
"S.find(sub [,start [,end]]) -> int\n\
\n\
@@ -6040,16 +6080,12 @@
unicode_find(PyUnicodeObject *self, PyObject *args)
{
PyObject *substring;
- Py_ssize_t start = 0;
- Py_ssize_t end = PY_SSIZE_T_MAX;
+ Py_ssize_t start;
+ Py_ssize_t end;
Py_ssize_t result;
- if (!PyArg_ParseTuple(args, "O|O&O&:find", &substring,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!_ParseTupleFinds(args, &substring, &start, &end))
return NULL;
- substring = PyUnicode_FromObject(substring);
- if (!substring)
- return NULL;
result = stringlib_find_slice(
PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
@@ -6110,15 +6146,11 @@
{
Py_ssize_t result;
PyObject *substring;
- Py_ssize_t start = 0;
- Py_ssize_t end = PY_SSIZE_T_MAX;
+ Py_ssize_t start;
+ Py_ssize_t end;
- if (!PyArg_ParseTuple(args, "O|O&O&:index", &substring,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!_ParseTupleFinds(args, &substring, &start, &end))
return NULL;
- substring = PyUnicode_FromObject(substring);
- if (!substring)
- return NULL;
result = stringlib_find_slice(
PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
@@ -6781,16 +6813,12 @@
unicode_rfind(PyUnicodeObject *self, PyObject *args)
{
PyObject *substring;
- Py_ssize_t start = 0;
- Py_ssize_t end = PY_SSIZE_T_MAX;
+ Py_ssize_t start;
+ Py_ssize_t end;
Py_ssize_t result;
- if (!PyArg_ParseTuple(args, "O|O&O&:rfind", &substring,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
- return NULL;
- substring = PyUnicode_FromObject(substring);
- if (!substring)
- return NULL;
+ if (!_ParseTupleFinds(args, &substring, &start, &end))
+ return NULL;
result = stringlib_rfind_slice(
PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
@@ -6812,16 +6840,12 @@
unicode_rindex(PyUnicodeObject *self, PyObject *args)
{
PyObject *substring;
- Py_ssize_t start = 0;
- Py_ssize_t end = PY_SSIZE_T_MAX;
+ Py_ssize_t start;
+ Py_ssize_t end;
Py_ssize_t result;
- if (!PyArg_ParseTuple(args, "O|O&O&:rindex", &substring,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
- return NULL;
- substring = PyUnicode_FromObject(substring);
- if (!substring)
- return NULL;
+ if (!_ParseTupleFinds(args, &substring, &start, &end))
+ return NULL;
result = stringlib_rfind_slice(
PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
Index: Objects/stringobject.c
===================================================================
--- Objects/stringobject.c (revisión: 58710)
+++ Objects/stringobject.c (copia de trabajo)
@@ -1879,16 +1879,28 @@
const char *sub;
Py_ssize_t sub_len;
Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
+ PyObject *obj_start=Py_None, *obj_end=Py_None;
- if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!PyArg_ParseTuple(args, "O|OO:find/rfind/index/rindex", &subobj,
+ &obj_start, &obj_end))
return -2;
+ /* To support None in "start" and "end" arguments, meaning
+ the same as if they were not passed.
+ */
+ if (obj_start != Py_None)
+ if (!_PyEval_SliceIndex(obj_start, &start))
+ return -2;
+ if (obj_end != Py_None)
+ if (!_PyEval_SliceIndex(obj_end, &end))
+ return -2;
+
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
sub_len = PyString_GET_SIZE(subobj);
}
+
#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(subobj))
+ else if (PyUnicode_Check(subobj))
return PyUnicode_Find(
(PyObject *)self, subobj, start, end, dir);
#endif
Index: Lib/test/string_tests.py
===================================================================
--- Lib/test/string_tests.py (revisión: 58710)
+++ Lib/test/string_tests.py (copia de trabajo)
@@ -159,6 +159,13 @@
self.checkequal(3, 'abc', 'find', '', 3)
self.checkequal(-1, 'abc', 'find', '', 4)
+ # to check the ability to pass None as defaults
+ self.checkequal( 2, 'rrarrrrrrrrra', 'find', 'a')
+ self.checkequal(12, 'rrarrrrrrrrra', 'find', 'a', 4)
+ self.checkequal(-1, 'rrarrrrrrrrra', 'find', 'a', 4, 6)
+ self.checkequal(12, 'rrarrrrrrrrra', 'find', 'a', 4, None)
+ self.checkequal( 2, 'rrarrrrrrrrra', 'find', 'a', None, 6)
+
self.checkraises(TypeError, 'hello', 'find')
self.checkraises(TypeError, 'hello', 'find', 42)
@@ -197,6 +204,13 @@
self.checkequal(3, 'abc', 'rfind', '', 3)
self.checkequal(-1, 'abc', 'rfind', '', 4)
+ # to check the ability to pass None as defaults
+ self.checkequal(12, 'rrarrrrrrrrra', 'rfind', 'a')
+ self.checkequal(12, 'rrarrrrrrrrra', 'rfind', 'a', 4)
+ self.checkequal(-1, 'rrarrrrrrrrra', 'rfind', 'a', 4, 6)
+ self.checkequal(12, 'rrarrrrrrrrra', 'rfind', 'a', 4, None)
+ self.checkequal( 2, 'rrarrrrrrrrra', 'rfind', 'a', None, 6)
+
self.checkraises(TypeError, 'hello', 'rfind')
self.checkraises(TypeError, 'hello', 'rfind', 42)
@@ -211,6 +225,13 @@
self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', 8)
self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', -1)
+ # to check the ability to pass None as defaults
+ self.checkequal( 2, 'rrarrrrrrrrra', 'index', 'a')
+ self.checkequal(12, 'rrarrrrrrrrra', 'index', 'a', 4)
+ self.checkraises(ValueError, 'rrarrrrrrrrra', 'index', 'a', 4, 6)
+ self.checkequal(12, 'rrarrrrrrrrra', 'index', 'a', 4, None)
+ self.checkequal( 2, 'rrarrrrrrrrra', 'index', 'a', None, 6)
+
self.checkraises(TypeError, 'hello', 'index')
self.checkraises(TypeError, 'hello', 'index', 42)
@@ -226,6 +247,13 @@
self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, 8)
self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, -1)
+ # to check the ability to pass None as defaults
+ self.checkequal(12, 'rrarrrrrrrrra', 'rindex', 'a')
+ self.checkequal(12, 'rrarrrrrrrrra', 'rindex', 'a', 4)
+ self.checkraises(ValueError, 'rrarrrrrrrrra', 'rindex', 'a', 4, 6)
+ self.checkequal(12, 'rrarrrrrrrrra', 'rindex', 'a', 4, None)
+ self.checkequal( 2, 'rrarrrrrrrrra', 'rindex', 'a', None, 6)
+
self.checkraises(TypeError, 'hello', 'rindex')
self.checkraises(TypeError, 'hello', 'rindex', 42)
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com