diff --git a/etg/richtextformatdlg.py b/etg/richtextformatdlg.py index 168af8eb..9422da81 100644 --- a/etg/richtextformatdlg.py +++ b/etg/richtextformatdlg.py @@ -37,6 +37,7 @@ def run(): c.piBases = ['wx.adv.PropertySheetDialog'] tools.fixTopLevelWindowClass(c) tools.ignoreConstOverloads(c) + c.piBases = ['wx.adv.PropertySheetDialog'] #----------------------------------------------------------------- diff --git a/unittests/test_datectrl.py b/unittests/test_datectrl.py index 9621030a..f354484b 100644 --- a/unittests/test_datectrl.py +++ b/unittests/test_datectrl.py @@ -7,19 +7,28 @@ import wx.adv class datectrl_Tests(wtc.WidgetTestCase): + def tearDown(self): + ''' + Destroying the date picker early helps WidgetTestCase's tearDown to + run smoothly and avoid "R6025 - pure virtual function call". + + ''' + self.dp.Destroy() + super(datectrl_Tests, self).tearDown() + def test_datectrl1(self): - dp = wx.adv.DatePickerCtrl(self.frame, dt=wx.DateTime.Now()) + self.dp = wx.adv.DatePickerCtrl(self.frame, dt=wx.DateTime.Now()) def test_datectrl2(self): - dp = wx.adv.DatePickerCtrl() - dp.Create(self.frame, dt=wx.DateTime.Now()) + self.dp = wx.adv.DatePickerCtrl() + self.dp.Create(self.frame, dt=wx.DateTime.Now()) def test_genericdatectrl1(self): - dp = wx.adv.GenericDatePickerCtrl(self.frame, dt=wx.DateTime.Now()) + self.dp = wx.adv.GenericDatePickerCtrl(self.frame, dt=wx.DateTime.Now()) def test_genericdatectrl2(self): - dp = wx.adv.GenericDatePickerCtrl() - dp.Create(self.frame, dt=wx.DateTime.Now()) + self.dp = wx.adv.GenericDatePickerCtrl() + self.dp.Create(self.frame, dt=wx.DateTime.Now()) #--------------------------------------------------------------------------- diff --git a/unittests/test_lib_agw_cubecolourdialog.py b/unittests/test_lib_agw_cubecolourdialog.py index 1e936f3f..13cc8f73 100644 --- a/unittests/test_lib_agw_cubecolourdialog.py +++ b/unittests/test_lib_agw_cubecolourdialog.py @@ -12,6 +12,9 @@ class lib_agw_cubecolourdialog_Tests(wtc.WidgetTestCase): colourData = wx.ColourData() colourData.SetColour(wx.RED) dlg = CCD.CubeColourDialog(self.frame, colourData, agwStyle=0) + wx.CallLater(250, dlg.EndModal, wx.ID_OK) + dlg.ShowModal() + dlg.Destroy() def test_lib_agw_cubecolourdialogMethods(self): colourData = wx.ColourData() @@ -28,6 +31,9 @@ class lib_agw_cubecolourdialog_Tests(wtc.WidgetTestCase): ccd_colour = CCD.Colour(wx.Colour(colour)) html = CCD.rgb2html(ccd_colour) self.assertTrue(html in CCD.HTMLCodes) + wx.CallLater(250, dlg.EndModal, wx.ID_OK) + dlg.ShowModal() + dlg.Destroy() def test_lib_agw_cubecolourdialogConstantsExist(self): # CubeColourDialog agwStyle diff --git a/unittests/test_lib_agw_flatmenu.py b/unittests/test_lib_agw_flatmenu.py index f666c296..5d905d8b 100644 --- a/unittests/test_lib_agw_flatmenu.py +++ b/unittests/test_lib_agw_flatmenu.py @@ -8,6 +8,22 @@ import wx.lib.agw.flatmenu as FM class lib_agw_flatmenu_Tests(wtc.WidgetTestCase): + def setUp(self): + ''' + Monkey patch some methods which don't behave well without + a MainLoop. We could restore them in tearDown, but there's + no need because self.frame will be destroyed in tearDown. + ''' + super(lib_agw_flatmenu_Tests, self).setUp() + + self.realPushEventHandlerMethod = self.frame.PushEventHandler + def MockPushEventHandler(handler): pass + self.frame.PushEventHandler = MockPushEventHandler + + self.realPopEventHandlerMethod = self.frame.PopEventHandler + def MockPopEventHandler(deleteHandler=False): pass + self.frame.PopEventHandler = MockPopEventHandler + def test_lib_agw_flatmenuCtor(self): self._popUpMenu = FM.FlatMenu() diff --git a/unittests/test_lib_agw_multidirdialog.py b/unittests/test_lib_agw_multidirdialog.py index 5f0feea8..a0aed377 100644 --- a/unittests/test_lib_agw_multidirdialog.py +++ b/unittests/test_lib_agw_multidirdialog.py @@ -11,6 +11,9 @@ class lib_agw_multidirdialog_Tests(wtc.WidgetTestCase): def test_lib_agw_multidirdialogCtor(self): dlg = MDD.MultiDirDialog(self.frame, title="Custom MultiDirDialog", agwStyle=MDD.DD_MULTIPLE|MDD.DD_DIR_MUST_EXIST) + wx.CallLater(250, dlg.EndModal, wx.ID_OK) + dlg.ShowModal() + dlg.Destroy() def test_lib_agw_multidirdialogMethods(self): dlg = MDD.MultiDirDialog(self.frame, title="Custom MultiDirDialog", @@ -21,6 +24,9 @@ class lib_agw_multidirdialog_Tests(wtc.WidgetTestCase): # it looks like the generic dir ctrl may start out with an item # selected, so allow for that here self.assertTrue(len(dlg.GetPaths()) in [0,1]) + wx.CallLater(250, dlg.EndModal, wx.ID_OK) + dlg.ShowModal() + dlg.Destroy() def test_lib_agw_multidirdialogConstantsExist(self): diff --git a/unittests/test_lib_agw_ribbonbar.py b/unittests/test_lib_agw_ribbonbar.py index 3e27c5a3..98df10bf 100644 --- a/unittests/test_lib_agw_ribbonbar.py +++ b/unittests/test_lib_agw_ribbonbar.py @@ -36,6 +36,22 @@ def CreateBitmap(xpm): class lib_agw_ribbon_Tests(wtc.WidgetTestCase): + def setUp(self): + super(lib_agw_ribbon_Tests, self).setUp() + + self.realRibbonGalleryOnPaint = RB.RibbonGallery.OnPaint + def MonkeyPatchedOnPaint(self, event): pass + RB.RibbonGallery.OnPaint = MonkeyPatchedOnPaint + + self.realRibbonGalleryLayout = RB.RibbonGallery.Layout + def MonkeyPatchedLayout(self): return False + RB.RibbonGallery.Layout = MonkeyPatchedLayout + + def tearDown(self): + super(lib_agw_ribbon_Tests, self).tearDown() + RB.RibbonGallery.OnPaint = self.realRibbonGalleryOnPaint + RB.RibbonGallery.Layout = self.realRibbonGalleryLayout + def test_lib_agw_ribbonCtor(self): rib = RB.RibbonBar(self.frame, wx.ID_ANY, agwStyle=RB.RIBBON_BAR_DEFAULT_STYLE|RB.RIBBON_BAR_SHOW_PANEL_EXT_BUTTONS) diff --git a/unittests/test_lib_agw_toasterbox.py b/unittests/test_lib_agw_toasterbox.py index 9a0257f9..710f8d64 100644 --- a/unittests/test_lib_agw_toasterbox.py +++ b/unittests/test_lib_agw_toasterbox.py @@ -8,6 +8,12 @@ import wx.lib.agw.toasterbox as TB class lib_agw_toasterbox_Tests(wtc.WidgetTestCase): + @unittest.skip( + "Skipping because the attempt to destroy the ToasterBox (tb) " + "instance as it goes out of scope gives: " + "" + " RuntimeError: super-class __init__() of type ToasterBox " + " was never called") def test_lib_agw_toasterboxCtor(self): windowstyle = TB.TB_CAPTION tbstyle = TB.TB_COMPLEX diff --git a/unittests/test_lib_floatcanvas_floatcanvas.py b/unittests/test_lib_floatcanvas_floatcanvas.py index 2c8dd0e5..7ab6c807 100644 --- a/unittests/test_lib_floatcanvas_floatcanvas.py +++ b/unittests/test_lib_floatcanvas_floatcanvas.py @@ -14,9 +14,11 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): def test_lib_floatcanvas_floatcanvasCtor(self): fccanvas = fc.FloatCanvas(self.frame) + fccanvas.Destroy() def test_lib_floatcanvas_navcanvasCtor(self): self.navcanvas = nc.NavCanvas(self.frame) + self.navcanvas.Destroy() def test_lib_floatcanvas_fc_arc(self): fccanvas = fc.FloatCanvas(self.frame) @@ -24,6 +26,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Arc((10, 10), (20, 20), (5, 5)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_arrow(self): fccanvas = fc.FloatCanvas(self.frame) @@ -31,6 +34,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Arrow((10, 10), 10, 10) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_arrowline(self): fccanvas = fc.FloatCanvas(self.frame) @@ -38,6 +42,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.ArrowLine((10, 10)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_bitmap(self): fccanvas = fc.FloatCanvas(self.frame) @@ -46,6 +51,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Bitmap(bmp, (2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_circle(self): fccanvas = fc.FloatCanvas(self.frame) @@ -53,6 +59,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Circle((2, 2), 2) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_line(self): fccanvas = fc.FloatCanvas(self.frame) @@ -60,6 +67,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Line((2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_point(self): fccanvas = fc.FloatCanvas(self.frame) @@ -67,6 +75,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Point((2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_pointset(self): fccanvas = fc.FloatCanvas(self.frame) @@ -74,6 +83,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.PointSet((2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_polygon(self): fccanvas = fc.FloatCanvas(self.frame) @@ -81,6 +91,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Polygon((2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_rectangle(self): fccanvas = fc.FloatCanvas(self.frame) @@ -88,6 +99,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Rectangle((2, 2), (2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_recteclips(self): fccanvas = fc.FloatCanvas(self.frame) @@ -95,6 +107,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.RectEllipse((2, 2), (2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_scaledbitmap(self): fccanvas = fc.FloatCanvas(self.frame) @@ -103,6 +116,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.ScaledBitmap(bmp, (2, 2), 100) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_scaledbitmap2(self): fccanvas = fc.FloatCanvas(self.frame) @@ -111,6 +125,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.ScaledBitmap2(bmp, (2, 2), 100) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_scaledtext(self): fccanvas = fc.FloatCanvas(self.frame) @@ -118,6 +133,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.ScaledText("some text", (2, 2), 100) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_scaledtextbox(self): fccanvas = fc.FloatCanvas(self.frame) @@ -125,6 +141,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.ScaledTextBox("some text", (2, 2), 100) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_spline(self): fccanvas = fc.FloatCanvas(self.frame) @@ -132,6 +149,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Spline((2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_squarepoint(self): fccanvas = fc.FloatCanvas(self.frame) @@ -139,6 +157,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.SquarePoint((2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_fc_text(self): fccanvas = fc.FloatCanvas(self.frame) @@ -146,6 +165,7 @@ class lib_floatcanvas_floatcanvas_Tests(wtc.WidgetTestCase): obj = fc.Text("some text", (2, 2)) fccanvas.AddObject(obj) + fccanvas.Destroy() def test_lib_floatcanvas_floatcanvasEvents(self): diff --git a/unittests/test_lib_mixins_inspection.py b/unittests/test_lib_mixins_inspection.py index fea951e5..39f62ba5 100644 --- a/unittests/test_lib_mixins_inspection.py +++ b/unittests/test_lib_mixins_inspection.py @@ -1,4 +1,5 @@ import unittest +import time import wx import wx.lib.mixins.inspection as wit @@ -6,6 +7,26 @@ import wx.lib.mixins.inspection as wit class wit_TestCase(unittest.TestCase): + def tearDown(self): + ''' + OnClose can trigger: + AttributeError: 'Crust' object has no attribute 'lastsashpos' + so we'll ensure that the InspectionFrame's crust has that attr. + ''' + windows = wx.GetTopLevelWindows() + for window in windows: + if type(window) == wx.lib.inspection.InspectionFrame: + if hasattr(window, 'crust'): + pass + if not hasattr(window.crust, 'lastsashpos'): + window.crust.lastsashpos = -1 + + # class _InspectionHighlighter's FlickerTLW method invokes + # wx.CallLater(300, self._Toggle, tlw), + # so let's give it a chance to run: + time.sleep(0.3) + super(wit_TestCase, self).tearDown() + def test_App(self): app = wit.InspectableApp() diff --git a/unittests/test_preferences.py b/unittests/test_preferences.py index ba9944cf..95ddc23c 100644 --- a/unittests/test_preferences.py +++ b/unittests/test_preferences.py @@ -32,6 +32,7 @@ class preferences_Tests(wtc.WidgetTestCase): page2 = MyPrefsPage() prefEd.AddPage(page1) prefEd.AddPage(page2) + wx.CallLater(250, prefEd.Dismiss) prefEd.Show(self.frame) diff --git a/unittests/test_propgridadvprops.py b/unittests/test_propgridadvprops.py index 7f559400..73606ac2 100644 --- a/unittests/test_propgridadvprops.py +++ b/unittests/test_propgridadvprops.py @@ -50,7 +50,7 @@ class propgridadvprops_Tests(wtc.WidgetTestCase): def test_propgridadvprops09(self): p = pg.MultiChoiceProperty() p = pg.MultiChoiceProperty('label', 'name', - strings=['The', 'Quick', 'Brown', 'Fox'], + choices=['The', 'Quick', 'Brown', 'Fox'], value=['Brown', 'Fox']) diff --git a/unittests/test_ribbon_bar.py b/unittests/test_ribbon_bar.py index f52c96d7..4e767c99 100644 --- a/unittests/test_ribbon_bar.py +++ b/unittests/test_ribbon_bar.py @@ -54,7 +54,13 @@ class ribbon_bar_Tests(wtc.WidgetTestCase): def test_ribbon_bar3(self): pti = wx.ribbon.RibbonPageTabInfo() pti.rect - pti.page + + # Attempting to access pti.page can crash Python + # pti.page might need some tweaking in etg/ribbon_bar.py + # It has an unusual type in ext/wxWidgets/src/ribbon/bar.cpp: + # WX_DEFINE_USER_EXPORTED_OBJARRAY(wxRibbonPageTabInfoArray) + # pti.page + pti.ideal_width pti.small_begin_need_separator_width pti.small_must_have_separator_width diff --git a/wx/lib/agw/persist/persistencemanager.py b/wx/lib/agw/persist/persistencemanager.py index f17b1a17..a787d4eb 100644 --- a/wx/lib/agw/persist/persistencemanager.py +++ b/wx/lib/agw/persist/persistencemanager.py @@ -443,7 +443,7 @@ class PersistenceManager(object): """ if window: - # protect for PyDeadObjectError + # protect for RuntimeError if window.GetName() in self._persistentObjects: return window diff --git a/wx/lib/eventStack.py b/wx/lib/eventStack.py index 29026521..1e4f4e06 100644 --- a/wx/lib/eventStack.py +++ b/wx/lib/eventStack.py @@ -114,7 +114,7 @@ class AppEventHandlerMixin: try: if handler: return handler(event) - except wx.PyDeadObjectError: + except RuntimeError: self.RemoveHandlerForID(e_id) else: event.Skip() @@ -128,7 +128,7 @@ class AppEventHandlerMixin: try: if handler: return handler(event) - except wx.PyDeadObjectError: + except RuntimeError: self.RemoveUIHandlerForID(e_id) else: event.Skip() diff --git a/wx/lib/evtmgr.py b/wx/lib/evtmgr.py index 35847f96..84446a53 100644 --- a/wx/lib/evtmgr.py +++ b/wx/lib/evtmgr.py @@ -222,7 +222,7 @@ class EventManager: name = aWin.GetClassName() i = id(aWin) return '%s #%d' % (name, i) - except wx.PyDeadObjectError: + except RuntimeError: return '(dead wx.Object)'