Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8afd757

Browse files
committed
Patch #636005: Filter unicode into unicode.
1 parent fc03a94 commit 8afd757

3 files changed

Lines changed: 70 additions & 0 deletions

File tree

Lib/test/test_builtin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,12 @@ class badstr(str):
365365
def __getitem__(self, index):
366366
raise ValueError
367367
self.assertRaises(ValueError, filter, lambda x: x >="3", badstr("1234"))
368+
if have_unicode:
369+
# test biltinmodule.c::filterstring()
370+
self.assertEqual(filter(None, unicode("12")), unicode("12"))
371+
self.assertEqual(filter(lambda x: x>="3", unicode("1234")), unicode("34"))
372+
self.assertRaises(TypeError, filter, 42, unicode("12"))
373+
self.assertRaises(ValueError, filter, lambda x: x >="3", badstr(unicode("1234")))
368374

369375
def test_float(self):
370376
self.assertEqual(float(3.14), 3.14)

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ What's New in Python 2.3 alpha 2?
1212
Core and builtins
1313
-----------------
1414

15+
- filter returns now Unicode results for Unicode arguments.
16+
1517
- raw_input can now return Unicode objects.
1618

1719
- List objects' sort() method now accepts None as the comparison function.

Python/bltinmodule.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ const char *Py_FileSystemDefaultEncoding = NULL; /* use default */
2424

2525
/* Forward */
2626
static PyObject *filterstring(PyObject *, PyObject *);
27+
#ifdef Py_USING_UNICODE
28+
static PyObject *filterunicode(PyObject *, PyObject *);
29+
#endif
2730
static PyObject *filtertuple (PyObject *, PyObject *);
2831

2932
static PyObject *
@@ -132,6 +135,10 @@ builtin_filter(PyObject *self, PyObject *args)
132135
/* Strings and tuples return a result of the same type. */
133136
if (PyString_Check(seq))
134137
return filterstring(func, seq);
138+
#ifdef Py_USING_UNICODE
139+
if (PyUnicode_Check(seq))
140+
return filterunicode(func, seq);
141+
#endif
135142
if (PyTuple_Check(seq))
136143
return filtertuple(func, seq);
137144

@@ -1926,3 +1933,58 @@ filterstring(PyObject *func, PyObject *strobj)
19261933
Py_DECREF(result);
19271934
return NULL;
19281935
}
1936+
1937+
#ifdef Py_USING_UNICODE
1938+
/* Helper for filter(): filter a Unicode object through a function */
1939+
1940+
static PyObject *
1941+
filterunicode(PyObject *func, PyObject *strobj)
1942+
{
1943+
PyObject *result;
1944+
register int i, j;
1945+
int len = PyUnicode_GetSize(strobj);
1946+
1947+
if (func == Py_None) {
1948+
/* No character is ever false -- share input string */
1949+
Py_INCREF(strobj);
1950+
return strobj;
1951+
}
1952+
if ((result = PyUnicode_FromUnicode(NULL, len)) == NULL)
1953+
return NULL;
1954+
1955+
for (i = j = 0; i < len; ++i) {
1956+
PyObject *item, *arg, *good;
1957+
int ok;
1958+
1959+
item = (*strobj->ob_type->tp_as_sequence->sq_item)(strobj, i);
1960+
if (item == NULL)
1961+
goto Fail_1;
1962+
arg = Py_BuildValue("(O)", item);
1963+
if (arg == NULL) {
1964+
Py_DECREF(item);
1965+
goto Fail_1;
1966+
}
1967+
good = PyEval_CallObject(func, arg);
1968+
Py_DECREF(arg);
1969+
if (good == NULL) {
1970+
Py_DECREF(item);
1971+
goto Fail_1;
1972+
}
1973+
ok = PyObject_IsTrue(good);
1974+
Py_DECREF(good);
1975+
if (ok)
1976+
PyUnicode_AS_UNICODE((PyStringObject *)result)[j++] =
1977+
PyUnicode_AS_UNICODE((PyStringObject *)item)[0];
1978+
Py_DECREF(item);
1979+
}
1980+
1981+
if (j < len)
1982+
PyUnicode_Resize(&result, j);
1983+
1984+
return result;
1985+
1986+
Fail_1:
1987+
Py_DECREF(result);
1988+
return NULL;
1989+
}
1990+
#endif

0 commit comments

Comments
 (0)