@@ -7793,68 +7793,124 @@ unicode_swapcase(PyUnicodeObject *self)
77937793 return fixup (self , fixswapcase );
77947794}
77957795
7796- PyDoc_STRVAR (translate__doc__ ,
7797- "S.translate(table ) -> unicode \n\
7796+ PyDoc_STRVAR (maketrans__doc__ ,
7797+ "str.maketrans(x[, y[, z]] ) -> dict (static method) \n\
77987798\n\
7799- Return a copy of the string S, where all characters have been mapped\n\
7800- through the given translation table, which must be a mapping of\n\
7801- Unicode ordinals to Unicode ordinals, Unicode strings or None.\n\
7802- Unmapped characters are left untouched. Characters mapped to None\n\
7803- are deleted." );
7799+ Return a translation table usable for str.translate().\n\
7800+ If there is only one argument, it must be a dictionary mapping Unicode\n\
7801+ ordinals (integers) or characters to Unicode ordinals, strings or None.\n\
7802+ Character keys will then be converted to ordinals.\n\
7803+ If there are two arguments, they must be strings of equal length, and\n\
7804+ in the resulting dictionary, each character in x will be mapped to the\n\
7805+ character at the same position in y. If there is a third argument, it\n\
7806+ must be a string, whose characters will be mapped to None in the result." );
78047807
78057808static PyObject *
7806- unicode_translate (PyUnicodeObject * self , PyObject * table )
7809+ unicode_maketrans (PyUnicodeObject * null , PyObject * args )
78077810{
7808- PyObject * newtable = NULL ;
7811+ PyObject * x , * y = NULL , * z = NULL ;
7812+ PyObject * new = NULL , * key , * value ;
78097813 Py_ssize_t i = 0 ;
7810- PyObject * key , * value , * result ;
7811-
7812- if (!PyDict_Check (table )) {
7813- PyErr_SetString (PyExc_TypeError , "translate argument must be a dict" );
7814+ int res ;
7815+
7816+ if (!PyArg_ParseTuple (args , "O|UU:maketrans" , & x , & y , & z ))
78147817 return NULL ;
7815- }
7816- /* fixup the table -- allow size-1 string keys instead of only int keys */
7817- newtable = PyDict_Copy (table );
7818- if (!newtable ) return NULL ;
7819- while (PyDict_Next (table , & i , & key , & value )) {
7820- if (PyUnicode_Check (key )) {
7821- /* convert string keys to integer keys */
7822- PyObject * newkey ;
7823- int res ;
7824- if (PyUnicode_GET_SIZE (key ) != 1 ) {
7825- PyErr_SetString (PyExc_ValueError , "string items in translate "
7826- "table must be 1 element long" );
7827- goto err ;
7828- }
7829- newkey = PyInt_FromLong (PyUnicode_AS_UNICODE (key )[0 ]);
7830- if (!newkey )
7818+ new = PyDict_New ();
7819+ if (!new )
7820+ return NULL ;
7821+ if (y != NULL ) {
7822+ /* x must be a string too, of equal length */
7823+ Py_ssize_t ylen = PyUnicode_GET_SIZE (y );
7824+ if (!PyUnicode_Check (x )) {
7825+ PyErr_SetString (PyExc_TypeError , "first maketrans argument must "
7826+ "be a string if there is a second argument" );
7827+ goto err ;
7828+ }
7829+ if (PyUnicode_GET_SIZE (x ) != ylen ) {
7830+ PyErr_SetString (PyExc_ValueError , "the first two maketrans "
7831+ "arguments must have equal length" );
7832+ goto err ;
7833+ }
7834+ /* create entries for translating chars in x to those in y */
7835+ for (i = 0 ; i < PyUnicode_GET_SIZE (x ); i ++ ) {
7836+ key = PyInt_FromLong (PyUnicode_AS_UNICODE (x )[i ]);
7837+ value = PyInt_FromLong (PyUnicode_AS_UNICODE (y )[i ]);
7838+ if (!key || !value )
78317839 goto err ;
7832- res = PyDict_SetItem (newtable , newkey , value );
7833- Py_DECREF (newkey );
7840+ res = PyDict_SetItem (new , key , value );
7841+ Py_DECREF (key );
7842+ Py_DECREF (value );
78347843 if (res < 0 )
78357844 goto err ;
7836- } else if (PyInt_Check (key )) {
7837- /* just keep integer keys */
7838- if (PyDict_SetItem (newtable , key , value ) < 0 )
7839- goto err ;
7840- } else {
7841- PyErr_SetString (PyExc_TypeError , "items in translate table must be "
7842- "strings or integers" );
7845+ }
7846+ /* create entries for deleting chars in z */
7847+ if (z != NULL ) {
7848+ for (i = 0 ; i < PyUnicode_GET_SIZE (z ); i ++ ) {
7849+ key = PyInt_FromLong (PyUnicode_AS_UNICODE (z )[i ]);
7850+ if (!key )
7851+ goto err ;
7852+ res = PyDict_SetItem (new , key , Py_None );
7853+ Py_DECREF (key );
7854+ if (res < 0 )
7855+ goto err ;
7856+ }
7857+ }
7858+ } else {
7859+ /* x must be a dict */
7860+ if (!PyDict_Check (x )) {
7861+ PyErr_SetString (PyExc_TypeError , "if you give only one argument "
7862+ "to maketrans it must be a dict" );
78437863 goto err ;
78447864 }
7865+ /* copy entries into the new dict, converting string keys to int keys */
7866+ while (PyDict_Next (x , & i , & key , & value )) {
7867+ if (PyUnicode_Check (key )) {
7868+ /* convert string keys to integer keys */
7869+ PyObject * newkey ;
7870+ if (PyUnicode_GET_SIZE (key ) != 1 ) {
7871+ PyErr_SetString (PyExc_ValueError , "string keys in translate "
7872+ "table must be of length 1" );
7873+ goto err ;
7874+ }
7875+ newkey = PyInt_FromLong (PyUnicode_AS_UNICODE (key )[0 ]);
7876+ if (!newkey )
7877+ goto err ;
7878+ res = PyDict_SetItem (new , newkey , value );
7879+ Py_DECREF (newkey );
7880+ if (res < 0 )
7881+ goto err ;
7882+ } else if (PyInt_Check (key )) {
7883+ /* just keep integer keys */
7884+ if (PyDict_SetItem (new , key , value ) < 0 )
7885+ goto err ;
7886+ } else {
7887+ PyErr_SetString (PyExc_TypeError , "keys in translate table must "
7888+ "be strings or integers" );
7889+ goto err ;
7890+ }
7891+ }
78457892 }
7846-
7847- result = PyUnicode_TranslateCharmap (self -> str ,
7848- self -> length ,
7849- newtable ,
7850- "ignore" );
7851- Py_DECREF (newtable );
7852- return result ;
7893+ return new ;
78537894 err :
7854- Py_DECREF (newtable );
7895+ Py_DECREF (new );
78557896 return NULL ;
78567897}
78577898
7899+ PyDoc_STRVAR (translate__doc__ ,
7900+ "S.translate(table) -> unicode\n\
7901+ \n\
7902+ Return a copy of the string S, where all characters have been mapped\n\
7903+ through the given translation table, which must be a mapping of\n\
7904+ Unicode ordinals to Unicode ordinals, Unicode strings or None.\n\
7905+ Unmapped characters are left untouched. Characters mapped to None\n\
7906+ are deleted." );
7907+
7908+ static PyObject *
7909+ unicode_translate (PyUnicodeObject * self , PyObject * table )
7910+ {
7911+ return PyUnicode_TranslateCharmap (self -> str , self -> length , table , "ignore" );
7912+ }
7913+
78587914PyDoc_STRVAR (upper__doc__ ,
78597915"S.upper() -> unicode\n\
78607916\n\
@@ -8076,6 +8132,8 @@ static PyMethodDef unicode_methods[] = {
80768132 {"__format__" , (PyCFunction ) unicode_unicode__format__ , METH_VARARGS , p_format__doc__ },
80778133 {"_formatter_field_name_split" , (PyCFunction ) formatter_field_name_split , METH_NOARGS },
80788134 {"_formatter_parser" , (PyCFunction ) formatter_parser , METH_NOARGS },
8135+ {"maketrans" , (PyCFunction ) unicode_maketrans ,
8136+ METH_VARARGS | METH_STATIC , maketrans__doc__ },
80798137#if 0
80808138 {"capwords" , (PyCFunction ) unicode_capwords , METH_NOARGS , capwords__doc__ },
80818139#endif
0 commit comments