Add bytes/bytearray.maketrans() to mirror str.maketrans(), and deprecate · pythoncapi/cpython@abc3877 · GitHub
Skip to content

Commit abc3877

Browse files
committed
Add bytes/bytearray.maketrans() to mirror str.maketrans(), and deprecate
string.maketrans() which actually works on bytes. (Also closes python#5675.)
1 parent 78532ba commit abc3877

11 files changed

Lines changed: 134 additions & 32 deletions

File tree

Doc/library/stdtypes.rst

Lines changed: 19 additions & 8 deletions

Doc/library/string.rst

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -548,13 +548,9 @@ rule:
548548
delimiter), and it should appear last in the regular expression.
549549

550550

551-
String functions
551+
Helper functions
552552
----------------
553553

554-
The following functions are available to operate on string objects.
555-
They are not available as string methods.
556-
557-
558554
.. function:: capwords(s)
559555

560556
Split the argument into words using :func:`split`, capitalize each word using
@@ -568,3 +564,6 @@ They are not available as string methods.
568564
Return a translation table suitable for passing to :meth:`bytes.translate`,
569565
that will map each character in *from* into the character at the same
570566
position in *to*; *from* and *to* must have the same length.
567+
568+
.. deprecated:: 3.1
569+
Use the :meth:`bytes.maketrans` static method instead.

Include/bytes_methods.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ extern void _Py_bytes_title(char *result, char *s, Py_ssize_t len);
2020
extern void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len);
2121
extern void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len);
2222

23+
/* This one gets the raw argument list. */
24+
extern PyObject* _Py_bytes_maketrans(PyObject *args);
25+
2326
/* Shared __doc__ strings. */
2427
extern const char _Py_isspace__doc__[];
2528
extern const char _Py_isalpha__doc__[];
@@ -33,6 +36,7 @@ extern const char _Py_upper__doc__[];
3336
extern const char _Py_title__doc__[];
3437
extern const char _Py_capitalize__doc__[];
3538
extern const char _Py_swapcase__doc__[];
39+
extern const char _Py_maketrans__doc__[];
3640

3741
#define FLAG_LOWER 0x01
3842
#define FLAG_UPPER 0x02

Lib/string.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ def maketrans(frm: bytes, to: bytes) -> bytes:
4949
mapped to the byte at the same position in to.
5050
The strings frm and to must be of the same length.
5151
"""
52+
import warnings
53+
warnings.warn("string.maketrans is deprecated, use bytes.maketrans instead",
54+
DeprecationWarning)
5255
if len(frm) != len(to):
5356
raise ValueError("maketrans arguments must have same length")
5457
if not (isinstance(frm, bytes) and isinstance(to, bytes)):

Lib/test/test_bigmem.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -418,18 +418,15 @@ def test_title(self, size):
418418
@bigmemtest(minsize=_2G, memuse=2)
419419
def test_translate(self, size):
420420
_ = self.from_latin1
421-
trans = {
422-
ord(_('.')): _('-'),
423-
ord(_('a')): _('!'),
424-
ord(_('Z')): _('$'),
425-
}
426421
SUBSTR = _('aZz.z.Aaz.')
427-
if not isinstance(SUBSTR, str):
428-
# Workaround the inexistence of bytes.maketrans()
429-
chars = bytearray(range(256))
430-
for k, v in trans.items():
431-
chars[k] = ord(v)
432-
trans = chars
422+
if isinstance(SUBSTR, str):
423+
trans = {
424+
ord(_('.')): _('-'),
425+
ord(_('a')): _('!'),
426+
ord(_('Z')): _('$'),
427+
}
428+
else:
429+
trans = bytes.maketrans(b'.aZ', b'-!$')
433430
sublen = len(SUBSTR)
434431
repeats = size // sublen + 2
435432
s = SUBSTR * repeats

Lib/test/test_bytes.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,13 @@ def test_ord(self):
450450
self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],
451451
[0, 65, 127, 128, 255])
452452

453+
def test_maketrans(self):
454+
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'
455+
456+
self.assertEqual(self.type2test.maketrans(b'abc', b'xyz'), transtable)
457+
self.assertRaises(ValueError, self.type2test.maketrans, b'abc', b'xyzq')
458+
self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def')
459+
453460

454461
class BytesTest(BaseBytesTest):
455462
type2test = bytes

Lib/test/test_string.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,6 @@ def check_unused_args(self, used_args, args, kwargs):
101101
self.assertRaises(ValueError, fmt.format, "{0}", 10, 20, i=100)
102102
self.assertRaises(ValueError, fmt.format, "{i}", 10, 20, i=100)
103103

104-
105-
def test_maketrans(self):
106-
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'
107-
108-
self.assertEqual(string.maketrans(b'abc', b'xyz'), transtable)
109-
self.assertRaises(ValueError, string.maketrans, b'abc', b'xyzq')
110-
self.assertRaises(TypeError, string.maketrans, 'abc', 'def')
111-
112104
def test_main():
113105
support.run_unittest(ModuleTest)
114106

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ What's New in Python 3.1 beta 1?
1212
Core and Builtins
1313
-----------------
1414

15+
- The string.maketrans() function is deprecated; there is a new static method
16+
maketrans() on the bytes and bytearray classes. This removes confusion about
17+
the types string.maketrans() is supposed to work with, and mirrors the
18+
methods available on the str class.
19+
1520
- Issue #2170: refactored xml.dom.minidom.normalize, increasing both
1621
its clarity and its speed.
1722

Objects/bytearrayobject.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,13 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
14511451
}
14521452

14531453

1454+
static PyObject *
1455+
bytes_maketrans(PyObject *null, PyObject *args)
1456+
{
1457+
return _Py_bytes_maketrans(args);
1458+
}
1459+
1460+
14541461
#define FORWARD 1
14551462
#define REVERSE -1
14561463

@@ -3131,6 +3138,8 @@ bytes_methods[] = {
31313138
{"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
31323139
{"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
31333140
{"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__},
3141+
{"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC,
3142+
_Py_maketrans__doc__},
31343143
{"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__},
31353144
{"pop", (PyCFunction)bytes_pop, METH_VARARGS, pop__doc__},
31363145
{"remove", (PyCFunction)bytes_remove, METH_O, remove__doc__},

Objects/bytes_methods.c

Lines changed: 67 additions & 0 deletions

0 commit comments

Comments
 (0)