SF 1193128: Let str.translate(None) be an identity transformation

This commit is contained in:
Raymond Hettinger 2007-04-12 04:10:00 +00:00
parent 5176180610
commit 4db5fe970c
6 changed files with 33 additions and 10 deletions

View File

@ -878,6 +878,13 @@ must be a string of length 256.
You can use the \function{maketrans()} helper function in the
\refmodule{string} module to create a translation table.
For string objects, set the \var{table} argument to \code{None}
for translations that only delete characters:
\begin{verbatim}
>>> 'read this short text'.translate(None, 'aeiou')
'rd ths shrt txt'
\end{verbatim}
\versionadded[Support for a \code{None} \var{table} argument]{2.6}
For Unicode objects, the \method{translate()} method does not
accept the optional \var{deletechars} argument. Instead, it

View File

@ -419,7 +419,8 @@ parameter cannot be passed in earlier 2.2 versions]{2.2.3}
Delete all characters from \var{s} that are in \var{deletechars} (if
present), and then translate the characters using \var{table}, which
must be a 256-character string giving the translation for each
character value, indexed by its ordinal.
character value, indexed by its ordinal. If \var{table} is \code{None},
then only the character deletion step is performed.
\end{funcdesc}
\begin{funcdesc}{upper}{s}

View File

@ -487,7 +487,7 @@ def translate(s, table, deletions=""):
deletions argument is not allowed for Unicode strings.
"""
if deletions:
if deletions or table is None:
return s.translate(table, deletions)
else:
# Add s[:0] so that if s is Unicode and table is an 8-bit string,

View File

@ -1096,6 +1096,9 @@ class MixinStrStringUserStringTest:
self.checkequal('Abc', 'abc', 'translate', table)
self.checkequal('xyz', 'xyz', 'translate', table)
self.checkequal('yz', 'xyz', 'translate', table, 'x')
self.checkequal('yx', 'zyzzx', 'translate', None, 'z')
self.checkequal('zyzzx', 'zyzzx', 'translate', None, '')
self.checkequal('zyzzx', 'zyzzx', 'translate', None)
self.checkraises(ValueError, 'xyz', 'translate', 'too short', 'strip')
self.checkraises(ValueError, 'xyz', 'translate', 'too short')

View File

@ -14,6 +14,10 @@ Core and builtins
- Request #1191699: Slices can now be pickled.
- Request #1193128: str.translate() now allows a None argument for
translations that only remove characters without re-mapping the
remaining characters.
- Patch #1682205: a TypeError while unpacking an iterable is no longer
masked by a generic one with the message "unpack non-sequence".

View File

@ -2344,10 +2344,10 @@ static PyObject *
string_translate(PyStringObject *self, PyObject *args)
{
register char *input, *output;
register const char *table;
const char *table;
register Py_ssize_t i, c, changed = 0;
PyObject *input_obj = (PyObject*)self;
const char *table1, *output_start, *del_table=NULL;
const char *output_start, *del_table=NULL;
Py_ssize_t inlen, tablen, dellen = 0;
PyObject *result;
int trans_table[256];
@ -2358,9 +2358,13 @@ string_translate(PyStringObject *self, PyObject *args)
return NULL;
if (PyString_Check(tableobj)) {
table1 = PyString_AS_STRING(tableobj);
table = PyString_AS_STRING(tableobj);
tablen = PyString_GET_SIZE(tableobj);
}
else if (tableobj == Py_None) {
table = NULL;
tablen = 256;
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(tableobj)) {
/* Unicode .translate() does not support the deletechars
@ -2374,7 +2378,7 @@ string_translate(PyStringObject *self, PyObject *args)
return PyUnicode_Translate((PyObject *)self, tableobj, NULL);
}
#endif
else if (PyObject_AsCharBuffer(tableobj, &table1, &tablen))
else if (PyObject_AsCharBuffer(tableobj, &table, &tablen))
return NULL;
if (tablen != 256) {
@ -2403,7 +2407,6 @@ string_translate(PyStringObject *self, PyObject *args)
dellen = 0;
}
table = table1;
inlen = PyString_GET_SIZE(input_obj);
result = PyString_FromStringAndSize((char *)NULL, inlen);
if (result == NULL)
@ -2411,7 +2414,7 @@ string_translate(PyStringObject *self, PyObject *args)
output_start = output = PyString_AsString(result);
input = PyString_AS_STRING(input_obj);
if (dellen == 0) {
if (dellen == 0 && table != NULL) {
/* If no deletions are required, use faster code */
for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++);
@ -2425,8 +2428,13 @@ string_translate(PyStringObject *self, PyObject *args)
return input_obj;
}
for (i = 0; i < 256; i++)
trans_table[i] = Py_CHARMASK(table[i]);
if (table == NULL) {
for (i = 0; i < 256; i++)
trans_table[i] = Py_CHARMASK(i);
} else {
for (i = 0; i < 256; i++)
trans_table[i] = Py_CHARMASK(table[i]);
}
for (i = 0; i < dellen; i++)
trans_table[(int) Py_CHARMASK(del_table[i])] = -1;