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

Fix all remaining instances that did bad things with the new str.translate().
This commit is contained in:
Georg Brandl 2007-08-31 10:37:15 +00:00
parent 226878cba5
commit 7f13e6b3e2
9 changed files with 39 additions and 62 deletions

View File

@ -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.
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'

View File

@ -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.
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`.

View File

@ -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))

View File

@ -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:
"""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):
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):
"""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:

View File

@ -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):
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)
#################################################################### ####################################################################

View File

@ -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):
@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

View File

@ -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)

View File

@ -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,10 +114,7 @@ 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.unicode_whitespace_trans)
text = text.translate(self.whitespace_trans)
elif isinstance(text, str):
text = text.translate(self.unicode_whitespace_trans)
return text return text

View File

@ -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=[]):
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)