summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/libstdtypes.tex7
-rw-r--r--Doc/lib/libstring.tex3
-rw-r--r--Lib/string.py2
-rw-r--r--Lib/test/string_tests.py3
-rw-r--r--Misc/NEWS4
-rw-r--r--Objects/stringobject.c24
6 files changed, 33 insertions, 10 deletions
diff --git a/Doc/lib/libstdtypes.tex b/Doc/lib/libstdtypes.tex
index 0ad2ebc..c9fd272 100644
--- a/Doc/lib/libstdtypes.tex
+++ b/Doc/lib/libstdtypes.tex
@@ -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
diff --git a/Doc/lib/libstring.tex b/Doc/lib/libstring.tex
index bc1649f..055ac0c 100644
--- a/Doc/lib/libstring.tex
+++ b/Doc/lib/libstring.tex
@@ -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}
diff --git a/Lib/string.py b/Lib/string.py
index 921bd8b..9e3cc41 100644
--- a/Lib/string.py
+++ b/Lib/string.py
@@ -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,
diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py
index 1aa68de..16161f3 100644
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -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')
diff --git a/Misc/NEWS b/Misc/NEWS
index 96b8b1d..4370030 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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".
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 64be0de..63e1381 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -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;