From 175a4c4305dc15e0031711b5f6c9d2cb3cc597d7 Mon Sep 17 00:00:00 2001 From: David Gobbi <david.gobbi@gmail.com> Date: Sat, 22 Aug 2015 23:37:39 -0600 Subject: [PATCH] Make vtkVariantStrictWeakOrder(a,b) work with Py3k. For Python 2, this method operated like the cmp(a,b) method. In Python 3, there is no cmp(a,b) method, so instead this method now returns (a < b) like the original C++ method. --- Common/Core/Testing/Python/TestVariant.py | 21 +++++-- Wrapping/Python/vtk/util/vtkVariant.py | 68 ++++++++++++++++++----- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/Common/Core/Testing/Python/TestVariant.py b/Common/Core/Testing/Python/TestVariant.py index 5bce363292b..260ccccee08 100644 --- a/Common/Core/Testing/Python/TestVariant.py +++ b/Common/Core/Testing/Python/TestVariant.py @@ -18,7 +18,7 @@ import sys import vtk from vtk.test import Testing -if sys.hexversion > 0x03000000: +if sys.hexversion >= 0x03000000: cedilla = 'Fran\xe7ois' else: cedilla = unicode('Fran\xe7ois', 'latin1') @@ -126,16 +126,27 @@ class TestVariant(Testing.vtkTest): l.sort() self.assertEqual(l, s) + def testComparisonMethods(self): + v1 = vtk.vtkVariant(10) + v2 = vtk.vtkVariant("10") + # compare without regards to type + self.assertEqual(vtk.vtkVariantEqual(v1, v2), True) + self.assertEqual(vtk.vtkVariantLessThan(v1, v2), False) + # compare with different types being non-equivalent + self.assertEqual(vtk.vtkVariantStrictEquality(v1, v2), False) + if sys.hexversion >= 0x03000000: + self.assertEqual(vtk.vtkVariantStrictWeakOrder(v1, v2), True) + else: + # for Python 2, it worked like the cmp() function + self.assertEqual(vtk.vtkVariantStrictWeakOrder(v1, v2), -1) + def testStrictWeakOrder(self): """Use vtkVariantStrictWeakOrder to sort a list of vtkVariants""" - if sys.hexversion > 0x03000000: - """sort() doesn't take comparator in py3k""" - return original = [1, 2.5, vtk.vtkVariant(), "0", cedilla] ordered = [vtk.vtkVariant(), 1, 2.5, "0", cedilla] l = [vtk.vtkVariant(x) for x in original] s = [vtk.vtkVariant(x) for x in ordered] - l.sort(vtk.vtkVariantStrictWeakOrder) + l.sort(key=vtk.vtkVariantStrictWeakOrderKey) self.assertEqual(l, s) def testVariantExtract(self): diff --git a/Wrapping/Python/vtk/util/vtkVariant.py b/Wrapping/Python/vtk/util/vtkVariant.py index fbf54a1b787..bad0a645878 100644 --- a/Wrapping/Python/vtk/util/vtkVariant.py +++ b/Wrapping/Python/vtk/util/vtkVariant.py @@ -3,6 +3,7 @@ Utility functions to mimic the template support functions for vtkVariant """ import vtk +import sys _variant_type_map = { 'void' : vtk.VTK_VOID, @@ -126,10 +127,11 @@ def vtkVariantCast(v, t): def vtkVariantStrictWeakOrder(s1, s2): """ - Compare variants by type first, and then by value. The return values - are -1, 0, 1 like the python cmp() method, for compatibility with the - python list sort() method. This is in contrast with the C++ version, - which returns true or false. + Compare variants by type first, and then by value. When called from + within a Python 2 interpreter, the return values are -1, 0, 1 like the + cmp() method, for compatibility with the Python 2 list sort() method. + This is in contrast with the Python 3 version of this method (and the + VTK C++ version), which return true or false. """ s1 = vtk.vtkVariant(s1) s2 = vtk.vtkVariant(s2) @@ -137,28 +139,64 @@ def vtkVariantStrictWeakOrder(s1, s2): t1 = s1.GetType() t2 = s2.GetType() + # define a cmp(x, y) for Python 3 that returns (x < y) + def vcmp(x, y): + if sys.hexversion >= 0x03000000: + return (x < y) + else: + return cmp(x,y) + # check based on type if t1 != t2: - return cmp(t1,t2) + return vcmp(t1,t2) v1 = s1.IsValid() v2 = s2.IsValid() # check based on validity - if (not v1) and (not v2): - return 0 - elif v1 != v2: - return cmp(v1,v2) + if (not v1) or (not v2): + return vcmp(v1,v2) # extract and compare the values r1 = getattr(s1, _variant_method_map[t1])() r2 = getattr(s2, _variant_method_map[t2])() - # compare vtk objects by classname + # compare vtk objects by classname, then address if t1 == vtk.VTK_OBJECT: - return cmp(r1.GetClassName(), r2.GetClassName()) - - return cmp(r1, r2) + c1 = r1.GetClassName() + c2 = r2.GetClassName() + if c1 != c2: + return vcmp(c1,c2) + else: + return vcmp(r1.__this__,r2.__this__) + + return vcmp(r1, r2) + + +if sys.hexversion >= 0x03000000: + class vtkVariantStrictWeakOrderKey: + """A key method (class, actually) for use with sort()""" + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return vtkVariantStrictWeakOrder(self.obj, other) +else: + class vtkVariantStrictWeakOrderKey: + """A key method (class, actually) for use with sort()""" + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return vtkVariantStrictWeakOrder(self.obj, other) < 0 + def __gt__(self, other): + return vtkVariantStrictWeakOrder(self.obj, other) > 0 + def __eq__(self, other): + return vtkVariantStrictWeakOrder(self.obj, other) == 0 + def __le__(self, other): + return vtkVariantStrictWeakOrder(self.obj, other) <= 0 + def __ge__(self, other): + return vtkVariantStrictWeakOrder(self.obj, other) >= 0 + def __ne__(self, other): + return vtkVariantStrictWeakOrder(self.obj, other) != 0 def vtkVariantStrictEquality(s1, s2): @@ -193,14 +231,14 @@ def vtkVariantStrictEquality(s1, s2): def vtkVariantLessThan(s1, s2): """ - Return true if s1 < s2. This isn't very useful in Python. + Return true if s1 < s2. """ return (vtk.vtkVariant(s1) < vtk.vtkVariant(s2)) def vtkVariantEqual(s1, s2): """ - Return true if s1 == s2. This isn't very useful in Python. + Return true if s1 == s2. """ return (vtk.vtkVariant(s1) == vtk.vtkVariant(s2)) -- GitLab