diff --git a/Changes b/Changes index a5d03e65de..5401d3d432 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,4 @@ -10.5.0.0 (relative to 10.4.10.0) +10.5.0.0 (relative to 10.4.10.1) ======== Features @@ -40,6 +40,15 @@ Breaking Changes - Changed function signature. - Bug fixes mean subtle changes to the resulting points. +10.4.10.1 (relative to 10.4.10.0) +======== + +Fixes +----- + +- FrameRange : Prevented creation of FrameRanges with negative steps +- IECore.dataTypeFromElement : Fixed support for list to Vector conversions + 10.4.10.0 (relative to 10.4.9.1) ======== diff --git a/python/IECore/DataTraits.py b/python/IECore/DataTraits.py index b368bde24b..6b079031cd 100644 --- a/python/IECore/DataTraits.py +++ b/python/IECore/DataTraits.py @@ -146,16 +146,16 @@ def isSequenceDataType(obj): IECore.M44fData: (imath.M44f, True), IECore.M44dData: (imath.M44d, True), - IECore.BoolVectorData: ( list, False, bool), + IECore.BoolVectorData: ( list, True, bool), IECore.CharVectorData: (list, False, str), IECore.UCharVectorData: (list, False, int), - IECore.IntVectorData: (list, False, int), + IECore.IntVectorData: (list, True, int), IECore.UIntVectorData: (list, False, int), IECore.HalfVectorData: (list, False, float), IECore.FloatVectorData: (list, False, float), - IECore.DoubleVectorData: (list, False, float), - IECore.StringVectorData: (list, False, str), - IECore.InternedStringVectorData: (list, False, IECore.InternedString), + IECore.DoubleVectorData: (list, True, float), + IECore.StringVectorData: (list, True, str), + IECore.InternedStringVectorData: (list, True, IECore.InternedString), IECore.ShortVectorData: (list, False, int), IECore.UShortVectorData: (list, False, int), IECore.Int64VectorData: (list, False, int), @@ -166,27 +166,27 @@ def isSequenceDataType(obj): IECore.V3fVectorDataBase: (list, False, imath.V3f), IECore.V3dVectorDataBase: (list, False, imath.V3d), IECore.V3iVectorDataBase: (list, False, imath.V3i), - IECore.V2fVectorData: (list, False, imath.V2f), - IECore.V2dVectorData: (list, False, imath.V2d), - IECore.V2iVectorData: (list, False, imath.V2i), - IECore.V3fVectorData: (list, False, imath.V3f), - IECore.V3dVectorData: (list, False, imath.V3d), - IECore.V3iVectorData: (list, False, imath.V3i), - IECore.QuatfVectorData: (list, False, imath.Quatf), - IECore.QuatdVectorData: (list, False, imath.Quatd), - IECore.Box2iVectorData: (list, False, imath.Box2i), - IECore.Box2fVectorData: (list, False, imath.Box2f), - IECore.Box2dVectorData: (list, False, imath.Box2d), - IECore.Box3iVectorData: (list, False, imath.Box3i), - IECore.Box3fVectorData: (list, False, imath.Box3f), - IECore.Box3dVectorData: (list, False, imath.Box3d), - IECore.M33fVectorData: (list, False, imath.M33f), - IECore.M33dVectorData: (list, False, imath.M33d), - IECore.M44fVectorData: (list, False, imath.M44f), - IECore.M44dVectorData: (list, False, imath.M44d), - IECore.Color3fVectorData: (list, False, imath.Color3f), + IECore.V2fVectorData: (list, True, imath.V2f), + IECore.V2dVectorData: (list, True, imath.V2d), + IECore.V2iVectorData: (list, True, imath.V2i), + IECore.V3fVectorData: (list, True, imath.V3f), + IECore.V3dVectorData: (list, True, imath.V3d), + IECore.V3iVectorData: (list, True, imath.V3i), + IECore.QuatfVectorData: (list, True, imath.Quatf), + IECore.QuatdVectorData: (list, True, imath.Quatd), + IECore.Box2iVectorData: (list, True, imath.Box2i), + IECore.Box2fVectorData: (list, True, imath.Box2f), + IECore.Box2dVectorData: (list, True, imath.Box2d), + IECore.Box3iVectorData: (list, True, imath.Box3i), + IECore.Box3fVectorData: (list, True, imath.Box3f), + IECore.Box3dVectorData: (list, True, imath.Box3d), + IECore.M33fVectorData: (list, True, imath.M33f), + IECore.M33dVectorData: (list, True, imath.M33d), + IECore.M44fVectorData: (list, True, imath.M44f), + IECore.M44dVectorData: (list, True, imath.M44d), + IECore.Color3fVectorData: (list, True, imath.Color3f), #IECore.Color3dVectorData: (list, False, IECore.Color3d), - IECore.Color4fVectorData: (list, False, imath.Color4f), + IECore.Color4fVectorData: (list, True, imath.Color4f), #IECore.Color4dVectorData: (list, False, IECore.Color4d), IECore.CompoundData: (dict, True, None), @@ -245,6 +245,9 @@ def valueTypeFromSequenceType(sequenceType): ## \ingroup python def dataTypeFromElementType(elementType): + if elementType is list: + raise TypeError( "`list` type is ambiguous and not a valid input to dataTypeFromElementType()" ) + for (dataType, value) in __dataTypesConversionDict.items(): if value is None: continue @@ -262,7 +265,9 @@ def dataTypeFromElement(element): # We have to check the list contents. elementValueType = type(element[0]) for (dataType, value) in __dataTypesConversionDict.items(): - if value[0] is list and len(value) >= 2 and value[2] is elementValueType: + if value is None: + continue + if value[0] is list and len(value) >= 2 and value[1] and value[2] is elementValueType: return dataType return dataTypeFromElementType(type(element)) diff --git a/src/IECore/FrameRange.cpp b/src/IECore/FrameRange.cpp index ef746faa76..8266abfaa2 100644 --- a/src/IECore/FrameRange.cpp +++ b/src/IECore/FrameRange.cpp @@ -58,6 +58,10 @@ FrameRange::FrameRange( Frame start, Frame end, Frame step ) : m_start( start ), { throw Exception( "FrameRange step cannot be zero" ); } + if ( step < 0 ) + { + throw Exception( "FrameRange step cannot be negative. Consider using the reverse suffix instead." ); + } } FrameRange::~FrameRange() @@ -102,6 +106,10 @@ void FrameRange::setStep( Frame step ) { throw Exception( "FrameRange step cannot be zero" ); } + if ( step < 0 ) + { + throw Exception( "FrameRange step cannot be negative. Consider using the reverse suffix instead." ); + } m_step = step; } diff --git a/test/IECore/DataTraitsTest.py b/test/IECore/DataTraitsTest.py index 6198e1115d..e860f04736 100644 --- a/test/IECore/DataTraitsTest.py +++ b/test/IECore/DataTraitsTest.py @@ -32,11 +32,11 @@ # ########################################################################## -import math import unittest import IECore -import random -import os +import datetime +import imath + class DataTraitsTest( unittest.TestCase ) : @@ -129,6 +129,65 @@ def testIsSequenceDataType( self ) : for data in falseData : self.assertFalse( IECore.DataTraits.isSequenceDataType( data ) ) + def testDataFromElement( self ) : + + dataMap = ( + ( True, IECore.BoolData, IECore.BoolVectorData ), + ( 10, IECore.IntData, IECore.IntVectorData ), + ( "abc", IECore.StringData, IECore.StringVectorData ), + ( IECore.InternedString( "abc" ), IECore.InternedStringData, IECore.InternedStringVectorData ), + ( 1.1, IECore.DoubleData, IECore.DoubleVectorData ), + ( imath.V2f( 1.0, 2.0 ), IECore.V2fData, IECore.V2fVectorData ), + ( imath.V2d( 1.0, 2.0 ), IECore.V2dData, IECore.V2dVectorData ), + ( imath.V2i( 1, 2 ), IECore.V2iData, IECore.V2iVectorData ), + ( imath.V3i( 1, 2, 3 ), IECore.V3iData, IECore.V3iVectorData ), + ( imath.V3f( 1.0, 2.0, 3.0 ), IECore.V3fData, IECore.V3fVectorData ), + ( imath.V3d( 1.0, 2.0, 3.0 ), IECore.V3dData, IECore.V3dVectorData ), + ( imath.Quatf(), IECore.QuatfData, IECore.QuatfVectorData ), + ( imath.Quatd(), IECore.QuatdData, IECore.QuatdVectorData ), + ( imath.Color3f(), IECore.Color3fData, IECore.Color3fVectorData ), + ( imath.Color4f(), IECore.Color4fData, IECore.Color4fVectorData ), + ( imath.Box2i(), IECore.Box2iData, IECore.Box2iVectorData ), + ( imath.Box3i(), IECore.Box3iData, IECore.Box3iVectorData ), + ( imath.Box2f(), IECore.Box2fData, IECore.Box2fVectorData ), + ( imath.Box2d(), IECore.Box2dData, IECore.Box2dVectorData ), + ( imath.Box3f(), IECore.Box3fData, IECore.Box3fVectorData ), + ( imath.Box3d(), IECore.Box3dData, IECore.Box3dVectorData ), + ( imath.M33f(), IECore.M33fData, IECore.M33fVectorData ), + ( imath.M33d(), IECore.M33dData, IECore.M33dVectorData ), + ( imath.M44f(), IECore.M44fData, IECore.M44fVectorData ), + ( imath.M44d(), IECore.M44dData, IECore.M44dVectorData ), + ( { "age" : 10 }, IECore.CompoundData, None ), + ( IECore.TransformationMatrixf(), IECore.TransformationMatrixfData, None ), + ( IECore.TransformationMatrixd(), IECore.TransformationMatrixdData, None ), + ( IECore.LineSegment3f( imath.V3f( 0 ), imath.V3f( 1 ) ), IECore.LineSegment3fData, None ), + ( IECore.LineSegment3d( imath.V3d( 0 ), imath.V3d( 1 ) ), IECore.LineSegment3dData, None ), + ( IECore.Splineff(), IECore.SplineffData, None ), + ( IECore.Splinedd(), IECore.SplineddData, None ), + ( IECore.SplinefColor3f(), IECore.SplinefColor3fData, None ), + ( IECore.SplinefColor4f(), IECore.SplinefColor4fData, None ), + ( datetime.datetime( 2023, 7, 14 ), IECore.DateTimeData, None ), + ( IECore.TimeCode(), IECore.TimeCodeData, None ), + ( IECore.PathMatcher(), IECore.PathMatcherData, None ), + ) + + for element, dataType, vectorType in dataMap : + # test single element conversion + self.assertEqual( IECore.dataFromElement( element ), dataType( element ) ) + if vectorType is None : + continue + + # test list of elements conversion to a vector data + self.assertEqual( + IECore.dataFromElement( [ element ] ), + vectorType( [ element ] ), + ) + + def testDataTypeFromElementType( self ) : + self.assertEqual( IECore.dataTypeFromElementType( int ) , IECore.IntData ) + self.assertRaises( TypeError, IECore.dataTypeFromElementType, list ) + + if __name__ == "__main__": - unittest.main() + unittest.main() diff --git a/test/IECore/FrameList.py b/test/IECore/FrameList.py index 8963a5f494..ed03fd4ae7 100644 --- a/test/IECore/FrameList.py +++ b/test/IECore/FrameList.py @@ -55,7 +55,24 @@ def testReverseConstruction( self ) : self.assertEqual( f.asList(), [ 5, 4, 3, 2, 1 ] ) self.assertEqual( IECore.frameListFromList( [ 5, 4, 3, 2, 1 ] ), f ) + def testFrameRange( self ) : + + f = IECore.FrameList.parse( "1-5" ) + self.assertTrue( isinstance( f, IECore.FrameRange ) ) + self.assertEqual( f.asList(), [ 1, 2, 3, 4, 5 ] ) + # test step + f = IECore.FrameList.parse( "10-20x5" ) + self.assertTrue( isinstance( f, IECore.FrameRange ) ) + self.assertEqual( f.asList(), [ 10, 15, 20 ] ) + # start must be smaller or equal to end + self.assertRaises( Exception, IECore.FrameList.parse, "5-1" ) + # step must be positive + self.assertRaises( Exception, IECore.FrameList.parse, "1-5x0" ) + self.assertRaises( Exception, IECore.FrameList.parse, "1-5x-1" ) + self.assertRaises( Exception, IECore.FrameList.parse, "5-1x-1" ) + + ## \todo: there should probably be a lot more tests in here... if __name__ == "__main__": - unittest.main() + unittest.main()