PyAssertionError invalid submenu

i sent this to the list a week ago but it never arrived.
i'm trying again.

hi,

i have a dynamic popup menu in an application. i'm occasionally seeing
exceptions similar to the following in the logfiles. the menus/submenus in
question change each time and there doesn't seem to be any obvious commonality.
the error can happen when adding an ordinary item (1st example) or when adding
a submenu (2nd example). according to the user, when it happens, the popup menu
stops working altogether and is ok again after restarting the application.
needless to say, it all works most of the time. can anyone shed any light on
what i might be doing that makes this happen? what causes a submenu to be invalid?

Exception
Traceback (most recent call last):
  File "lib\app.py", line 209, in decorated
    try: return func(*args, **kwargs)
  File "lib\app.py", line 21290, in OnPopup
    menuitem(submenu, 'Remaining', self.OnRemaining, 'Process any remaining')
  File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 11051, in AppendMenu
    return _core_.Menu_AppendMenu(*args, **kwargs)
PyAssertionError: C++ assertion "submenu->GetHMenu()" failed at ..\..\src\msw\menu.cpp(376) in wxMenu::DoInsertOrAppend(): invalid submenu

Exception
Traceback (most recent call last):
  File "lib\app.py", line 209, in decorated
    try: return func(*args, **kwargs)
  File "lib\app.py", line 21425, in OnPopup
    item = eom_submenu.AppendMenu(id=-1, text='Annual', submenu=a_submenu)
  File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 11051, in AppendMenu
    return _core_.Menu_AppendMenu(*args, **kwargs)
PyAssertionError: C++ assertion "submenu->GetHMenu()" failed at ..\..\src\msw\menu.cpp(376) in wxMenu::DoInsertOrAppend(): invalid submenu

p.s. menuitem() which appears in the 1st example is defined as:

def menuitem(menu, text, func, help='', id=-1):
  '''Append an item to the given menu with the given text, handler
  function, tooltip help text and id.'''
  item = menu.Append(id=id, text=text, help=help)
  app.mainframe.Bind(EVT_MENU, func, item)

i have found someone on the net with the same errors a few
years ago that solved their problem and said:

Client issue - RSW
Postby drwr >> Fri Nov 09, 2007 12:07 pm

I finally fixed this bug! I tracked it down to a leak of Windows
system handles. Turns out that under wxPython, windows and menus
are not reference-counted in the way you would expect, and must be
explicitly Destroyed when they're no longer needed, or they will
leak. When you have eventually leaked all of the available system
handles, bad things start to happen.

is this still the case? do i need to explicitly Destroy() the popup
menu at the end of every single EVT_MENU handler?

cheers,
raf

No, but you do need to do it after the PopupMenu() function call returns, unless you are going to reuse the menu instead of recreating it the next time a popup is needed.

  menu = wx.Menu()
  menu.Append(...)
  ...
  self.PopupMenu(menu)
  menu.Destroy()

···

On 2/14/11 9:39 PM, raf wrote:

i sent this to the list a week ago but it never arrived.
i'm trying again.

hi,

i have a dynamic popup menu in an application. i'm occasionally seeing
exceptions similar to the following in the logfiles. the menus/submenus in
question change each time and there doesn't seem to be any obvious commonality.
the error can happen when adding an ordinary item (1st example) or when adding
a submenu (2nd example). according to the user, when it happens, the popup menu
stops working altogether and is ok again after restarting the application.
needless to say, it all works most of the time. can anyone shed any light on
what i might be doing that makes this happen? what causes a submenu to be invalid?

Exception
Traceback (most recent call last):
   File "lib\app.py", line 209, in decorated
     try: return func(*args, **kwargs)
   File "lib\app.py", line 21290, in OnPopup
     menuitem(submenu, 'Remaining', self.OnRemaining, 'Process any remaining')
   File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 11051, in AppendMenu
     return _core_.Menu_AppendMenu(*args, **kwargs)
PyAssertionError: C++ assertion "submenu->GetHMenu()" failed at ..\..\src\msw\menu.cpp(376) in wxMenu::DoInsertOrAppend(): invalid submenu

Exception
Traceback (most recent call last):
   File "lib\app.py", line 209, in decorated
     try: return func(*args, **kwargs)
   File "lib\app.py", line 21425, in OnPopup
     item = eom_submenu.AppendMenu(id=-1, text='Annual', submenu=a_submenu)
   File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 11051, in AppendMenu
     return _core_.Menu_AppendMenu(*args, **kwargs)
PyAssertionError: C++ assertion "submenu->GetHMenu()" failed at ..\..\src\msw\menu.cpp(376) in wxMenu::DoInsertOrAppend(): invalid submenu

p.s. menuitem() which appears in the 1st example is defined as:

def menuitem(menu, text, func, help='', id=-1):
  '''Append an item to the given menu with the given text, handler
  function, tooltip help text and id.'''
  item = menu.Append(id=id, text=text, help=help)
  app.mainframe.Bind(EVT_MENU, func, item)

i have found someone on the net with the same errors a few
years ago that solved their problem and said:

http://rswgame.com/forum/viewtopic.php?f=1&t=35
Postby drwr>> Fri Nov 09, 2007 12:07 pm

I finally fixed this bug! I tracked it down to a leak of Windows
system handles. Turns out that under wxPython, windows and menus
are not reference-counted in the way you would expect, and must be
explicitly Destroyed when they're no longer needed, or they will
leak. When you have eventually leaked all of the available system
handles, bad things start to happen.

is this still the case? do i need to explicitly Destroy() the popup
menu at the end of every single EVT_MENU handler?

--
Robin Dunn
Software Craftsman

Robin Dunn wrote:

···

On 2/14/11 9:39 PM, raf wrote:
>hi,
>
>i have a dynamic popup menu in an application. i'm occasionally
>seeing exceptions similar to the following in the logfiles. the
>menus/submenus in question change each time and there doesn't seem
>to be any obvious commonality. the error can happen when adding an
>ordinary item (1st example) or when adding a submenu (2nd example).
>according to the user, when it happens, the popup menu stops working
>altogether and is ok again after restarting the application. needless
>to say, it all works most of the time. can anyone shed any light on
>what i might be doing that makes this happen? what causes a submenu
>to be invalid?
>
>PyAssertionError: C++ assertion "submenu->GetHMenu()" failed at
>..\..\src\msw\menu.cpp(376) in wxMenu::DoInsertOrAppend(): invalid submenu
>
>PyAssertionError: C++ assertion "submenu->GetHMenu()" failed at
>..\..\src\msw\menu.cpp(376) in wxMenu::DoInsertOrAppend(): invalid submenu
>
>i have found someone on the net with the same errors a few
>years ago that solved their problem and said:
>
>>http://rswgame.com/forum/viewtopic.php?f=1&t=35
>>Postby drwr>> Fri Nov 09, 2007 12:07 pm
>>
>>I finally fixed this bug! I tracked it down to a leak of Windows
>>system handles. Turns out that under wxPython, windows and menus
>>are not reference-counted in the way you would expect, and must be
>>explicitly Destroyed when they're no longer needed, or they will
>>leak. When you have eventually leaked all of the available system
>>handles, bad things start to happen.
>
>is this still the case? do i need to explicitly Destroy() the popup
>menu at the end of every single EVT_MENU handler?

No, but you do need to do it after the PopupMenu() function call
returns, unless you are going to reuse the menu instead of recreating it
the next time a popup is needed.

  menu = wx.Menu()
  menu.Append(...)
  menu.Append(...)
  ...
  self.PopupMenu(menu)
  menu.Destroy()

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

thanks robin. that's great to know.

cheers,
raf