Kaydet (Commit) 4db5fe97 authored tarafından Raymond Hettinger's avatar Raymond Hettinger

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

üst 51761806
...@@ -878,6 +878,13 @@ must be a string of length 256. ...@@ -878,6 +878,13 @@ must be a string of length 256.
You can use the \function{maketrans()} helper function in the You can use the \function{maketrans()} helper function in the
\refmodule{string} module to create a translation table. \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 For Unicode objects, the \method{translate()} method does not
accept the optional \var{deletechars} argument. Instead, it accept the optional \var{deletechars} argument. Instead, it
......
...@@ -419,7 +419,8 @@ parameter cannot be passed in earlier 2.2 versions]{2.2.3} ...@@ -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 Delete all characters from \var{s} that are in \var{deletechars} (if
present), and then translate the characters using \var{table}, which present), and then translate the characters using \var{table}, which
must be a 256-character string giving the translation for each 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} \end{funcdesc}
\begin{funcdesc}{upper}{s} \begin{funcdesc}{upper}{s}
......
...@@ -487,7 +487,7 @@ def translate(s, table, deletions=""): ...@@ -487,7 +487,7 @@ def translate(s, table, deletions=""):
deletions argument is not allowed for Unicode strings. deletions argument is not allowed for Unicode strings.
""" """
if deletions: if deletions or table is None:
return s.translate(table, deletions) return s.translate(table, deletions)
else: else:
# Add s[:0] so that if s is Unicode and table is an 8-bit string, # Add s[:0] so that if s is Unicode and table is an 8-bit string,
......
...@@ -1096,6 +1096,9 @@ class MixinStrStringUserStringTest: ...@@ -1096,6 +1096,9 @@ class MixinStrStringUserStringTest:
self.checkequal('Abc', 'abc', 'translate', table) self.checkequal('Abc', 'abc', 'translate', table)
self.checkequal('xyz', 'xyz', 'translate', table) self.checkequal('xyz', 'xyz', 'translate', table)
self.checkequal('yz', 'xyz', 'translate', table, 'x') 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', 'strip')
self.checkraises(ValueError, 'xyz', 'translate', 'too short') self.checkraises(ValueError, 'xyz', 'translate', 'too short')
......
...@@ -14,6 +14,10 @@ Core and builtins ...@@ -14,6 +14,10 @@ Core and builtins
- Request #1191699: Slices can now be pickled. - 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 - Patch #1682205: a TypeError while unpacking an iterable is no longer
masked by a generic one with the message "unpack non-sequence". masked by a generic one with the message "unpack non-sequence".
......
...@@ -2344,10 +2344,10 @@ static PyObject * ...@@ -2344,10 +2344,10 @@ static PyObject *
string_translate(PyStringObject *self, PyObject *args) string_translate(PyStringObject *self, PyObject *args)
{ {
register char *input, *output; register char *input, *output;
register const char *table; const char *table;
register Py_ssize_t i, c, changed = 0; register Py_ssize_t i, c, changed = 0;
PyObject *input_obj = (PyObject*)self; 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; Py_ssize_t inlen, tablen, dellen = 0;
PyObject *result; PyObject *result;
int trans_table[256]; int trans_table[256];
...@@ -2358,9 +2358,13 @@ string_translate(PyStringObject *self, PyObject *args) ...@@ -2358,9 +2358,13 @@ string_translate(PyStringObject *self, PyObject *args)
return NULL; return NULL;
if (PyString_Check(tableobj)) { if (PyString_Check(tableobj)) {
table1 = PyString_AS_STRING(tableobj); table = PyString_AS_STRING(tableobj);
tablen = PyString_GET_SIZE(tableobj); tablen = PyString_GET_SIZE(tableobj);
} }
else if (tableobj == Py_None) {
table = NULL;
tablen = 256;
}
#ifdef Py_USING_UNICODE #ifdef Py_USING_UNICODE
else if (PyUnicode_Check(tableobj)) { else if (PyUnicode_Check(tableobj)) {
/* Unicode .translate() does not support the deletechars /* Unicode .translate() does not support the deletechars
...@@ -2374,7 +2378,7 @@ string_translate(PyStringObject *self, PyObject *args) ...@@ -2374,7 +2378,7 @@ string_translate(PyStringObject *self, PyObject *args)
return PyUnicode_Translate((PyObject *)self, tableobj, NULL); return PyUnicode_Translate((PyObject *)self, tableobj, NULL);
} }
#endif #endif
else if (PyObject_AsCharBuffer(tableobj, &table1, &tablen)) else if (PyObject_AsCharBuffer(tableobj, &table, &tablen))
return NULL; return NULL;
if (tablen != 256) { if (tablen != 256) {
...@@ -2403,7 +2407,6 @@ string_translate(PyStringObject *self, PyObject *args) ...@@ -2403,7 +2407,6 @@ string_translate(PyStringObject *self, PyObject *args)
dellen = 0; dellen = 0;
} }
table = table1;
inlen = PyString_GET_SIZE(input_obj); inlen = PyString_GET_SIZE(input_obj);
result = PyString_FromStringAndSize((char *)NULL, inlen); result = PyString_FromStringAndSize((char *)NULL, inlen);
if (result == NULL) if (result == NULL)
...@@ -2411,7 +2414,7 @@ string_translate(PyStringObject *self, PyObject *args) ...@@ -2411,7 +2414,7 @@ string_translate(PyStringObject *self, PyObject *args)
output_start = output = PyString_AsString(result); output_start = output = PyString_AsString(result);
input = PyString_AS_STRING(input_obj); input = PyString_AS_STRING(input_obj);
if (dellen == 0) { if (dellen == 0 && table != NULL) {
/* If no deletions are required, use faster code */ /* If no deletions are required, use faster code */
for (i = inlen; --i >= 0; ) { for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++); c = Py_CHARMASK(*input++);
...@@ -2425,8 +2428,13 @@ string_translate(PyStringObject *self, PyObject *args) ...@@ -2425,8 +2428,13 @@ string_translate(PyStringObject *self, PyObject *args)
return input_obj; return input_obj;
} }
for (i = 0; i < 256; i++) if (table == NULL) {
trans_table[i] = Py_CHARMASK(table[i]); 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++) for (i = 0; i < dellen; i++)
trans_table[(int) Py_CHARMASK(del_table[i])] = -1; trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment