Phoenix port of wx.lib and friends

Hi All,

    just in case anyone is interested in helping out porting wx.lib to
Python 3 and Phoenix (and I hope some of you will be...), I'd like to
share some of the experience I had with AGW.

First of all, I am almost finished in porting AGW to Phoenix and
Python 3 (meaning that Python 2 and Python 3 do not complain about the
AGW code), although I am hitting some barriers I wasn't expecting to
find, so I'll leave some questions to Robin at the end.

If any of you would like to contribute to the porting effort (and just
in case you care), this is what I did:

1) Get the Phoenix binaries from:

http://wxpython.org/Phoenix/snapshot-builds/

(Or build them from source if none of the architectures matches yours).

2) Get modernize:

https://github.com/mitsuhiko/python-modernize

3) Pick your favourite wx.lib module you wish to port (possibly from
wxPython SVN) and, on Windows (but I am sure it will be similar on
other platforms), do this:

c:\Python27\Scripts\python-modernize.exe -p -w the_wxlib_script.py

You will find that the original source has been overwritten by
modernize, but a backup file exists with the original code in it.

4) For some of the scripts in wx.lib, modernize will add a dependency
on the six module (http://packages.python.org/six/), but I have hacked
it a bit and adapted it to wxPython needs. Yo can find it here:

http://xoomer.virgilio.it/infinity77/Zipped/wx2to3.py

I currently have it under wx.lib. Then, I did the following:

a) Remove any import of the six module;
b) Replace map(something) and zip(something) with list(map(something))
and list(zip(something)) - although this can be sometimes awkward, see
http://getpython3.com/diveintopython3/porting-code-to-python-3-with-2to3.html;
c) Put the wx2to3 into wx.lib and, if necessary (see points (d) to (f)
), import it as "import wx.lib.wx2to3 as wx2to3";
d) Any instance of "six.u(string)" becomes "wx2to3.u(string)" - to
handle unicode objects transparently across Python versions;
e) All the calls to cPickle and StringIO should be replaced by
wx2to3.pickle and wx2to3.StringIO;
f) Any list sort() which uses a cmp function as keeyword or argument
should be replaced by wx2to3.sort(the_list, cmp_function).

5) Create a very simple dummy sample app for your converted module and
you should be able to test it under Python 2 and Python 3 (but see
questions to Robin below).

@Robin:

I have started testing AGW against Phoenix (using the simple snippets
in the docstrings, not the full blown demo in AGW), and the first
three widgets did not give encouraging results:

1) AdvancedSplash:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python advancedsplash.py
Traceback (most recent call last):
  File "advancedsplash.py", line 164, in <module>
    class AdvancedSplash(wx.Frame):
  File "advancedsplash.py", line 172, in AdvancedSplash
    style=wx.FRAME_NO_TASKBAR | wx.FRAME_SHAPED | wx.STAY_ON_TOP,
AttributeError: 'module' object has no attribute 'FRAME_SHAPED'

OK then, let's remove wx.FRAME_SHAPED from the style bits then:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python advancedsplash.py
advancedsplash.py:556: wxPyDeprecationWarning: Call to deprecated item
'EmptyBitmap'.
  bitmap = wx.EmptyBitmap(100, 100)
Traceback (most recent call last):
  File "advancedsplash.py", line 557, in <module>
    splash = AdvancedSplash(None, bitmap=bitmap, timeout=5000,
agwStyle=AS_TIMEOUT)
  File "advancedsplash.py", line 255, in __init__
    self.reg = wx.RegionFromBitmap(self.bmp)
AttributeError: 'module' object has no attribute 'RegionFromBitmap'

I had to stop as without wx.RegionFromBitmap there is no
AdvancedSplash. Also, the deprecation of wx.EmptyBitmap (and its
friend, wx.EmptyBitmapRGBA) is going to kill a good chunk of wx.lib
(but we can get away by automatically replacing it via some scripts).

2) AquaButton:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python aquabutton.py
aquabutton.py:305: wxPyDeprecationWarning: Using deprecated class Colour.
  rc2.width, wx.NamedColour("grey"), wx.WHITE)
aquabutton.py:348: wxPyDeprecationWarning: Call to deprecated item
'EmptyBitmapRGBA'.
  self._storedBitmap = wx.EmptyBitmapRGBA(max(width, 1), max(height, 1))

wx.Colour can not be a deprecated class.

But I went back and changed wx.EmptyBitmapRGBA to wx.Bitmap.FromRGBA,
but all I get are two grey rectangles (where the AquaButtons should
be) and the application frame can not be closed (it's hanging). Not
sure what it means though.

3) CubeColourDialog:

Traceback (most recent call last):
  File "cubecolourdialog.py", line 3503, in <module>
    dlg = CubeColourDialog(None, colourData)
  File "cubecolourdialog.py", line 2918, in __init__
    self.DoLayout()
  File "cubecolourdialog.py", line 3026, in DoLayout
    panelSizer.Add((0, 0), 1, wx.EXPAND)
TypeError: Sizer.Add(): arguments did not match any overloaded call:
  overload 1: argument 1 has unexpected type 'tuple'
  overload 2: argument 1 has unexpected type 'tuple'
  overload 3: argument 1 has unexpected type 'tuple'
  overload 4: argument 1 has unexpected type 'tuple'
  overload 5: argument 1 has unexpected type 'tuple'
  overload 6: argument 1 has unexpected type 'tuple'

It's going to be funny :slight_smile: . After unpacking the tuple into width,
height for Sizer.Add to be happy (and changing all the instances of
wx.EmptyBitmap, DrawRectangleRect and SetClippingRect), it seems to
run OK, although when I close the CubeColourDialog window (it's a
simple dialog called via ShowModal), the app does not exit (it hangs
there, although the dialog has disappeared) as I clicked on the "OK"
button and called Destroy() on it.

I'll do some more testing in the next few days.

···

--
Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

<snip>
<snap>

1) AdvancedSplash:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python advancedsplash.py
Traceback (most recent call last):
  File "advancedsplash.py", line 164, in <module>
    class AdvancedSplash(wx.Frame):
  File "advancedsplash.py", line 172, in AdvancedSplash
    style=wx.FRAME_NO_TASKBAR | wx.FRAME_SHAPED | wx.STAY_ON_TOP,
AttributeError: 'module' object has no attribute 'FRAME_SHAPED'

OK then, let's remove wx.FRAME_SHAPED from the style bits then:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python advancedsplash.py
advancedsplash.py:556: wxPyDeprecationWarning: Call to deprecated item
'EmptyBitmap'.
  bitmap = wx.EmptyBitmap(100, 100)
Traceback (most recent call last):
  File "advancedsplash.py", line 557, in <module>
    splash = AdvancedSplash(None, bitmap=bitmap, timeout=5000,
agwStyle=AS_TIMEOUT)
  File "advancedsplash.py", line 255, in __init__
    self.reg = wx.RegionFromBitmap(self.bmp)
AttributeError: 'module' object has no attribute 'RegionFromBitmap'

I had to stop as without wx.RegionFromBitmap there is no
AdvancedSplash. Also, the deprecation of wx.EmptyBitmap (and its
friend, wx.EmptyBitmapRGBA) is going to kill a good chunk of wx.lib
(but we can get away by automatically replacing it via some scripts).

My apologies, wx.RegionFromBitmap is of course gone as now there is
only one constructor, wx.Region. But the wx.FRAME_SHAPED issue remains
after that change:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python advancedsplash.py
advancedsplash.py:556: wxPyDeprecationWarning: Call to deprecated item
'EmptyBitmap'.
  bitmap = wx.EmptyBitmap(100, 100)
Traceback (most recent call last):
  File "advancedsplash.py", line 557, in <module>
    splash = AdvancedSplash(None, bitmap=bitmap, timeout=5000,
agwStyle=AS_TIMEOUT)
  File "advancedsplash.py", line 263, in __init__
    self.SetSplashShape()
  File "advancedsplash.py", line 298, in SetSplashShape
    self.SetShape(self.reg)
wx._core.wxAssertionError: C++ assertion "HasFlag(0x0010)" failed at
E:\Phoenix\wxWidgets\trunk\include\wx/nonownedwnd.h(42) in
wxNonOwnedWindowBase::SetShape():
Shaped windows must be created with the wxFRAME_SHAPED style.

2) AquaButton:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python aquabutton.py
aquabutton.py:305: wxPyDeprecationWarning: Using deprecated class Colour.
  rc2.width, wx.NamedColour("grey"), wx.WHITE)
aquabutton.py:348: wxPyDeprecationWarning: Call to deprecated item
'EmptyBitmapRGBA'.
  self._storedBitmap = wx.EmptyBitmapRGBA(max(width, 1), max(height, 1))

wx.Colour can not be a deprecated class.

But wx.NamedColour is, in fact I got rid of the warning by simply
using wx.Colour. But the buttons are still grey, no text, and the main
frame can not be closed.

Andrea.

···

On 10 July 2012 20:56, Andrea Gavana wrote:

Hi All,

     just in case anyone is interested in helping out porting wx.lib to
Python 3 and Phoenix (and I hope some of you will be...), I'd like to
share some of the experience I had with AGW.

First of all, I am almost finished in porting AGW to Phoenix and
Python 3 (meaning that Python 2 and Python 3 do not complain about the
AGW code), although I am hitting some barriers I wasn't expecting to
find, so I'll leave some questions to Robin at the end.

If any of you would like to contribute to the porting effort (and just
in case you care), this is what I did:

1) Get the Phoenix binaries from:

http://wxpython.org/Phoenix/snapshot-builds/

(Or build them from source if none of the architectures matches yours).

2) Get modernize:

https://github.com/mitsuhiko/python-modernize

3) Pick your favourite wx.lib module you wish to port (possibly from
wxPython SVN) and, on Windows (but I am sure it will be similar on
other platforms), do this:

c:\Python27\Scripts\python-modernize.exe -p -w the_wxlib_script.py

You will find that the original source has been overwritten by
modernize, but a backup file exists with the original code in it.

4) For some of the scripts in wx.lib, modernize will add a dependency
on the six module (http://packages.python.org/six/), but I have hacked
it a bit and adapted it to wxPython needs. Yo can find it here:

http://xoomer.virgilio.it/infinity77/Zipped/wx2to3.py

I currently have it under wx.lib. Then, I did the following:

a) Remove any import of the six module;
b) Replace map(something) and zip(something) with list(map(something))
and list(zip(something)) - although this can be sometimes awkward, see
http://getpython3.com/diveintopython3/porting-code-to-python-3-with-2to3.html;
c) Put the wx2to3 into wx.lib and, if necessary (see points (d) to (f)
), import it as "import wx.lib.wx2to3 as wx2to3";
d) Any instance of "six.u(string)" becomes "wx2to3.u(string)" - to
handle unicode objects transparently across Python versions;
e) All the calls to cPickle and StringIO should be replaced by
wx2to3.pickle and wx2to3.StringIO;
f) Any list sort() which uses a cmp function as keeyword or argument
should be replaced by wx2to3.sort(the_list, cmp_function).

5) Create a very simple dummy sample app for your converted module and
you should be able to test it under Python 2 and Python 3 (but see
questions to Robin below).

If you want to help out then please also refer to the steps in Phase 2 at http://wiki.wxpython.org/ProjectPhoenix/LibraryMigration, namely review and or adding Sphinx-compatible docstrings everywhere and also making unittests. A module will not be considered finished without proper docs and a unittest.

Andrea, could you write something at http://wiki.wxpython.org/ProjectPhoenix/DocumentationProject which gives a summary and examples about what kinds of things should be in typical wx.lib docstrings, and maybe also some links to the relevant Sphinx or ReST pages that help with the markup syntax. Thanks.

@Robin:

I have started testing AGW against Phoenix (using the simple snippets
in the docstrings, not the full blown demo in AGW), and the first
three widgets did not give encouraging results:

1) AdvancedSplash:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python advancedsplash.py
Traceback (most recent call last):
   File "advancedsplash.py", line 164, in <module>
     class AdvancedSplash(wx.Frame):
   File "advancedsplash.py", line 172, in AdvancedSplash
     style=wx.FRAME_NO_TASKBAR | wx.FRAME_SHAPED | wx.STAY_ON_TOP,
AttributeError: 'module' object has no attribute 'FRAME_SHAPED'

Looks like somebody didn't add it to the interface headers so there wasn't anything for the ETG script to extract. I'll add it for tonight's build.

OK then, let's remove wx.FRAME_SHAPED from the style bits then:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python advancedsplash.py
advancedsplash.py:556: wxPyDeprecationWarning: Call to deprecated item
'EmptyBitmap'.
   bitmap = wx.EmptyBitmap(100, 100)
Traceback (most recent call last):
   File "advancedsplash.py", line 557, in <module>
     splash = AdvancedSplash(None, bitmap=bitmap, timeout=5000,
agwStyle=AS_TIMEOUT)
   File "advancedsplash.py", line 255, in __init__
     self.reg = wx.RegionFromBitmap(self.bmp)
AttributeError: 'module' object has no attribute 'RegionFromBitmap'

Now you should just use wx.Region(self.bmp). The overloading support in SIP will take care of routing it to the proper C++ constructor. See the note about overloaded functions in the migration guide.

I realized a few weeks back that the generic description for most things in the migration guide is not always helpful enough, so I made a wiki page where people can record details about the things like this that they needed to change while porting to Phoenix. http://wiki.wxpython.org/ProjectPhoenix/PortingIssues

I had to stop as without wx.RegionFromBitmap there is no
AdvancedSplash. Also, the deprecation of wx.EmptyBitmap (and its
friend, wx.EmptyBitmapRGBA) is going to kill a good chunk of wx.lib
(but we can get away by automatically replacing it via some scripts).

2) AquaButton:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python aquabutton.py
aquabutton.py:305: wxPyDeprecationWarning: Using deprecated class Colour.
   rc2.width, wx.NamedColour("grey"), wx.WHITE)
aquabutton.py:348: wxPyDeprecationWarning: Call to deprecated item
'EmptyBitmapRGBA'.
   self._storedBitmap = wx.EmptyBitmapRGBA(max(width, 1), max(height, 1))

wx.Colour can not be a deprecated class.

Try it with last night's binaries. I made some changes yesterday that should make the deprecation messages be more clear, and most of them should now tell you what you should be using instead.

But I went back and changed wx.EmptyBitmapRGBA to wx.Bitmap.FromRGBA,
but all I get are two grey rectangles (where the AquaButtons should
be) and the application frame can not be closed (it's hanging). Not
sure what it means though.

3) CubeColourDialog:

Traceback (most recent call last):
   File "cubecolourdialog.py", line 3503, in <module>
     dlg = CubeColourDialog(None, colourData)
   File "cubecolourdialog.py", line 2918, in __init__
     self.DoLayout()
   File "cubecolourdialog.py", line 3026, in DoLayout
     panelSizer.Add((0, 0), 1, wx.EXPAND)
TypeError: Sizer.Add(): arguments did not match any overloaded call:
   overload 1: argument 1 has unexpected type 'tuple'
   overload 2: argument 1 has unexpected type 'tuple'
   overload 3: argument 1 has unexpected type 'tuple'
   overload 4: argument 1 has unexpected type 'tuple'
   overload 5: argument 1 has unexpected type 'tuple'
   overload 6: argument 1 has unexpected type 'tuple'

Oops I thought that Add() and the others had an overload taking a wxSize, which can be automatically converted from a 2 element sequence... I'll take a look at doing something to get those working again.

It's going to be funny :slight_smile: . After unpacking the tuple into width,
height for Sizer.Add to be happy (and changing all the instances of
wx.EmptyBitmap, DrawRectangleRect and SetClippingRect), it seems to
run OK, although when I close the CubeColourDialog window (it's a
simple dialog called via ShowModal), the app does not exit (it hangs
there, although the dialog has disappeared) as I clicked on the "OK"
button and called Destroy() on it.

I'll do some more testing in the next few days.

Thanks.

···

On 7/10/12 11:56 AM, Andrea Gavana wrote:

--
Robin Dunn
Software Craftsman
http://wxPython.org

I gave it a go:

http://wiki.wxpython.org/ProjectPhoenix/DocumentationProject

Please let me know if you had something else in mind or if you want me
to expand some of the topics.

···

On 10 July 2012 22:50, Robin Dunn wrote:

On 7/10/12 11:56 AM, Andrea Gavana wrote:

Hi All,

     just in case anyone is interested in helping out porting wx.lib to
Python 3 and Phoenix (and I hope some of you will be...), I'd like to
share some of the experience I had with AGW.

First of all, I am almost finished in porting AGW to Phoenix and
Python 3 (meaning that Python 2 and Python 3 do not complain about the
AGW code), although I am hitting some barriers I wasn't expecting to
find, so I'll leave some questions to Robin at the end.

If any of you would like to contribute to the porting effort (and just
in case you care), this is what I did:

1) Get the Phoenix binaries from:

http://wxpython.org/Phoenix/snapshot-builds/

(Or build them from source if none of the architectures matches yours).

2) Get modernize:

https://github.com/mitsuhiko/python-modernize

3) Pick your favourite wx.lib module you wish to port (possibly from
wxPython SVN) and, on Windows (but I am sure it will be similar on
other platforms), do this:

c:\Python27\Scripts\python-modernize.exe -p -w the_wxlib_script.py

You will find that the original source has been overwritten by
modernize, but a backup file exists with the original code in it.

4) For some of the scripts in wx.lib, modernize will add a dependency
on the six module (http://packages.python.org/six/), but I have hacked
it a bit and adapted it to wxPython needs. Yo can find it here:

http://xoomer.virgilio.it/infinity77/Zipped/wx2to3.py

I currently have it under wx.lib. Then, I did the following:

a) Remove any import of the six module;
b) Replace map(something) and zip(something) with list(map(something))
and list(zip(something)) - although this can be sometimes awkward, see

http://getpython3.com/diveintopython3/porting-code-to-python-3-with-2to3.html;
c) Put the wx2to3 into wx.lib and, if necessary (see points (d) to (f)
), import it as "import wx.lib.wx2to3 as wx2to3";
d) Any instance of "six.u(string)" becomes "wx2to3.u(string)" - to
handle unicode objects transparently across Python versions;
e) All the calls to cPickle and StringIO should be replaced by
wx2to3.pickle and wx2to3.StringIO;
f) Any list sort() which uses a cmp function as keeyword or argument
should be replaced by wx2to3.sort(the_list, cmp_function).

5) Create a very simple dummy sample app for your converted module and
you should be able to test it under Python 2 and Python 3 (but see
questions to Robin below).

If you want to help out then please also refer to the steps in Phase 2 at
http://wiki.wxpython.org/ProjectPhoenix/LibraryMigration, namely review and
or adding Sphinx-compatible docstrings everywhere and also making unittests.
A module will not be considered finished without proper docs and a unittest.

Andrea, could you write something at
http://wiki.wxpython.org/ProjectPhoenix/DocumentationProject which gives a
summary and examples about what kinds of things should be in typical wx.lib
docstrings, and maybe also some links to the relevant Sphinx or ReST pages
that help with the markup syntax. Thanks.

--
Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

Andrea Gavana wrote:

···

On 10 July 2012 22:50, Robin Dunn wrote:

Andrea, could you write something at
http://wiki.wxpython.org/ProjectPhoenix/DocumentationProject which gives a
summary and examples about what kinds of things should be in typical wx.lib
docstrings, and maybe also some links to the relevant Sphinx or ReST pages
that help with the markup syntax. Thanks.

I gave it a go:

http://wiki.wxpython.org/ProjectPhoenix/DocumentationProject

Please let me know if you had something else in mind or if you want me
to expand some of the topics.

That looks good. Thank you.

--
Robin Dunn
Software Craftsman
http://wxPython.org

Robin, All,

@Robin:

I have started testing AGW against Phoenix (using the simple snippets
in the docstrings, not the full blown demo in AGW), and the first
three widgets did not give encouraging results:

1) AdvancedSplash:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python
advancedsplash.py
Traceback (most recent call last):
   File "advancedsplash.py", line 164, in <module>
     class AdvancedSplash(wx.Frame):
   File "advancedsplash.py", line 172, in AdvancedSplash
     style=wx.FRAME_NO_TASKBAR | wx.FRAME_SHAPED | wx.STAY_ON_TOP,
AttributeError: 'module' object has no attribute 'FRAME_SHAPED'

Looks like somebody didn't add it to the interface headers so there wasn't
anything for the ETG script to extract. I'll add it for tonight's build.

OK then, let's remove wx.FRAME_SHAPED from the style bits then:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python
advancedsplash.py
advancedsplash.py:556: wxPyDeprecationWarning: Call to deprecated item
'EmptyBitmap'.
   bitmap = wx.EmptyBitmap(100, 100)
Traceback (most recent call last):
   File "advancedsplash.py", line 557, in <module>
     splash = AdvancedSplash(None, bitmap=bitmap, timeout=5000,
agwStyle=AS_TIMEOUT)
   File "advancedsplash.py", line 255, in __init__
     self.reg = wx.RegionFromBitmap(self.bmp)
AttributeError: 'module' object has no attribute 'RegionFromBitmap'

Now you should just use wx.Region(self.bmp). The overloading support in SIP
will take care of routing it to the proper C++ constructor. See the note
about overloaded functions in the migration guide.

I realized a few weeks back that the generic description for most things in
the migration guide is not always helpful enough, so I made a wiki page
where people can record details about the things like this that they needed
to change while porting to Phoenix.
http://wiki.wxpython.org/ProjectPhoenix/PortingIssues

I had to stop as without wx.RegionFromBitmap there is no
AdvancedSplash. Also, the deprecation of wx.EmptyBitmap (and its
friend, wx.EmptyBitmapRGBA) is going to kill a good chunk of wx.lib
(but we can get away by automatically replacing it via some scripts).

2) AquaButton:

C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw>python aquabutton.py
aquabutton.py:305: wxPyDeprecationWarning: Using deprecated class Colour.
   rc2.width, wx.NamedColour("grey"), wx.WHITE)
aquabutton.py:348: wxPyDeprecationWarning: Call to deprecated item
'EmptyBitmapRGBA'.
   self._storedBitmap = wx.EmptyBitmapRGBA(max(width, 1), max(height, 1))

wx.Colour can not be a deprecated class.

Try it with last night's binaries. I made some changes yesterday that
should make the deprecation messages be more clear, and most of them should
now tell you what you should be using instead.

But I went back and changed wx.EmptyBitmapRGBA to wx.Bitmap.FromRGBA,
but all I get are two grey rectangles (where the AquaButtons should
be) and the application frame can not be closed (it's hanging). Not
sure what it means though.

3) CubeColourDialog:

Traceback (most recent call last):
   File "cubecolourdialog.py", line 3503, in <module>
     dlg = CubeColourDialog(None, colourData)
   File "cubecolourdialog.py", line 2918, in __init__
     self.DoLayout()
   File "cubecolourdialog.py", line 3026, in DoLayout
     panelSizer.Add((0, 0), 1, wx.EXPAND)
TypeError: Sizer.Add(): arguments did not match any overloaded call:
   overload 1: argument 1 has unexpected type 'tuple'
   overload 2: argument 1 has unexpected type 'tuple'
   overload 3: argument 1 has unexpected type 'tuple'
   overload 4: argument 1 has unexpected type 'tuple'
   overload 5: argument 1 has unexpected type 'tuple'
   overload 6: argument 1 has unexpected type 'tuple'

Oops I thought that Add() and the others had an overload taking a wxSize,
which can be automatically converted from a 2 element sequence... I'll take
a look at doing something to get those working again.

It's going to be funny :slight_smile: . After unpacking the tuple into width,
height for Sizer.Add to be happy (and changing all the instances of
wx.EmptyBitmap, DrawRectangleRect and SetClippingRect), it seems to
run OK, although when I close the CubeColourDialog window (it's a
simple dialog called via ShowModal), the app does not exit (it hangs
there, although the dialog has disappeared) as I clicked on the "OK"
button and called Destroy() on it.

I'll do some more testing in the next few days.

I have done some more porting and testing in the last few days while
porting AGW, and there are a few remarks I have written down.

First of all, if anyone cares, this file:

http://xoomer.virgilio.it/infinity77/Zipped/classic_vs_phoenix.txt

Contains a list of the most common wxPython functions, classes and
wx.Window/wx.Sizer methods which need to be changed to a new syntax in
Phoenix; it's a 2-columns, tab-separated file containing the old
wxPython name on the left and the new (if it exists) Phoenix name on
the right. I found it impressively useful while porting AGW to
Phoenix.

Few more comments follow.

General syntax:

1) All modules using wx.Font (not only AGW, also in wx.lib and in all
of your applications):

Old constructors are broken, i.e.:

wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD)

TypeError: Font(): arguments did not match any overloaded call:
  overload 1: too many arguments
  overload 2: argument 1 has unexpected type 'int'
  overload 3: argument 4 has unexpected type 'FontStyle'
  overload 4: argument 1 has unexpected type 'int'
  overload 5: argument 4 has unexpected type 'FontStyle'
  overload 6: argument 1 has unexpected type 'int'
  overload 7: argument 1 has unexpected type 'int'

They *need* to be:

wx.Font(8, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False)

I.e., parameters 2 to 4 need to have the proper type in front of them
(FONTFAMILY_*, FONTSTYLE_* and FONTWEIGHT_*).

2) All modules using wx.Brush and wx.Pen (not only AGW, also in wx.lib
and in all of your applications):

Old constructors are broken, i.e.:

wx.Brush(wx.RED, wx.SOLID)
wx.Pen(wx.BLACK, 1, wx.DOT)

TypeError: Brush(): arguments did not match any overloaded call:
  overload 1: too many arguments
  overload 2: argument 2 has unexpected type 'PenStyle'
  overload 3: argument 1 has unexpected type 'Colour'
  overload 4: argument 1 has unexpected type 'Colour'

They *need* to be converted into:

wx.Brush(wx.RED, wx.BRUSHSTYLE_SOLID)
wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)

3) The Calc{Scrolled|Unscrolled}Position methods do not accept a
wx.Point or a tuple anymore, they need to be converted to 2 integer
arguments.

AGW:

Module which seem to work: AdvancedSplash, BalloonTip, ButtonPanel,
CustomTreeCtrl, FoldPanelBar, FourWaySplitter, HyperLinkCtrl,
KnobCtrl, PeakMeter, PieCtrl, PyBusyInfo, PyCollapsiblePane, PyGauge,
RulerCtrl, ShapedButton, SuperToolTip, ThumbnailCtrl, ToasterBox,
UltimateListCtrl, ZoomBar.

1) AquaButton still displays grey, empty rectangles: the OnPaint
method is never called, for some reason (see comment on GradientButton
as well);

2) CubeColourDialog seems to work, but the app still hangs after
closing the dialog (via any button), even though I explicitely call
dlg.Destroy();

3) FlatMenu has too many dependencies in need to be ported, so no
testing for now;

4) FlatNotebook:

E:\Phoenix\wxPython\Phoenix\wx\lib\agw>python flatnotebook.py
Traceback (most recent call last):
  File "flatnotebook.py", line 6689, in <module>
    frame = MyFrame(None)
  File "flatnotebook.py", line 6666, in __init__
    notebook = FlatNotebook(panel, -1)
  File "flatnotebook.py", line 3929, in __init__
    self._pages = PageContainer(self, wx.ID_ANY, wx.DefaultPosition,
wx.DefaultSize, style)
  File "flatnotebook.py", line 5129, in __init__
    self._pDropTarget = FNBDropTarget(self)
  File "flatnotebook.py", line 1058, in __init__
    self._dataobject = wx.CustomDataObject(wx.CustomDataFormat("FlatNotebook"))
AttributeError: 'module' object has no attribute 'CustomDataFormat'

Commenting out the code with wx.CustomDataFormat I get this:

E:\Phoenix\wxPython\Phoenix\wx\lib\agw>python flatnotebook.py
Traceback (most recent call last):
  File "flatnotebook.py", line 5183, in OnPaint
    renderer.DrawTabs(self, dc)
  File "flatnotebook.py", line 2363, in DrawTabs
    self.DrawLeftArrow(pc, dc)
  File "flatnotebook.py", line 1852, in DrawLeftArrow
    arrowBmp = wx.Bitmap(left_arrow_xpm)
TypeError: Bitmap(): arguments did not match any overloaded call:
  overload 1: too many arguments
  overload 2: argument 1 has unexpected type 'list'
  overload 3: argument 1 has unexpected type 'list'
  overload 4: argument 1 has unexpected type 'list'
  overload 5: argument 1 has unexpected type 'list'
  overload 6: argument 1 has unexpected type 'list'
  overload 7: argument 1 has unexpected type 'list'

Now, how do we handle XPM data in Phoenix? All the available
constructors seem to reject it, although one of the wxWidgets
constructors has it:

http://docs.wxwidgets.org/trunk/classwx_bitmap.html#a0b750963aa91e021dfa222138d1678ed

5) FloatSpin:

E:\Phoenix\wxPython\Phoenix\wx\lib\agw>python floatspin.py
Traceback (most recent call last):
  File "floatspin.py", line 1749, in <module>
    frame = MyFrame(None)
  File "floatspin.py", line 1740, in __init__
    increment=0.01, value=0.1, agwStyle=FS_LEFT)
  File "floatspin.py", line 498, in __init__
    self._textctrl.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter)
AttributeError: 'module' object has no attribute 'EVT_TEXT_ENTER'

6) GenericMessageDialog seems to work, but the app still hangs after
closing the dialog (via any button), even though I explicitely call
dlg.Destroy();

7) GradientButton has the same problem as AquaButton, so I believe it
is something related to wx.GCDC/wx.GraphicsContext;

8) HyperTreeList:

E:\Phoenix\wxPython\Phoenix\wx\lib\agw>python hypertreelist.py
Traceback (most recent call last):
  File "hypertreelist.py", line 4884, in <module>
    frame = MyFrame(None)
  File "hypertreelist.py", line 4868, in __init__
    tree_list = HyperTreeList(self)
  File "hypertreelist.py", line 4155, in __init__
    self.SetBuffered(IsBufferingSupported())
  File "hypertreelist.py", line 372, in IsBufferingSupported
    if wx.App.GetComCtl32Version() >= 600:
AttributeError: type object 'App' has no attribute 'GetComCtl32Version'

Commenting out that code I also see:

AttributeError: 'module' object has no attribute 'TR_EXTENDED'

and:

AttributeError: 'module' object has no attribute 'TR_COLUMN_LINES'

After that HyperTreeList appears to be working (with the exception of
GetComCtl32Version).

9) InfoBar depends on wx.aui, but after removing that dependency I get this:

E:\Phoenix\wxPython\Phoenix\wx\lib\agw>python infobar.py
Traceback (most recent call last):
  File "infobar.py", line 866, in <module>
    frame = MyFrame(None)
  File "infobar.py", line 843, in __init__
    self._infoBar = InfoBar(self)
  File "infobar.py", line 349, in __init__
    self.Init()
  File "infobar.py", line 405, in Init
    self._showEffect = wx.SHOW_EFFECT_MAX
AttributeError: 'module' object has no attribute 'SHOW_EFFECT_MAX'

10) LabelBook needs a bunch of XPM Bitmaps, which fail as in FlatNotebook;

11) MultiDirDialog:

E:\Phoenix\wxPython\Phoenix\wx\lib\agw>python multidirdialog.py
Traceback (most recent call last):
  File "multidirdialog.py", line 128, in <module>
    DD_DIR_MUST_EXIST = wx.DD_DIR_MUST_EXIST
AttributeError: 'module' object has no attribute 'DD_DIR_MUST_EXIST'

Same applies to DD_NEW_DIR_BUTTON.

12) PyProgress works, but the application hangs after destroying the
dialog (as all the other dialogs in AGW);

13) ShortcutEditor has too many dependencies on not-yet-ported stuff
in wx.lib to be tested;

14) SpeedMeter works if the dependency on wx.lib.fancytext is removed;

15) XLSGrid depends on wx.grid, so no testing for the moment.

I'll try and concentrate on other wx.lib modules (especially the ones
needed by AGW, such as wx.lib.buttons, wx.lib.fancytext and
wx.lib.embeddedimage) in the next few days. By the way,
wx.lib.embeddedimage is so fundamental (and so NOT working in Python 3
because of the idiotic string/bytes changes) that it would be nice if
some of you could try and make it runnable on both Python versions.

Last comment:

http://trac.wxwidgets.org/changeset/72064

(i.e., phoenix-port and unittest for wx.lib.stattext).

The module doesn't comply with one of the rules spelled out by the
BDFL a few days back:

"A module in wx.lib will not be considered ready (and thus not
included in the Phoenix distribution) if it doesn't have proper
documentation and unittest."

I would say that, documentation-wise, wx.lib.stattext is not ready.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

···

On 10 July 2012 21:50, Robin Dunn wrote:

On 7/10/12 11:56 AM, Andrea Gavana wrote:

I have done some more porting and testing in the last few days while
porting AGW, and there are a few remarks I have written down.

First of all, if anyone cares, this file:

http://xoomer.virgilio.it/infinity77/Zipped/classic_vs_phoenix.txt

Contains a list of the most common wxPython functions, classes and
wx.Window/wx.Sizer methods which need to be changed to a new syntax in
Phoenix; it's a 2-columns, tab-separated file containing the old
wxPython name on the left and the new (if it exists) Phoenix name on
the right. I found it impressively useful while porting AGW to
Phoenix.

Thanks. We should probably find a way to include that information in the migration guide, or perhaps just make it a separate document that is linked to from the migration guide.

Few more comments follow.

General syntax:

1) All modules using wx.Font (not only AGW, also in wx.lib and in all
of your applications):

Old constructors are broken, i.e.:

wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD)

Hmmm... I thought I had made it possible to still use the old flag names, maybe something changed in sip. I'll take another look at that.

2) All modules using wx.Brush and wx.Pen (not only AGW, also in wx.lib
and in all of your applications):

Old constructors are broken, i.e.:

Ditto.

3) The Calc{Scrolled|Unscrolled}Position methods do not accept a
wx.Point or a tuple anymore, they need to be converted to 2 integer
arguments.

I'll add the overloads to the interface headers. I don't see any reason for them to have been removed, so they were probably just forgotten.

Module which seem to work: AdvancedSplash, BalloonTip, ButtonPanel,
CustomTreeCtrl, FoldPanelBar, FourWaySplitter, HyperLinkCtrl,
KnobCtrl, PeakMeter, PieCtrl, PyBusyInfo, PyCollapsiblePane, PyGauge,
RulerCtrl, ShapedButton, SuperToolTip, ThumbnailCtrl, ToasterBox,
UltimateListCtrl, ZoomBar.

1) AquaButton still displays grey, empty rectangles: the OnPaint
method is never called, for some reason (see comment on GradientButton
as well);

2) CubeColourDialog seems to work, but the app still hangs after
closing the dialog (via any button), even though I explicitely call
dlg.Destroy();

I'm not sure what's going on with dialogs, I'll look into that today. I have an idea what it may be. In the cases you are seeing the problem are they dialog-only apps or do they also have one or more frames?

3) FlatMenu has too many dependencies in need to be ported, so no
testing for now;

4) FlatNotebook:
     self._dataobject = wx.CustomDataObject(wx.CustomDataFormat("FlatNotebook"))
AttributeError: 'module' object has no attribute 'CustomDataFormat'

Just use wx.DataFormat instead.

     arrowBmp = wx.Bitmap(left_arrow_xpm)
TypeError: Bitmap(): arguments did not match any overloaded call:

Now, how do we handle XPM data in Phoenix? All the available
constructors seem to reject it, although one of the wxWidgets
constructors has it:

I didn't think anybody was using the XPM constructor... Getting it to work in Classic was kind of a hack and so I hadn't bothered porting it yet. I'll take another look at it.

5) FloatSpin:
AttributeError: 'module' object has no attribute 'EVT_TEXT_ENTER'

Fixed.

6) GenericMessageDialog seems to work, but the app still hangs after
closing the dialog (via any button), even though I explicitely call
dlg.Destroy();

7) GradientButton has the same problem as AquaButton, so I believe it
is something related to wx.GCDC/wx.GraphicsContext;

Can you narrow the problem down at all?

8) HyperTreeList:
AttributeError: type object 'App' has no attribute 'GetComCtl32Version'

ok

Commenting out that code I also see:

AttributeError: 'module' object has no attribute 'TR_EXTENDED'

and:

AttributeError: 'module' object has no attribute 'TR_COLUMN_LINES'

TR_EXTENDED was marked in the source as deprecated so I think that is why it was not included in the interface headers. It looks like TR_COLUMN_LINES came from wx.gizmos.TreeListCtrl and never was part of actual wxWidgets...

After that HyperTreeList appears to be working (with the exception of
GetComCtl32Version).

9) InfoBar depends on wx.aui, but after removing that dependency I get this:
AttributeError: 'module' object has no attribute 'SHOW_EFFECT_MAX'

Fixed.

10) LabelBook needs a bunch of XPM Bitmaps, which fail as in FlatNotebook;

11) MultiDirDialog:

E:\Phoenix\wxPython\Phoenix\wx\lib\agw>python multidirdialog.py
Traceback (most recent call last):
   File "multidirdialog.py", line 128, in <module>
     DD_DIR_MUST_EXIST = wx.DD_DIR_MUST_EXIST
AttributeError: 'module' object has no attribute 'DD_DIR_MUST_EXIST'

Same applies to DD_NEW_DIR_BUTTON.

Fixed, although DD_NEW_DIR_BUTTON is deprecated since that feature is turned on by default now and you should use wxDD_DIR_MUST_EXIST to turn it off.

12) PyProgress works, but the application hangs after destroying the
dialog (as all the other dialogs in AGW);

13) ShortcutEditor has too many dependencies on not-yet-ported stuff
in wx.lib to be tested;

14) SpeedMeter works if the dependency on wx.lib.fancytext is removed;

15) XLSGrid depends on wx.grid, so no testing for the moment.

I'll try and concentrate on other wx.lib modules (especially the ones
needed by AGW, such as wx.lib.buttons, wx.lib.fancytext and
wx.lib.embeddedimage) in the next few days. By the way,
wx.lib.embeddedimage is so fundamental (and so NOT working in Python 3
because of the idiotic string/bytes changes) that it would be nice if
some of you could try and make it runnable on both Python versions.

Last comment:

http://trac.wxwidgets.org/changeset/72064

(i.e., phoenix-port and unittest for wx.lib.stattext).

The module doesn't comply with one of the rules spelled out by the
BDFL a few days back:

"A module in wx.lib will not be considered ready (and thus not
included in the Phoenix distribution) if it doesn't have proper
documentation and unittest."

I would say that, documentation-wise, wx.lib.stattext is not ready.

Agreed. I have some more changes for it in progress in my workspace still to be committed. Oops, I see you beat me to it. (BTW, IIRC that quote is you paraphrasing my statement, and that my wording was a little different. :wink: )

BTW, notice the "Tags:" line I added to the header. I was thinking that this would be a good and easy way to keep track of what has been done to each module. Currently it has "phoenix-port" and "unittest" tags, and I was thinking that there should be 3 more tags, something like "py3-port", "documented" and "approved".

Also, the wiki page on the lib migration says that the unittests for the lib modules should go in a subfolder but I ended up just putting "lib" in the test module name instead (test_lib_stattext.py) and keeping it in the same folder as I didn't feel like wrestling with the unittest module's discover feature and build.py's testOne command at the time. If anybody feels like making those changes so we can easiuly have tests in subfolders feel free to send me a patch. Otherwise we can just use a naming convention.

···

On 7/14/12 9:09 AM, Andrea Gavana wrote:

--
Robin Dunn
Software Craftsman
http://wxPython.org

Robin,

I have done some more porting and testing in the last few days while
porting AGW, and there are a few remarks I have written down.

First of all, if anyone cares, this file:

http://xoomer.virgilio.it/infinity77/Zipped/classic_vs_phoenix.txt

Contains a list of the most common wxPython functions, classes and
wx.Window/wx.Sizer methods which need to be changed to a new syntax in
Phoenix; it's a 2-columns, tab-separated file containing the old
wxPython name on the left and the new (if it exists) Phoenix name on
the right. I found it impressively useful while porting AGW to
Phoenix.

Thanks. We should probably find a way to include that information in the
migration guide, or perhaps just make it a separate document that is linked
to from the migration guide.

I have written down something in here:

http://svn.wxwidgets.org/viewvc/wx/wxPython/Phoenix/trunk/docs/sphinx/rest_substitutions/overviews/classic_vs_phoenix.rst?view=markup

And linked it to the Migration Guide, in the "Overloaded Functions"
paragraph. Please let me know if you would like to see any
modifications to these two documents.

2) CubeColourDialog seems to work, but the app still hangs after
closing the dialog (via any button), even though I explicitely call
dlg.Destroy();

I'm not sure what's going on with dialogs, I'll look into that today. I
have an idea what it may be. In the cases you are seeing the problem are
they dialog-only apps or do they also have one or more frames?

It appears to be with dialogs only. I have no idea if it is a
consequence of creating custom dialogs or not, as I believe the native
dialogs behave properly.

7) GradientButton has the same problem as AquaButton, so I believe it
is something related to wx.GCDC/wx.GraphicsContext;

Can you narrow the problem down at all?

I'll take a look at it tomorrow, although not even the first paint
event is triggered, which is a bit strange...

Last comment:

http://trac.wxwidgets.org/changeset/72064

(i.e., phoenix-port and unittest for wx.lib.stattext).

The module doesn't comply with one of the rules spelled out by the
BDFL a few days back:

"A module in wx.lib will not be considered ready (and thus not
included in the Phoenix distribution) if it doesn't have proper
documentation and unittest."

I would say that, documentation-wise, wx.lib.stattext is not ready.

Agreed. I have some more changes for it in progress in my workspace still
to be committed. Oops, I see you beat me to it. (BTW, IIRC that quote is
you paraphrasing my statement, and that my wording was a little different.
:wink: )

I didn't mean any offence or disrespect; I didn't know about the "Tag"
attribute so I assumed you were failing your own promise on the wx.lib
port :wink: .

BTW, notice the "Tags:" line I added to the header. I was thinking that
this would be a good and easy way to keep track of what has been done to
each module. Currently it has "phoenix-port" and "unittest" tags, and I was
thinking that there should be 3 more tags, something like "py3-port",
"documented" and "approved".

Good idea, it's easy to keep track of what we are doing like that.

Also, the wiki page on the lib migration says that the unittests for the lib
modules should go in a subfolder but I ended up just putting "lib" in the
test module name instead (test_lib_stattext.py) and keeping it in the same
folder as I didn't feel like wrestling with the unittest module's discover
feature and build.py's testOne command at the time. If anybody feels like
making those changes so we can easiuly have tests in subfolders feel free to
send me a patch. Otherwise we can just use a naming convention.

Until now, I have been writing the unittest for AGW using that naming
convention, i.e. test_lib_agw_advancedsplash.py. But I am open to all
suggestions.

···

On 14 July 2012 22:37, Robin Dunn wrote:

On 7/14/12 9:09 AM, Andrea Gavana wrote:

--
Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #