CustomTreeCtrl bug with multi-byte Unicode text

Hi

This is my first bug report so please bear with me.

I have a filesystem navigator app that uses HyperTreeCtrl, based on the demo code for this control.

If I resize the column or the top-level frame, the ‘ellipsizing’ code seems to have intermittent problems with multi-byte Unicode char strings when calculating text widths. It also triggers some asserts on exit.

This happens on both Linux and Mac. Not tried on Windows.

I have a attached a small test case which reproduces the error(s).

Thanks.

tree_text_bug_test.py (2.56 KB)

···

Environment:

wx.version(): ‘3.0.2.0 gtk2 (classic)’

uname: Linux mint 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Python 2.7.6 (default, Oct 26 2016, 20:30:19)

[GCC 4.8.4] on linux2

Output:

(1) Periodically when the bug is triggered

Traceback (most recent call last):

File “/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/wxPython/wx/lib/agw/hypertreelist.py”, line 3288, in OnPaint

y, x_maincol = self.PaintLevel(self._anchor, dc, 0, 0, x_maincol)

File “/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/wxPython/wx/lib/agw/hypertreelist.py”, line 3195, in PaintLevel

y, x_maincol = self.PaintLevel(child, dc, level+1, y, x_maincol)

File “/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/wxPython/wx/lib/agw/hypertreelist.py”, line 3106, in PaintLevel

self.PaintItem(item, dc)

File “/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/wxPython/wx/lib/agw/hypertreelist.py”, line 3006, in PaintItem

text = ChopText(dc, text, maxsize)

File “/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/wxPython/wx/lib/agw/customtreectrl.py”, line 649, in ChopText

x, y = dc.GetTextExtent(s)

File “/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/wxPython/wx/_gdi.py”, line 4127, in GetTextExtent

return gdi.DC_GetTextExtent(*args, **kwargs)

File “/usr/lib/python2.7/encodings/utf_8.py”, line 16, in decode

return codecs.utf_8_decode(input, errors, True)

UnicodeDecodeError: ‘utf8’ codec can’t decode byte 0xd8 in position 53: invalid continuation byte

(2) At interpreter exit

/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/src/gtk/dcclient.cpp(250): assert “Assert failure” failed in wxFreePoolGC(): Wrong GC

/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/src/gtk/dcclient.cpp(250): assert “Assert failure” failed in wxFreePoolGC(): Wrong GC

/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/src/gtk/dcclient.cpp(250): assert “Assert failure” failed in wxFreePoolGC(): Wrong GC

/home/duncang/openbackup/wx/wxPython-src-3.0.2.0/src/gtk/dcclient.cpp(250): assert “Assert failure” failed in wxFreePoolGC(): Wrong GC

(3) Mac is very similar but I also get a backtrace on exit

Apr 22 17:30:24 python[13200] : CGContextRestoreGState: invalid context 0x0. Backtrace:

  <_ZN14wxWindowDCImplD2Ev+54>

   <_ZN13wxPaintDCImplD0Ev+27>

    <_ZN9wxPaintDCD0Ev+44>

     <_wrap_delete_DC+107>

      <PySwigObject_dealloc+622>

       <_PyDict_Contains+162>

        <_PyObject_SlotCompare+23622>

         <PyFrame_GetLineNumber+142>

          <PySys_WriteStdout+3026>

           <PyDict_DelItemString+2315>

            <PyDict_Merge+715>

             <PyDict_SetItem+181>

              <PyDict_SetItemString+62>

               <PyImport_Cleanup+311>

                <Py_Finalize+297>

                 <Py_Main+2455>

(4) Unicode strings, used for my testing

서울시

ວຽງຈັນ

กรุงเทพมหานคร

Hà Nội

London

أبو ظبي‎

اسلام‌اباد

دبي‎

دولة الإمارات العربية المتحدة

Αθήνα

Αθήναι

Москва

Тошкент

मुंबई

ঢাকা

နေပြည်တော်

ශ්‍රී ජයවර්ධනපුර කෝට්ටේ

北京

東京都

As an update, I see similar behaviour with Phoenix.

This on Linux; I’ll try Mac later.

PS when building Phoenix, make sure you have already installed all the pre-requisite packages. The configure script will not pick some of these up, e.g. webkit. Guess how I know this :wink:

···

Linux mint 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Python 2.7.6 (default, Oct 26 2016, 20:30:19)

[GCC 4.8.4] on linux2

Type “help”, “copyright”, “credits” or “license” for more information.

import wx

wx.version()

‘4.0.0a1 gtk2 (phoenix)’

Traceback (most recent call last):

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/hypertreelist.py”, line 3291, in OnPaint

y, x_maincol = self.PaintLevel(self._anchor, dc, 0, 0, x_maincol)

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/hypertreelist.py”, line 3198, in PaintLevel

y, x_maincol = self.PaintLevel(child, dc, level+1, y, x_maincol)

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/hypertreelist.py”, line 3198, in PaintLevel

y, x_maincol = self.PaintLevel(child, dc, level+1, y, x_maincol)

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/hypertreelist.py”, line 3198, in PaintLevel

y, x_maincol = self.PaintLevel(child, dc, level+1, y, x_maincol)

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/hypertreelist.py”, line 3198, in PaintLevel

y, x_maincol = self.PaintLevel(child, dc, level+1, y, x_maincol)

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/hypertreelist.py”, line 3198, in PaintLevel

y, x_maincol = self.PaintLevel(child, dc, level+1, y, x_maincol)

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/hypertreelist.py”, line 3198, in PaintLevel

y, x_maincol = self.PaintLevel(child, dc, level+1, y, x_maincol)

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/hypertreelist.py”, line 3109, in PaintLevel

self.PaintItem(item, dc)

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/hypertreelist.py”, line 3009, in PaintItem

text = ChopText(dc, text, maxsize)

File “/usr/local/lib/python2.7/dist-packages/wx/lib/agw/customtreectrl.py”, line 652, in ChopText

x, y = dc.GetTextExtent(s)

UnicodeDecodeError: ‘utf8’ codec can’t decode byte 0xd8 in position 53: invalid continuation byte

On Saturday, 22 April 2017 18:40:00 UTC+1, obdev wrote:

Hi

I wasn’t able to reproduce your error but I would try converting your strings to unicode objects before adding them to the tree.

if not isinstance(t, unicode):

t = t.decode(‘utf-8’)

child = self.AppendItem(self.root, t, ct_type=1)

···


Robin Dunn

Software Craftsman

http://wxPython.org

That’s for Python 2.7. In Python 3 they will already be unicode.

···

On Wednesday, April 26, 2017 at 9:43:20 AM UTC-7, Robin Dunn wrote:

On Saturday, April 22, 2017 at 8:30:14 PM UTC-7, obdev wrote:

UnicodeDecodeError: ‘utf8’ codec can’t decode byte 0xd8 in position 53: invalid continuation byte

I wasn’t able to reproduce your error but I would try converting your strings to unicode objects before adding them to the tree.

if not isinstance(t, unicode):

t = t.decode(‘utf-8’)

child = self.AppendItem(self.root, t, ct_type=1)


Robin Dunn

Software Craftsman