Add a GetIM() method to Colour, Point, Size, Rect and other ‘value’ types.

GetIM() returns a replicant of the original object that is immutable, so it can be used as a dictionary key, or etc., but still gives access to the properties by name, which using the Get() method to get a tuple of the values does not do.
This commit is contained in:
Robin Dunn
2017-04-14 19:19:26 -07:00
parent a79cd3254c
commit 52facb4d7f
15 changed files with 194 additions and 0 deletions

View File

@@ -163,6 +163,8 @@ def run():
briefDoc="""\
Returns the RGB intensity values as a tuple, optionally the alpha value as well.""")
tools.addGetIMMethodTemplate(module, c, ['red', 'green', 'blue', 'alpha'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')

View File

@@ -51,6 +51,9 @@ def run():
""",
briefDoc="Set both the row and column properties.")
tools.addGetIMMethodTemplate(module, c, ['row', 'col'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "wx.GBPosition"+str(self.Get())')
@@ -92,6 +95,8 @@ def run():
""",
briefDoc="Set both the rowspan and colspan properties.")
tools.addGetIMMethodTemplate(module, c, ['rowspan', 'colspan'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "wx.GBSpan"+str(self.Get())')

View File

@@ -109,6 +109,9 @@ def run():
pyArgsString="() -> (x,y)",
briefDoc="Return the x and y properties as a tuple.")
tools.addGetIMMethodTemplate(module, c, ['x', 'y'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "wx.Point"+str(self.Get())')
@@ -180,6 +183,8 @@ def run():
pyArgsString="() -> (width, height)",
briefDoc="Return the width and height properties as a tuple.")
tools.addGetIMMethodTemplate(module, c, ['width', 'height'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "wx.Size"+str(self.Get())')
@@ -258,6 +263,8 @@ def run():
pyArgsString="() -> (x, y, width, height)",
briefDoc="Return the rectangle's properties as a tuple.")
tools.addGetIMMethodTemplate(module, c, ['x', 'y', 'width', 'height'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "wx.Rect"+str(self.Get())')
@@ -310,6 +317,8 @@ def run():
pyArgsString="() -> (x, y)",
briefDoc="Return the point's properties as a tuple.")
tools.addGetIMMethodTemplate(module, c, ['x', 'y'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "wx.RealPoint"+str(self.Get())')

View File

@@ -65,6 +65,8 @@ def run():
Get() -> (x,y)\n
Return the x and y properties as a tuple.""")
tools.addGetIMMethodTemplate(module, c, ['x', 'y'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "wx.Point2D"+str(self.Get())')
@@ -110,6 +112,8 @@ def run():
Get() -> (x, y, width, height)\n
Return the rectangle's properties as a tuple.""")
tools.addGetIMMethodTemplate(module, c, ['x', 'y', 'width', 'height'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "wx.Rect2D"+str(self.Get())')

View File

@@ -103,6 +103,8 @@ def run():
pyArgsString="() -> (row,col)",
briefDoc="Return the row and col properties as a tuple.")
tools.addGetIMMethodTemplate(module, c, ['Row', 'Col'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "GridCellCoords"+str(self.Get())')

View File

@@ -42,6 +42,8 @@ def run():
pyArgsString="() -> (row,col)",
briefDoc="Return the row and col properties as a tuple.")
tools.addGetIMMethodTemplate(module, c, ['Row', 'Col'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "wx.Position"+str(self.Get())')

View File

@@ -171,6 +171,8 @@ def run():
pyArgsString="() -> (start, end)",
briefDoc="Return the start and end properties as a tuple.")
tools.addGetIMMethodTemplate(module, c, ['Start', 'End'])
# Add sequence protocol methods and other goodies
c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
c.addPyMethod('__repr__', '(self)', 'return "RichTextRange"+str(self.Get())')

View File

@@ -616,6 +616,33 @@ def checkForUnitTestModule(module):
#---------------------------------------------------------------------------
def addGetIMMethodTemplate(module, klass, fields):
"""
Add a bit of code to the module, and add a GetIM method to the klass which
returns an immutable representation self.
"""
name = klass.pyName or klass.name
if name.startswith('wx'):
name = name[2:]
module.addPyCode("""\
from collections import namedtuple
_im_{name} = namedtuple('_im_{name}', {fields})
del namedtuple
""".format(name=name, fields=str(fields)))
klass.addPyMethod('GetIM', '(self)',
doc="""\
Returns an immutable representation of the ``wx.{name}`` object, based on ``namedtuple``.
This new object is hashable and can be used as a dictionary key,
be added to sets, etc. It can be converted back into a real ``wx.{name}``
with a simple statement like this: ``obj = wx.{name}(imObj)``.
""".format(name=name),
body="return _im_{name}(*self.Get())".format(name=name)
)
#---------------------------------------------------------------------------
def convertTwoIntegersTemplate(CLASS):
# Note: The GIL is already acquired where this code is used.

View File

@@ -42,6 +42,19 @@ class Colour(wtc.WidgetTestCase):
p = wx.Colour(wx.Rect(1,2,3,4))
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.Colour(1,2,3,4)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.red == obj.red
assert im.green == obj.green
assert im.blue == obj.blue
assert im.alpha == obj.alpha
obj2 = wx.Colour(im)
assert obj == obj2
if hasattr(wx, 'testColourTypeMap'):
def test_ColourTypemaps(self):
c = wx.testColourTypeMap('red')

View File

@@ -106,6 +106,29 @@ class gbsizer_Tests(wtc.WidgetTestCase):
self.assertTrue(items[2].IsSpacer())
self.assertTrue(items[0].Border == 5)
def test_GetIM_position(self):
# Test the immutable version returned by GetIM
obj = wx.GBPosition(1,2)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.row == obj.row
assert im.col == obj.col
obj2 = wx.GBPosition(im)
assert obj == obj2
def test_GetIM_span(self):
# Test the immutable version returned by GetIM
obj = wx.GBSpan(1,2)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.rowspan == obj.rowspan
assert im.colspan == obj.colspan
obj2 = wx.GBSpan(im)
assert obj == obj2
#---------------------------------------------------------------------------

View File

@@ -117,6 +117,17 @@ class Point(unittest.TestCase):
self.assertEqual(p6, (-4,-6))
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.Point(1,2)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.x == obj.x
assert im.y == obj.y
obj2 = wx.Point(im)
assert obj == obj2
def test_converters(self):
# Ensure that other types that are sequence-like can't be
# auto-converted, the copy constructor is good-enough for testing this
@@ -241,6 +252,17 @@ class Size(unittest.TestCase):
s[2]
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.Size(1,2)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.width == obj.width
assert im.height == obj.height
obj2 = wx.Size(im)
assert obj == obj2
def test_converters(self):
# Ensure that other types that are sequence-like can't be
# auto-converted, the copy constructor is good-enough for testing this
@@ -273,6 +295,18 @@ class RealPoint(unittest.TestCase):
p.y += 2
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.RealPoint(1,2)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.x == obj.x
assert im.y == obj.y
obj2 = wx.RealPoint(im)
assert obj == obj2
#---------------------------------------------------------------------------
@@ -312,6 +346,19 @@ class Rect(unittest.TestCase):
self.assertTrue(r.x == 0 and r.y == 0)
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.Rect(1,2,3,4)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.x == obj.x
assert im.y == obj.y
assert im.width == obj.width
assert im.height == obj.height
obj2 = wx.Rect(im)
assert obj == obj2
def test_converters(self):
# Ensure that other types that are sequence-like can't be
# auto-converted, the copy constructor is good-enough for testing this

View File

@@ -20,6 +20,16 @@ class Point2D(unittest.TestCase):
self.assertTrue(p1 == (1.23, 4.56))
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.Point2D(1.23,2.34)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.x == obj.x
assert im.y == obj.y
obj2 = wx.Point2D(im)
assert obj == obj2
class Rect2D(unittest.TestCase):
@@ -36,6 +46,19 @@ class Rect2D(unittest.TestCase):
self.assertTrue(r1 is not r2)
self.assertTrue(r1 == (.5, .5, 100.1, 99.2))
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.Rect2D(1.5, 2.5, 3.5, 4.5)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.x == obj.x
assert im.y == obj.y
assert im.width == obj.width
assert im.height == obj.height
obj2 = wx.Rect2D(im)
assert obj == obj2
#---------------------------------------------------------------------------

View File

@@ -303,6 +303,17 @@ class grid_Tests(wtc.WidgetTestCase):
wx.grid.Grid.SetCellHighlightPenWidth # Does it exist
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.grid.GridCellCoords(1,2)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.Row == obj.Row
assert im.Col == obj.Col
obj2 = wx.grid.GridCellCoords(im)
assert obj == obj2
#---------------------------------------------------------------------------
if __name__ == '__main__':

View File

@@ -48,6 +48,19 @@ class position_Tests(wtc.WidgetTestCase):
self.assertTrue(p4 == p1)
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.Position(1,2)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.Row == obj.Row
assert im.Col == obj.Col
obj2 = wx.Position(im)
assert obj == obj2
#---------------------------------------------------------------------------

View File

@@ -287,6 +287,17 @@ class richtextbuffer_Tests(wtc.WidgetTestCase):
def test_GetIM(self):
# Test the immutable version returned by GetIM
obj = wx.richtext.RichTextRange(1,2)
im = obj.GetIM()
assert isinstance(im, tuple)
assert im.Start == obj.Start
assert im.End == obj.End
obj2 = wx.richtext.RichTextRange(im)
assert obj == obj2