Commit d76d5e1a authored by Kirill Smelkov's avatar Kirill Smelkov

golang_str: Fix ustr.translate on sequence

NumPy uses s.translate(str) and under gpython/py3 with str patched to be
ustr it breaks with:

      File ".../numpy-1.24.4-py3.9-linux-x86_64.egg/numpy/core/_string_helpers.py", line 40, in english_lower
        lowered = s.translate(LOWER_TABLE)
      File "golang/_golang_str.pyx", line 909, in golang._golang._pyustr.translate
    AttributeError: 'str' object has no attribute 'items'

https://docs.python.org/3/library/stdtypes.html#str.translate documents
translate to work on both mappings and sequences, so my usage of
table.items() in ff24be3d (golang_str: bstr/ustr string methods) was not
correct.

-> Fix it by reworking ustr.translate to use our proxy mapping instead
of going through all items of original table in the beginning.
parent b31c5fa2
......@@ -986,12 +986,7 @@ cdef class _pyustr(unicode):
def translate(self, table):
# unicode.translate does not accept bstr values
t = {}
for k,v in table.items():
if not isinstance(v, int): # either unicode ordinal,
v = _xpyu_coerce(v) # character or None
t[k] = v
return pyu(zunicode.translate(self, t))
return pyu(zunicode.translate(self, _pyustrTranslateTab(table)))
def upper(self): return pyu(zunicode.upper(self))
def zfill(self, width): return pyu(zunicode.zfill(self, width))
......@@ -1090,6 +1085,18 @@ def pyuiter(obj):
return iter(pyu(obj)) # TODO iterate obj directly
# _pyustrTranslateTab wraps table for .translate to return bstr as unicode
# because unicode.translate does not accept bstr values.
cdef class _pyustrTranslateTab:
cdef object tab
def __init__(self, tab):
self.tab = tab
def __getitem__(self, k):
v = self.tab[k]
if not isinstance(v, int): # either unicode ordinal,
v = _xpyu_coerce(v) # character or None
return v
# _bdata/_udata retrieve raw data from bytes/unicode.
def _bdata(obj): # -> bytes
......
......@@ -1886,6 +1886,7 @@ def test_strings_methods():
_("МиР").swapcase( ok="мИр")
_("МиР").title( ok="Мир")
_("мир").translate({ord(u'м'):ord(u'и'), ord(u'и'):'я', ord(u'р'):None}, ok="ия")
_(u"\u0000\u0001\u0002.").translate([u'м', ord(u'и'), None], ok="ми.")
_("МиР").upper( ok="МИР")
_("мир").zfill(10, ok="0000000мир")
_("123").zfill(10, ok="0000000123")
......
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