From 9096426603272672d9a676e8bcdcadf0a1cfa1a2 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 26 Feb 2020 11:10:27 -0800 Subject: [PATCH] Add __index__ to wx.WindowID, and __bool__ to wx.Region --- etg/region.py | 5 +++-- etg/windowid.py | 32 +++++++++++++++++--------------- unittests/test_windowid.py | 23 +++++++++++++++++++++-- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/etg/region.py b/etg/region.py index 0982c1fe5..d5bc45759 100644 --- a/etg/region.py +++ b/etg/region.py @@ -88,11 +88,12 @@ def next(self): c.mustHaveApp() c.find('operator++').ignore() - # SIP maps operator bool() to __int__, but Classic used __nonzero__. Does - # it make any difference either way? c.find('operator bool').ignore() c.addCppMethod('int', '__nonzero__', '()', 'return (int)self->operator bool();', 'Returns true while there are still rectangles available in the iteration.') + c.addCppMethod('int', '__bool__', '()', 'return (int)self->operator bool();', + 'Returns true while there are still rectangles available in the iteration.') + c.addCppMethod('void', 'Next', '()', 'self->operator++();', 'Move the iterator to the next rectangle in the region.') diff --git a/etg/windowid.py b/etg/windowid.py index 27b041b3d..da2ed395e 100644 --- a/etg/windowid.py +++ b/etg/windowid.py @@ -53,12 +53,12 @@ def run(): MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True, briefDoc='Create reference from an ID', items=[ ParamDef(type='int', name='id') ]), - + MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True, briefDoc='Copy an ID reference', items=[ ParamDef(type='const wxWindowIDRef&', name='idref') ]), ]), - + MethodDef(name='~wxWindowIDRef', className='wxWindowIDRef', isDtor=True), MethodDef(type='int', name='GetValue', @@ -73,11 +73,13 @@ def run(): """) klass.addCppMethod('int', '__int__', '()', - doc="Alias for GetValue allowing the IDRef to be passed as the WindowID parameter when creating widgets or etc.", - body="""\ - return self->GetValue(); - """) - + doc="Alias for GetValue allowing the IDRef to be passed as the WindowID parameter when creating widgets or other places an integer type is needed.", + body="return self->GetValue();") + klass.addCppMethod('int', '__index__', '()', + doc="See :meth:`__int__`", + body="return self->GetValue();") + + klass.addCppMethod('bool', '__eq__', '(wxWindowID id)', "return self->GetValue() == id;") klass.addCppMethod('bool', '__ne__', '(wxWindowID id)', "return self->GetValue() != id;") klass.addCppMethod('bool', '__lt__', '(wxWindowID id)', "return self->GetValue() < id;") @@ -92,17 +94,17 @@ def run(): # and finish it up by adding it to the module module.addItem(klass) - # Now, let's add a new Python function to the global scope that reserves an - # ID (or range) and returns a ref object for it. - module.addPyFunction('NewIdRef', '(count=1)', + # Now, let's add a new Python function to the global scope that reserves an + # ID (or range) and returns a ref object for it. + module.addPyFunction('NewIdRef', '(count=1)', doc="""\ - Reserves a new Window ID (or range of WindowIDs) and returns a - :class:`wx.WindowIDRef` object (or list of them) that will help + Reserves a new Window ID (or range of WindowIDs) and returns a + :class:`wx.WindowIDRef` object (or list of them) that will help manage the reservation of that ID. - This function is intended to be a drop-in replacement of the old - and deprecated :func:`wx.NewId` function, with the added benefit - that the ID should never conflict with an in-use ID or other IDs + This function is intended to be a drop-in replacement of the old + and deprecated :func:`wx.NewId` function, with the added benefit + that the ID should never conflict with an in-use ID or other IDs generated by this function. """, body="""\ diff --git a/unittests/test_windowid.py b/unittests/test_windowid.py index 4593e5a69..fc36c9eb8 100644 --- a/unittests/test_windowid.py +++ b/unittests/test_windowid.py @@ -31,9 +31,9 @@ def test_newIdRef02(self): def test_newIdRef03(self): """Check that Auto ID Management is enabled (--enable-autoidman)""" # This test is expected to fail if autoID mangagement is turned on - # because a reference to the ID is not being saved, so it will be + # because a reference to the ID is not being saved, so it will be # unreserved when the first widget is destroyed. - + id = wx.Window.NewControlId() b = wx.Button(self.frame, id, 'button') b.Destroy() @@ -75,6 +75,7 @@ def test_WindowIDRef01(self): val = ref1 <= ref2 assert type(val) == bool + def test_WindowIDRef02(self): d = {wx.NewIdRef(): 'one', wx.NewIdRef(): 'two'} @@ -82,6 +83,24 @@ def test_WindowIDRef02(self): for k in keys: val = d[k] + + def test_WindowIDRef03(self): + # Ensure wx.WindowIDRef can be converted to int without warning when + # making a call to warrped method. In Py3.8+ this means there needs to + # be an __index__ method. + + # Turn warnings into exceptions so this test will fail if there is + # a warning + import warnings + warnings.simplefilter('error') + + wid = wx.NewIdRef() + assert isinstance(wid, wx.WindowIDRef) + + b = wx.Button(self.frame, wid, 'button') + assert b.GetId() == wid.GetId() + + #---------------------------------------------------------------------------