Skip to content

Commit dc0c599

Browse files
committed
IECoreBinding : repr infinity for eval
1 parent 55eed97 commit dc0c599

File tree

3 files changed

+79
-4
lines changed

3 files changed

+79
-4
lines changed

Changes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
10.5.x.x (relative to 10.5.11.0)
22
========
33

4+
Fixes
5+
-----
6+
7+
- IECore : Fixed bug that was causing imath vectors and colors with values of `inf` / `std::numeric_limits<float>::infinity()` to be serialised in a way that could not be evaluated with `eval()`.
48

59

610
10.5.11.0 (relative to 10.5.10.0)

src/IECorePython/IECoreBinding.cpp

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ IECORE_POP_DEFAULT_VISIBILITY
5858
using namespace std;
5959
using namespace Imath;
6060

61+
namespace
62+
{
63+
64+
static std::string g_positiveInfString = "float( 'inf' )";
65+
static std::string g_negativeInfString = "-float( 'inf' )";
66+
67+
}
68+
6169
namespace IECorePython
6270
{
6371

@@ -70,7 +78,18 @@ std::string repr<VEC>( VEC &x )\
7078
s << "imath." << #VEC << "( ";\
7179
for( unsigned i=0; i<VEC::dimensions(); i++ )\
7280
{\
73-
s << boost::lexical_cast<string>( x[i] );\
81+
if constexpr( std::numeric_limits<VEC::BaseType>::has_infinity )\
82+
{\
83+
s << (\
84+
x[i] == std::numeric_limits<VEC::BaseType>::infinity() ? g_positiveInfString :\
85+
( x[i] == -std::numeric_limits<VEC::BaseType>::infinity() ? g_negativeInfString :\
86+
boost::lexical_cast<std::string>( x[i] ) ) \
87+
);\
88+
}\
89+
else\
90+
{\
91+
s << boost::lexical_cast<string>( x[i] );\
92+
}\
7493
if( i!=VEC::dimensions()-1 )\
7594
{\
7695
s << ", ";\
@@ -86,7 +105,18 @@ std::string str<VEC>( VEC &x )\
86105
std::stringstream s;\
87106
for( unsigned i=0; i<VEC::dimensions(); i++ )\
88107
{\
89-
s << boost::lexical_cast<string>( x[i] );\
108+
if constexpr( std::numeric_limits<VEC::BaseType>::has_infinity )\
109+
{\
110+
s << (\
111+
x[i] == std::numeric_limits<VEC::BaseType>::infinity() ? g_positiveInfString :\
112+
( x[i] == -std::numeric_limits<VEC::BaseType>::infinity() ? g_negativeInfString :\
113+
boost::lexical_cast<std::string>( x[i] ) ) \
114+
);\
115+
}\
116+
else\
117+
{\
118+
s << boost::lexical_cast<string>( x[i] );\
119+
}\
90120
if( i!=VEC::dimensions()-1 )\
91121
{\
92122
s << " ";\
@@ -142,7 +172,18 @@ std::string repr<COL>( COL &x )\
142172
s << "imath." << #COL << "( ";\
143173
for( unsigned i=0; i<COL::dimensions(); i++ )\
144174
{\
145-
s << boost::lexical_cast<std::string>( x[i] );\
175+
if constexpr( std::numeric_limits<COL::BaseType>::has_infinity )\
176+
{\
177+
s << (\
178+
x[i] == std::numeric_limits<COL::BaseType>::infinity() ? g_positiveInfString :\
179+
( x[i] == -std::numeric_limits<COL::BaseType>::infinity() ? g_negativeInfString :\
180+
boost::lexical_cast<std::string>( x[i] ) ) \
181+
);\
182+
}\
183+
else\
184+
{\
185+
s << boost::lexical_cast<string>( x[i] );\
186+
}\
146187
if( i!=COL::dimensions()-1 )\
147188
{\
148189
s << ", ";\
@@ -158,7 +199,18 @@ std::string str<COL>( COL &x )\
158199
std::stringstream s;\
159200
for( unsigned i=0; i<COL::dimensions(); i++ )\
160201
{\
161-
s << boost::lexical_cast<std::string>( x[i] );\
202+
if constexpr( std::numeric_limits<COL::BaseType>::has_infinity )\
203+
{\
204+
s << (\
205+
x[i] == std::numeric_limits<COL::BaseType>::infinity() ? g_positiveInfString :\
206+
( x[i] == -std::numeric_limits<COL::BaseType>::infinity() ? g_negativeInfString :\
207+
boost::lexical_cast<std::string>( x[i] ) ) \
208+
);\
209+
}\
210+
else\
211+
{\
212+
s << boost::lexical_cast<string>( x[i] );\
213+
}\
162214
if( i!=COL::dimensions()-1 )\
163215
{\
164216
s << " ";\

test/IECore/ReprTest.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,25 @@ def test( self ) :
6060
] :
6161
self.assertTrue( type( v ) is type( eval( IECore.repr( v ) ) ) )
6262
self.assertEqual( v, eval( IECore.repr( v ) ) )
63+
64+
def testInfinity( self ) :
65+
66+
for v in [
67+
# Python raises "OverflowError : bad numeric conversion : positive overflow"
68+
# when passing `float( "inf" )` to `V2f``
69+
imath.V2d( float( "inf" ), float( "inf" ) ),
70+
imath.V3f( float( "inf" ), float( "inf" ), float( "inf" ) ),
71+
imath.V3d( float( "inf" ), float( "inf" ), float( "inf" ) ),
72+
imath.Color3f( float( "inf" ), float( "inf" ), float( "inf" ) ),
73+
imath.Color4f( float( "inf" ), float( "inf" ), float( "inf" ), float( "inf" ) ),
74+
] :
75+
with self.subTest( v = v ) :
76+
self.assertTrue( type( v ) is type( eval( IECore.repr( v ) ) ) )
77+
self.assertEqual( v, eval( IECore.repr( v ) ) )
78+
79+
self.assertTrue( type( -v ) is type( eval( IECore.repr( -v ) ) ) )
80+
self.assertEqual( -v, eval( IECore.repr( -v ) ) )
81+
6382

6483
if __name__ == "__main__":
6584
unittest.main()

0 commit comments

Comments
 (0)