From d453e92a73afce7402d96bb04e0237f6e6800bf8 Mon Sep 17 00:00:00 2001
From: Robin Dunn <robin@alldunn.com>
Date: Wed, 26 Feb 2020 11:10:27 -0800
Subject: [PATCH] Add __index__ to wx.WindowID, and __bool__ to wx.Region
(cherry picked from commit 9096426603272672d9a676e8bcdcadf0a1cfa1a2)
---
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()
+
+
#---------------------------------------------------------------------------