Commit 7f13e6b3 authored by Georg Brandl's avatar Georg Brandl

string.maketrans() now produces translation tables for bytes.translate() -- wrong module?

Fix all remaining instances that did bad things with the new str.translate().
parent 226878cb
...@@ -1549,10 +1549,10 @@ further useful methods also found on strings. ...@@ -1549,10 +1549,10 @@ further useful methods also found on strings.
b'example' b'example'
.. method:: bytes.translate(table[, deletechars]) .. method:: bytes.translate(table[, delete])
Return a copy of the bytes object where all bytes occurring in the optional Return a copy of the bytes object where all bytes occurring in the optional
argument *deletechars* are removed, and the remaining bytes have been mapped argument *delete* are removed, and the remaining bytes have been mapped
through the given translation table, which must be a bytes object of length through the given translation table, which must be a bytes object of length
256. 256.
...@@ -1560,8 +1560,7 @@ further useful methods also found on strings. ...@@ -1560,8 +1560,7 @@ further useful methods also found on strings.
create a translation table. create a translation table.
.. XXX a None table doesn't seem to be supported .. XXX a None table doesn't seem to be supported
For string objects, set the *table* argument to Set the *table* argument to ``None`` for translations that only delete characters::
``None`` for translations that only delete characters::
>>> 'read this short text'.translate(None, 'aeiou') >>> 'read this short text'.translate(None, 'aeiou')
'rd ths shrt txt' 'rd ths shrt txt'
......
...@@ -128,10 +128,11 @@ formatting behaviors using the same implementation as the built-in ...@@ -128,10 +128,11 @@ formatting behaviors using the same implementation as the built-in
.. method:: get_field(field_name, args, kwargs, used_args) .. method:: get_field(field_name, args, kwargs, used_args)
Given *field_name* as returned by :meth:`parse` (see above), convert it to Given *field_name* as returned by :meth:`parse` (see above), convert it to
an object to be formatted. The default version takes strings of the form an object to be formatted. Returns a tuple (obj, used_key). The default
defined in :pep:`3101`, such as "0[name]" or "label.title". It records version takes strings of the form defined in :pep:`3101`, such as
which args have been used in *used_args*. *args* and *kwargs* are as "0[name]" or "label.title". *args* and *kwargs* are as passed in to
passed in to :meth:`vformat`. :meth:`vformat`. The return value *used_key* has the same meaning as the
*key* parameter to :meth:`get_value`.
.. method:: get_value(key, args, kwargs) .. method:: get_value(key, args, kwargs)
...@@ -554,15 +555,8 @@ They are not available as string methods. ...@@ -554,15 +555,8 @@ They are not available as string methods.
leading and trailing whitespace. leading and trailing whitespace.
.. XXX is obsolete with unicode.translate .. function:: maketrans(frm, to)
.. function:: maketrans(from, to)
Return a translation table suitable for passing to :func:`translate`, that will Return a translation table suitable for passing to :meth:`bytes.translate`,
map each character in *from* into the character at the same position in *to*; that will map each character in *from* into the character at the same
*from* and *to* must have the same length. position in *to*; *from* and *to* must have the same length.
.. warning::
Don't use strings derived from :const:`lowercase` and :const:`uppercase` as
arguments; in some locales, these don't have the same length. For case
conversions, always use :func:`lower` and :func:`upper`.
...@@ -348,11 +348,10 @@ class install (Command): ...@@ -348,11 +348,10 @@ class install (Command):
if opt_name[-1] == "=": if opt_name[-1] == "=":
opt_name = opt_name[0:-1] opt_name = opt_name[0:-1]
if self.negative_opt.has_key(opt_name): if self.negative_opt.has_key(opt_name):
opt_name = self.negative_opt[opt_name].translate( opt_name = longopt_xlate(self.negative_opt[opt_name])
longopt_xlate)
val = not getattr(self, opt_name) val = not getattr(self, opt_name)
else: else:
opt_name = opt_name.translate(longopt_xlate) opt_name = longopt_xlate(opt_name)
val = getattr(self, opt_name) val = getattr(self, opt_name)
print(" %s: %s" % (opt_name, val)) print(" %s: %s" % (opt_name, val))
......
...@@ -26,7 +26,7 @@ neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat)) ...@@ -26,7 +26,7 @@ neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat))
# This is used to translate long options to legitimate Python identifiers # This is used to translate long options to legitimate Python identifiers
# (for use as attributes of some object). # (for use as attributes of some object).
longopt_xlate = string.maketrans('-', '_') longopt_xlate = lambda s: s.replace('-', '_')
class FancyGetopt: class FancyGetopt:
"""Wrapper around the standard 'getopt()' module that provides some """Wrapper around the standard 'getopt()' module that provides some
...@@ -107,7 +107,7 @@ class FancyGetopt: ...@@ -107,7 +107,7 @@ class FancyGetopt:
"""Translate long option name 'long_option' to the form it """Translate long option name 'long_option' to the form it
has as an attribute of some object: ie., translate hyphens has as an attribute of some object: ie., translate hyphens
to underscores.""" to underscores."""
return long_option.translate(longopt_xlate) return longopt_xlate(long_option)
def _check_alias_dict(self, aliases, what): def _check_alias_dict(self, aliases, what):
assert isinstance(aliases, dict) assert isinstance(aliases, dict)
...@@ -372,7 +372,7 @@ def fancy_getopt(options, negative_opt, object, args): ...@@ -372,7 +372,7 @@ def fancy_getopt(options, negative_opt, object, args):
return parser.getopt(args, object) return parser.getopt(args, object)
WS_TRANS = string.maketrans(string.whitespace, ' ' * len(string.whitespace)) WS_TRANS = {ord(_wschar) : ' ' for _wschar in string.whitespace}
def wrap_text(text, width): def wrap_text(text, width):
"""wrap_text(text : string, width : int) -> [string] """wrap_text(text : string, width : int) -> [string]
...@@ -432,7 +432,7 @@ def translate_longopt(opt): ...@@ -432,7 +432,7 @@ def translate_longopt(opt):
"""Convert a long option name to a valid Python identifier by """Convert a long option name to a valid Python identifier by
changing "-" to "_". changing "-" to "_".
""" """
return opt.translate(longopt_xlate) return longopt_xlate(opt)
class OptionDummy: class OptionDummy:
......
...@@ -25,10 +25,6 @@ octdigits = '01234567' ...@@ -25,10 +25,6 @@ octdigits = '01234567'
punctuation = """!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" punctuation = """!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
printable = digits + ascii_letters + punctuation + whitespace printable = digits + ascii_letters + punctuation + whitespace
# Case conversion helpers
# Use str to convert Unicode literal in case of -U
_idmap = str('').join(chr(c) for c in range(256))
# Functions which aren't available as string methods. # Functions which aren't available as string methods.
# Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def". # Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def".
...@@ -44,26 +40,23 @@ def capwords(s, sep=None): ...@@ -44,26 +40,23 @@ def capwords(s, sep=None):
return (sep or ' ').join([x.capitalize() for x in s.split(sep)]) return (sep or ' ').join([x.capitalize() for x in s.split(sep)])
# Construct a translation string # Construct a translation map for bytes.translate
_idmapL = None def maketrans(frm, to):
def maketrans(fromstr, tostr): """maketrans(frm, to) -> bytes
"""maketrans(frm, to) -> string
Return a translation table (a string of 256 bytes long)
suitable for use in string.translate. The strings frm and to
must be of the same length.
Return a translation table (a bytes object of length 256)
suitable for use in bytes.translate where each byte in frm is
mapped to the byte at the same position in to.
The strings frm and to must be of the same length.
""" """
if len(fromstr) != len(tostr): if len(frm) != len(to):
raise ValueError("maketrans arguments must have same length") raise ValueError("maketrans arguments must have same length")
global _idmapL if not (isinstance(frm, bytes) and isinstance(to, bytes)):
if not _idmapL: raise TypeError("maketrans arguments must be bytes objects")
_idmapL = list(_idmap) L = bytes(range(256))
L = _idmapL[:] for i, c in enumerate(frm):
for i, c in enumerate(fromstr): L[c] = to[i]
L[ord(c)] = tostr[i] return L
return ''.join(L)
#################################################################### ####################################################################
......
...@@ -3,7 +3,6 @@ from test.test_support import bigmemtest, _1G, _2G ...@@ -3,7 +3,6 @@ from test.test_support import bigmemtest, _1G, _2G
import unittest import unittest
import operator import operator
import string
import sys import sys
# Bigmem testing houserules: # Bigmem testing houserules:
...@@ -376,7 +375,7 @@ class StrTest(unittest.TestCase): ...@@ -376,7 +375,7 @@ class StrTest(unittest.TestCase):
@bigmemtest(minsize=_2G, memuse=2) @bigmemtest(minsize=_2G, memuse=2)
def test_translate(self, size): def test_translate(self, size):
trans = string.maketrans('.aZ', '-!$') trans = {ord('.'):'-', ord('a'):'!', ord('Z'):'$'}
SUBSTR = 'aZz.z.Aaz.' SUBSTR = 'aZz.z.Aaz.'
sublen = len(SUBSTR) sublen = len(SUBSTR)
repeats = size // sublen + 2 repeats = size // sublen + 2
......
...@@ -103,10 +103,11 @@ class ModuleTest(unittest.TestCase): ...@@ -103,10 +103,11 @@ class ModuleTest(unittest.TestCase):
def test_maketrans(self): def test_maketrans(self):
transtable = '\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' 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('abc', 'xyz'), transtable) self.assertEqual(string.maketrans(b'abc', b'xyz'), transtable)
self.assertRaises(ValueError, string.maketrans, 'abc', 'xyzq') self.assertRaises(ValueError, string.maketrans, b'abc', b'xyzq')
self.assertRaises(TypeError, string.maketrans, 'abc', 'def')
def test_main(): def test_main():
test_support.run_unittest(ModuleTest) test_support.run_unittest(ModuleTest)
......
...@@ -59,8 +59,6 @@ class TextWrapper: ...@@ -59,8 +59,6 @@ class TextWrapper:
Drop leading and trailing whitespace from lines. Drop leading and trailing whitespace from lines.
""" """
whitespace_trans = string.maketrans(_whitespace, ' ' * len(_whitespace))
unicode_whitespace_trans = {} unicode_whitespace_trans = {}
uspace = ord(' ') uspace = ord(' ')
for x in _whitespace: for x in _whitespace:
...@@ -116,9 +114,6 @@ class TextWrapper: ...@@ -116,9 +114,6 @@ class TextWrapper:
if self.expand_tabs: if self.expand_tabs:
text = text.expandtabs() text = text.expandtabs()
if self.replace_whitespace: if self.replace_whitespace:
if isinstance(text, str8):
text = text.translate(self.whitespace_trans)
elif isinstance(text, str):
text = text.translate(self.unicode_whitespace_trans) text = text.translate(self.unicode_whitespace_trans)
return text return text
......
...@@ -1420,7 +1420,6 @@ def reporthook(blocknum, blocksize, totalsize): ...@@ -1420,7 +1420,6 @@ def reporthook(blocknum, blocksize, totalsize):
# Test program # Test program
def test(args=[]): def test(args=[]):
import string
if not args: if not args:
args = [ args = [
'/etc/passwd', '/etc/passwd',
...@@ -1443,9 +1442,7 @@ def test(args=[]): ...@@ -1443,9 +1442,7 @@ def test(args=[]):
fp = open(fn, 'rb') fp = open(fn, 'rb')
data = fp.read() data = fp.read()
del fp del fp
if '\r' in data: data = data.replace("\r", "")
table = string.maketrans("", "")
data = data.translate(table, "\r")
print(data) print(data)
fn, h = None, None fn, h = None, None
print('-'*40) print('-'*40)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment