Index: Objects/unicodeobject.c =================================================================== --- Objects/unicodeobject.c (revision 74880) +++ Objects/unicodeobject.c (working copy) @@ -6610,13 +6610,15 @@ codecs.register_error that can handle UnicodeEncodeErrors."); static PyObject * -unicode_encode(PyUnicodeObject *self, PyObject *args) +unicode_encode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"encoding", "errors", 0}; char *encoding = NULL; char *errors = NULL; PyObject *v; - if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode", + kwlist, &encoding, &errors)) return NULL; v = PyUnicode_AsEncodedObject((PyObject *)self, encoding, errors); if (v == NULL) @@ -6646,13 +6648,15 @@ able to handle UnicodeDecodeErrors."); static PyObject * -unicode_decode(PyUnicodeObject *self, PyObject *args) +unicode_decode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"encoding", "errors", 0}; char *encoding = NULL; char *errors = NULL; PyObject *v; - if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", + kwlist, &encoding, &errors)) return NULL; v = PyUnicode_AsDecodedObject((PyObject *)self, encoding, errors); if (v == NULL) @@ -8054,7 +8058,7 @@ /* Order is according to common usage: often used methods should appear first, since lookup is done sequentially. */ - {"encode", (PyCFunction) unicode_encode, METH_VARARGS, encode__doc__}, + {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__}, {"replace", (PyCFunction) unicode_replace, METH_VARARGS, replace__doc__}, {"split", (PyCFunction) unicode_split, METH_VARARGS, split__doc__}, {"rsplit", (PyCFunction) unicode_rsplit, METH_VARARGS, rsplit__doc__}, @@ -8070,7 +8074,7 @@ {"ljust", (PyCFunction) unicode_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction) unicode_lower, METH_NOARGS, lower__doc__}, {"lstrip", (PyCFunction) unicode_lstrip, METH_VARARGS, lstrip__doc__}, - {"decode", (PyCFunction) unicode_decode, METH_VARARGS, decode__doc__}, + {"decode", (PyCFunction) unicode_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__}, /* {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS, maketrans__doc__}, */ {"rfind", (PyCFunction) unicode_rfind, METH_VARARGS, rfind__doc__}, {"rindex", (PyCFunction) unicode_rindex, METH_VARARGS, rindex__doc__}, Index: Objects/stringobject.c =================================================================== --- Objects/stringobject.c (revision 74880) +++ Objects/stringobject.c (working copy) @@ -3332,13 +3332,15 @@ codecs.register_error that is able to handle UnicodeEncodeErrors."); static PyObject * -string_encode(PyStringObject *self, PyObject *args) +string_encode(PyStringObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"encoding", "errors", 0}; char *encoding = NULL; char *errors = NULL; PyObject *v; - if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode", + kwlist, &encoding, &errors)) return NULL; v = PyString_AsEncodedObject((PyObject *)self, encoding, errors); if (v == NULL) @@ -3369,13 +3371,15 @@ able to handle UnicodeDecodeErrors."); static PyObject * -string_decode(PyStringObject *self, PyObject *args) +string_decode(PyStringObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"encoding", "errors", 0}; char *encoding = NULL; char *errors = NULL; PyObject *v; - if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", + kwlist, &encoding, &errors)) return NULL; v = PyString_AsDecodedObject((PyObject *)self, encoding, errors); if (v == NULL) @@ -4053,8 +4057,8 @@ {"__format__", (PyCFunction) string__format__, METH_VARARGS, p_format__doc__}, {"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS}, {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS}, - {"encode", (PyCFunction)string_encode, METH_VARARGS, encode__doc__}, - {"decode", (PyCFunction)string_decode, METH_VARARGS, decode__doc__}, + {"encode", (PyCFunction)string_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__}, + {"decode", (PyCFunction)string_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__}, {"expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS, expandtabs__doc__}, {"splitlines", (PyCFunction)string_splitlines, METH_VARARGS, Index: Doc/library/stdtypes.rst =================================================================== --- Doc/library/stdtypes.rst (revision 74880) +++ Doc/library/stdtypes.rst (working copy) @@ -815,8 +815,8 @@ .. index:: pair: string; methods -Below are listed the string methods which both 8-bit strings and Unicode objects -support. Note that none of these methods take keyword arguments. +Below are listed the string methods which both 8-bit strings and +Unicode objects support. In addition, Python's strings support the sequence type methods described in the :ref:`typesseq` section. To output formatted strings @@ -861,6 +861,8 @@ .. versionchanged:: 2.3 Support for other error handling schemes added. + .. versionchanged:: 2.7 + Support for keyword arguments added. .. method:: str.encode([encoding[,errors]]) @@ -879,6 +881,8 @@ Support for ``'xmlcharrefreplace'`` and ``'backslashreplace'`` and other error handling schemes added. + .. versionchanged:: 2.7 + Support for keyword arguments added. .. method:: str.endswith(suffix[, start[, end]]) Index: Lib/test/test_unicode.py =================================================================== --- Lib/test/test_unicode.py (revision 74880) +++ Lib/test/test_unicode.py (working copy) @@ -593,12 +593,28 @@ self.assertRaises(UnicodeError, u'Andr\202 x'.encode, 'ascii','strict') self.assertEqual(u'Andr\202 x'.encode('ascii','ignore'), "Andr x") self.assertEqual(u'Andr\202 x'.encode('ascii','replace'), "Andr? x") + self.assertEqual(u'Andr\202 x'.encode('ascii', 'replace'), + u'Andr\202 x'.encode('ascii', errors='replace')) + self.assertEqual(u'Andr\202 x'.encode('ascii', 'ignore'), + u'Andr\202 x'.encode(encoding='ascii', errors='ignore')) + self.assertEqual('abcde'.encode('ascii', 'replace'), + 'abcde'.encode('ascii', errors='replace')) + self.assertEqual('abcde'.encode('ascii', 'ignore'), + 'abcde'.encode(encoding='ascii', errors='ignore')) # Error handling (decoding) self.assertRaises(UnicodeError, unicode, 'Andr\202 x', 'ascii') self.assertRaises(UnicodeError, unicode, 'Andr\202 x', 'ascii','strict') self.assertEqual(unicode('Andr\202 x','ascii','ignore'), u"Andr x") self.assertEqual(unicode('Andr\202 x','ascii','replace'), u'Andr\uFFFD x') + self.assertEqual('Andr\202 x'.decode('ascii', 'ignore'), + 'Andr\202 x'.decode('ascii', errors='ignore')) + self.assertEqual('Andr\202 x'.decode('ascii', 'replace'), + 'Andr\202 x'.decode(encoding='ascii', errors='replace')) + self.assertEqual(u'abcde'.decode('ascii', 'ignore'), + u'abcde'.decode('ascii', errors='ignore')) + self.assertEqual(u'abcde'.decode('ascii', 'replace'), + u'abcde'.decode(encoding='ascii', errors='replace')) # Error handling (unknown character names) self.assertEqual("\\N{foo}xx".decode("unicode-escape", "ignore"), u"xx")