]> granicus.if.org Git - python/commitdiff
SF 1193128: Let str.translate(None) be an identity transformation
authorRaymond Hettinger <python@rcn.com>
Thu, 12 Apr 2007 04:10:00 +0000 (04:10 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 12 Apr 2007 04:10:00 +0000 (04:10 +0000)
Doc/lib/libstdtypes.tex
Doc/lib/libstring.tex
Lib/string.py
Lib/test/string_tests.py
Misc/NEWS
Objects/stringobject.c

index 0ad2ebcca3203b56a73f6ab6d4441ef65a10d091..c9fd2726b07d4cad77e2b817687cfc32263106e0 100644 (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
index bc1649fdbfc2b1ee3c234079be2e82d0c72546f1..055ac0cf1b9288c7376c269ab31957d35c20e0e2 100644 (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}
index 921bd8b1d014ee3d845927db2352bb969caca2ac..9e3cc418ef172eb177ce97ef41bff5c012e8ad7d 100644 (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,
index 1aa68dedd0d88daa05da5615d3d3b824b793e392..16161f3ff46930b29eee6fb3c8e62939ebc86c5f 100644 (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')
 
index 96b8b1d8cbec1d5f26ede3e36182a1bd6e424487..4370030c66c66f74f0b4023a9c7efc249533728d 100644 (file)
--- 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".
 
index 64be0de19999f9dd0a736bc13abbaf10a7974f48..63e138158b44042e708661cff3666f8503d54bfc 100644 (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;