[Python-checkins] r71521 - in python/branches/py3k: Doc/library/stdtypes.rst Doc/library/string.rst Include/bytes_methods.h Lib/string.py Lib/test/test_bigmem.py Lib/test/test_bytes.py Lib/test/test_string.py Misc/NEWS Objects/bytearrayobject.c Objects/bytes_methods.c Objects/bytesobject.c

georg.brandl python-checkins at python.org
Sun Apr 12 17:51:51 CEST 2009


Author: georg.brandl
Date: Sun Apr 12 17:51:51 2009
New Revision: 71521

Log:
Add bytes/bytearray.maketrans() to mirror str.maketrans(), and deprecate
string.maketrans() which actually works on bytes.  (Also closes #5675.)



Modified:
   python/branches/py3k/Doc/library/stdtypes.rst
   python/branches/py3k/Doc/library/string.rst
   python/branches/py3k/Include/bytes_methods.h
   python/branches/py3k/Lib/string.py
   python/branches/py3k/Lib/test/test_bigmem.py
   python/branches/py3k/Lib/test/test_bytes.py
   python/branches/py3k/Lib/test/test_string.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/bytearrayobject.c
   python/branches/py3k/Objects/bytes_methods.c
   python/branches/py3k/Objects/bytesobject.c

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Sun Apr 12 17:51:51 2009
@@ -479,7 +479,7 @@
    exponent.
 
 
-.. method:: float.fromhex(s)
+.. classmethod:: float.fromhex(s)
 
    Class method to return the float represented by a hexadecimal
    string *s*.  The string *s* may have leading and trailing
@@ -967,7 +967,7 @@
       'example.com'
 
 
-.. method:: str.maketrans(x[, y[, z]])
+.. staticmethod:: str.maketrans(x[, y[, z]])
 
    This static method returns a translation table usable for :meth:`str.translate`.
 
@@ -1514,8 +1514,8 @@
 
 The bytes and bytearray types have an additional class method:
 
-.. method:: bytes.fromhex(string)
-            bytearray.fromhex(string)
+.. classmethod:: bytes.fromhex(string)
+                 bytearray.fromhex(string)
 
    This :class:`bytes` class method returns a bytes or bytearray object,
    decoding the given string object.  The string must contain two hexadecimal
@@ -1524,7 +1524,9 @@
    >>> bytes.fromhex('f0 f1f2  ')
    b'\xf0\xf1\xf2'
 
-The translate method differs in semantics from the version available on strings:
+
+The maketrans and translate methods differ in semantics from the versions
+available on strings:
 
 .. method:: bytes.translate(table[, delete])
 
@@ -1533,8 +1535,7 @@
    mapped through the given translation table, which must be a bytes object of
    length 256.
 
-   You can use the :func:`string.maketrans` helper function to create a
-   translation table.
+   You can use the :func:`bytes.maketrans` method to create a translation table.
 
    Set the *table* argument to ``None`` for translations that only delete
    characters::
@@ -1543,6 +1544,16 @@
       b'rd ths shrt txt'
 
 
+.. staticmethod:: bytes.maketrans(from, to)
+
+   This static method returns a translation table usable for
+   :meth:`bytes.translate` that will map each character in *from* into the
+   character at the same position in *to*; *from* and *to* must be bytes objects
+   and have the same length.
+
+   .. versionadded:: 3.1
+
+
 .. _types-set:
 
 Set Types --- :class:`set`, :class:`frozenset`
@@ -1847,7 +1858,7 @@
 
       Return a shallow copy of the dictionary.
 
-   .. method:: fromkeys(seq[, value])
+   .. classmethod:: fromkeys(seq[, value])
 
       Create a new dictionary with keys from *seq* and values set to *value*.
 

Modified: python/branches/py3k/Doc/library/string.rst
==============================================================================
--- python/branches/py3k/Doc/library/string.rst	(original)
+++ python/branches/py3k/Doc/library/string.rst	Sun Apr 12 17:51:51 2009
@@ -548,13 +548,9 @@
   delimiter), and it should appear last in the regular expression.
 
 
-String functions
+Helper functions
 ----------------
 
-The following functions are available to operate on string objects.
-They are not available as string methods.
-
-
 .. function:: capwords(s)
 
    Split the argument into words using :func:`split`, capitalize each word using
@@ -568,3 +564,6 @@
    Return a translation table suitable for passing to :meth:`bytes.translate`,
    that will map each character in *from* into the character at the same
    position in *to*; *from* and *to* must have the same length.
+
+   .. deprecated:: 3.1
+      Use the :meth:`bytes.maketrans` static method instead.

Modified: python/branches/py3k/Include/bytes_methods.h
==============================================================================
--- python/branches/py3k/Include/bytes_methods.h	(original)
+++ python/branches/py3k/Include/bytes_methods.h	Sun Apr 12 17:51:51 2009
@@ -20,6 +20,9 @@
 extern void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len);
 extern void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len);
 
+/* This one gets the raw argument list. */
+extern PyObject* _Py_bytes_maketrans(PyObject *args);
+
 /* Shared __doc__ strings. */
 extern const char _Py_isspace__doc__[];
 extern const char _Py_isalpha__doc__[];
@@ -33,6 +36,7 @@
 extern const char _Py_title__doc__[];
 extern const char _Py_capitalize__doc__[];
 extern const char _Py_swapcase__doc__[];
+extern const char _Py_maketrans__doc__[];
 
 #define FLAG_LOWER  0x01
 #define FLAG_UPPER  0x02

Modified: python/branches/py3k/Lib/string.py
==============================================================================
--- python/branches/py3k/Lib/string.py	(original)
+++ python/branches/py3k/Lib/string.py	Sun Apr 12 17:51:51 2009
@@ -49,6 +49,9 @@
     mapped to the byte at the same position in to.
     The strings frm and to must be of the same length.
     """
+    import warnings
+    warnings.warn("string.maketrans is deprecated, use bytes.maketrans instead",
+                  DeprecationWarning)
     if len(frm) != len(to):
         raise ValueError("maketrans arguments must have same length")
     if not (isinstance(frm, bytes) and isinstance(to, bytes)):

Modified: python/branches/py3k/Lib/test/test_bigmem.py
==============================================================================
--- python/branches/py3k/Lib/test/test_bigmem.py	(original)
+++ python/branches/py3k/Lib/test/test_bigmem.py	Sun Apr 12 17:51:51 2009
@@ -418,18 +418,15 @@
     @bigmemtest(minsize=_2G, memuse=2)
     def test_translate(self, size):
         _ = self.from_latin1
-        trans = {
-            ord(_('.')): _('-'),
-            ord(_('a')): _('!'),
-            ord(_('Z')): _('$'),
-        }
         SUBSTR = _('aZz.z.Aaz.')
-        if not isinstance(SUBSTR, str):
-            # Workaround the inexistence of bytes.maketrans()
-            chars = bytearray(range(256))
-            for k, v in trans.items():
-                chars[k] = ord(v)
-            trans = chars
+        if isinstance(SUBSTR, str):
+            trans = {
+                ord(_('.')): _('-'),
+                ord(_('a')): _('!'),
+                ord(_('Z')): _('$'),
+            }
+        else:
+            trans = bytes.maketrans(b'.aZ', b'-!$')
         sublen = len(SUBSTR)
         repeats = size // sublen + 2
         s = SUBSTR * repeats

Modified: python/branches/py3k/Lib/test/test_bytes.py
==============================================================================
--- python/branches/py3k/Lib/test/test_bytes.py	(original)
+++ python/branches/py3k/Lib/test/test_bytes.py	Sun Apr 12 17:51:51 2009
@@ -450,6 +450,13 @@
         self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],
                          [0, 65, 127, 128, 255])
 
+    def test_maketrans(self):
+        transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
+
+        self.assertEqual(self.type2test.maketrans(b'abc', b'xyz'), transtable)
+        self.assertRaises(ValueError, self.type2test.maketrans, b'abc', b'xyzq')
+        self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def')
+
 
 class BytesTest(BaseBytesTest):
     type2test = bytes

Modified: python/branches/py3k/Lib/test/test_string.py
==============================================================================
--- python/branches/py3k/Lib/test/test_string.py	(original)
+++ python/branches/py3k/Lib/test/test_string.py	Sun Apr 12 17:51:51 2009
@@ -101,14 +101,6 @@
         self.assertRaises(ValueError, fmt.format, "{0}", 10, 20, i=100)
         self.assertRaises(ValueError, fmt.format, "{i}", 10, 20, i=100)
 
-
-    def test_maketrans(self):
-        transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
-
-        self.assertEqual(string.maketrans(b'abc', b'xyz'), transtable)
-        self.assertRaises(ValueError, string.maketrans, b'abc', b'xyzq')
-        self.assertRaises(TypeError, string.maketrans, 'abc', 'def')
-
 def test_main():
     support.run_unittest(ModuleTest)
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sun Apr 12 17:51:51 2009
@@ -12,6 +12,11 @@
 Core and Builtins
 -----------------
 
+- The string.maketrans() function is deprecated; there is a new static method
+  maketrans() on the bytes and bytearray classes.  This removes confusion about
+  the types string.maketrans() is supposed to work with, and mirrors the
+  methods available on the str class.
+
 - Issue #2170: refactored xml.dom.minidom.normalize, increasing both
   its clarity and its speed.
 

Modified: python/branches/py3k/Objects/bytearrayobject.c
==============================================================================
--- python/branches/py3k/Objects/bytearrayobject.c	(original)
+++ python/branches/py3k/Objects/bytearrayobject.c	Sun Apr 12 17:51:51 2009
@@ -1451,6 +1451,13 @@
 }
 
 
+static PyObject *
+bytes_maketrans(PyObject *null, PyObject *args)
+{
+	return _Py_bytes_maketrans(args);
+}
+
+
 #define FORWARD 1
 #define REVERSE -1
 
@@ -3131,6 +3138,8 @@
     {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
     {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
     {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__},
+    {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC,
+     _Py_maketrans__doc__},
     {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__},
     {"pop", (PyCFunction)bytes_pop, METH_VARARGS, pop__doc__},
     {"remove", (PyCFunction)bytes_remove, METH_O, remove__doc__},

Modified: python/branches/py3k/Objects/bytes_methods.c
==============================================================================
--- python/branches/py3k/Objects/bytes_methods.c	(original)
+++ python/branches/py3k/Objects/bytes_methods.c	Sun Apr 12 17:51:51 2009
@@ -608,3 +608,70 @@
 	}
 }
 
+
+PyDoc_STRVAR_shared(_Py_maketrans__doc__,
+"B.maketrans(frm, to) -> translation table\n\
+\n\
+Return a translation table (a bytes object of length 256)\n\
+suitable for use in bytes.translate where each byte in frm is\n\
+mapped to the byte at the same position in to.\n\
+The strings frm and to must be of the same length.");
+
+static Py_ssize_t
+_getbuffer(PyObject *obj, Py_buffer *view)
+{
+    PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
+
+    if (buffer == NULL || buffer->bf_getbuffer == NULL)
+    {
+        PyErr_Format(PyExc_TypeError,
+                     "Type %.100s doesn't support the buffer API",
+                     Py_TYPE(obj)->tp_name);
+        return -1;
+    }
+
+    if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
+            return -1;
+    return view->len;
+}
+
+PyObject *
+_Py_bytes_maketrans(PyObject *args)
+{
+	PyObject *frm, *to, *res = NULL;
+	Py_buffer bfrm, bto;
+	int i;
+	char *p;
+
+	bfrm.len = -1;
+	bto.len = -1;
+	
+	if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to))
+		return NULL;
+	if (_getbuffer(frm, &bfrm) < 0)
+		return NULL;
+	if (_getbuffer(to, &bto) < 0)
+		goto done;
+	if (bfrm.len != bto.len) {
+		PyErr_Format(PyExc_ValueError,
+			     "maketrans arguments must have same length");
+		goto done;
+	}
+	res = PyBytes_FromStringAndSize(NULL, 256);
+	if (!res) {
+		goto done;
+	}
+	p = PyBytes_AS_STRING(res);
+	for (i = 0; i < 256; i++)
+		p[i] = i;
+	for (i = 0; i < bfrm.len; i++) {
+		p[(int)((char *)bfrm.buf)[i]] = ((char *)bto.buf)[i];
+	}
+
+  done:
+	if (bfrm.len != -1)
+		PyBuffer_Release(&bfrm);
+	if (bto.len != -1)
+		PyBuffer_Release(&bto);
+	return res;
+}

Modified: python/branches/py3k/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k/Objects/bytesobject.c	(original)
+++ python/branches/py3k/Objects/bytesobject.c	Sun Apr 12 17:51:51 2009
@@ -1950,6 +1950,12 @@
 }
 
 
+static PyObject *
+string_maketrans(PyObject *null, PyObject *args)
+{
+	return _Py_bytes_maketrans(args);
+}
+
 #define FORWARD 1
 #define REVERSE -1
 
@@ -2851,6 +2857,8 @@
 	{"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
 	{"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
 	{"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__},
+	{"maketrans", (PyCFunction)string_maketrans, METH_VARARGS|METH_STATIC,
+	 _Py_maketrans__doc__},
 	{"partition", (PyCFunction)string_partition, METH_O, partition__doc__},
 	{"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__},
 	{"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__},


More information about the Python-checkins mailing list