Commit fe5ab935 authored by Kirill Smelkov's avatar Kirill Smelkov

golang_str: Fix bstr/ustr %-formatting wrt tuple subclass

In 390fd810 (golang_str: bstr/ustr %-formatting) I've implemented
percent formatting but missed to handle tuple-subclass argv correctly.
For example the following works with std string:

    In [1]: import collections as cc
    In [5]: Point = cc.namedtuple('Point', ['x', 'y'])

    In [9]: 'α %s %s π' % Point('β','γ')
    Out[9]: '\xce\xb1 \xce\xb2 \xce\xb3 \xcf\x80'

while it fails with ustr:

    In [8]: ustr('α %s %s π') % Point('β','γ')
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-8-4f1a97267f2a> in <module>()
    ----> 1 ustr('α %s %s π') % Point('β','γ')

    /home/kirr/src/tools/go/pygolang/golang/_golang_str.pyx in golang._golang._pyustr.__mod__()
        850     # %-formatting
        851     def __mod__(a, b):
    --> 852         return pyu(pyb(a).__mod__(b))
        853     def __rmod__(b, a):
        854         # ("..." % x)  calls  "x.__rmod__()" for string subtypes

    /home/kirr/src/tools/go/pygolang/golang/_golang_str.pyx in golang._golang._pybstr.__mod__()
        473     # %-formatting
        474     def __mod__(a, b):
    --> 475         return _bprintf(a, b)
        476     def __rmod__(b, a):
        477         # ("..." % x)  calls  "x.__rmod__()" for string subtypes

    /home/kirr/src/tools/go/pygolang/golang/_golang_str.pyx in golang._golang._bprintf()
       1648
       1649     if isinstance(xarg, tuple):
    -> 1650         argv = xarg
       1651         xarg = _missing
       1652

    TypeError: Expected tuple, got Point

-> Fix that.
parent 3f221568
......@@ -1636,7 +1636,7 @@ cdef object _atidx_re = pyre.compile('.* at index ([0-9]+)$')
cdef _bprintf(const byte[::1] fmt, xarg): # -> pybstr
cdef bytearray out = bytearray()
cdef tuple argv = None # if xarg is tuple
cdef object argv = None # if xarg is tuple or subclass
cdef object argm = None # if xarg is mapping
# https://github.com/python/cpython/blob/2.7-0-g8d21aa21f2c/Objects/stringobject.c#L4298-L4300
......
......@@ -1457,7 +1457,10 @@ def test_strings_mod_and_format():
# namedtuple
cc = collections; xcc = six.moves
Point = cc.namedtuple('Point', ['x', 'y'])
_('α %s π', (Point('β','γ'),) , "α Point(x='β', y='γ') π")
verify_fmt_all_types(lambda fmt, args: fmt % args,
'α %s π', Point('β','γ') , TypeError("not all arguments converted during string formatting"), excok=True)
_('α %s %s π',Point('β','γ') , "α β γ π")
_('α %s π', (Point('β','γ'),) , "α Point(x='β', y='γ') π")
# deque
_('α %s π', cc.deque(['β','γ']) , "α deque(['β', 'γ']) π")
_('α %s π', (cc.deque(['β','γ']),) , "α deque(['β', 'γ']) π")
......
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