Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a9c3d8b

Browse files
Fix conversion of 'float' and 'double' values
Fix problem of conversion 'float' and 'double' values in converter.cs. As there was a range check both for 'float' and 'double' values, which are less or greater than its 'MinValue' and 'MaxValue' accordingly, several values like 'float.NegativeInfinity', 'float.PositiveInfinity' and the same 'double' values cannot be converted from Python to .NET values. Add error check after 'PyFloat_AsDouble' call. Due to Python C API documentation, method 'PyFloat_AsDouble' can return '-1.0' upon failure. So it requires error check. This rule forces to check for error and throw exception in case of error. Add tests, which cover problem of conversion 'float' and 'double' values. Resolves: #486.
1 parent aef02e2 commit a9c3d8b

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

src/embed_tests/Python.EmbeddingTest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
<Compile Include="pyimport.cs" />
8585
<Compile Include="pyinitialize.cs" />
8686
<Compile Include="pyrunstring.cs" />
87+
<Compile Include="TestConverter.cs" />
8788
<Compile Include="TestCustomMarshal.cs" />
8889
<Compile Include="TestExample.cs" />
8990
<Compile Include="TestPyAnsiString.cs" />

src/embed_tests/TestConverter.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using NUnit.Framework;
2+
using Python.Runtime;
3+
4+
namespace Python.EmbeddingTest
5+
{
6+
public class TestConverter
7+
{
8+
[OneTimeSetUp]
9+
public void SetUp()
10+
{
11+
PythonEngine.Initialize();
12+
}
13+
14+
[OneTimeTearDown]
15+
public void Dispose()
16+
{
17+
PythonEngine.Shutdown();
18+
}
19+
20+
[Test]
21+
public void TestConvertSingleToManaged(
22+
[Values(float.PositiveInfinity, float.NegativeInfinity, float.MinValue, float.MaxValue, float.NaN,
23+
float.Epsilon)] float testValue)
24+
{
25+
var pyFloat = new PyFloat(testValue);
26+
27+
object convertedValue;
28+
var converted = Converter.ToManaged(pyFloat.Handle, typeof(float), out convertedValue, false);
29+
30+
Assert.IsTrue(converted);
31+
Assert.IsTrue(((float) convertedValue).Equals(testValue));
32+
}
33+
34+
[Test]
35+
public void TestConvertDoubleToManaged(
36+
[Values(double.PositiveInfinity, double.NegativeInfinity, double.MinValue, double.MaxValue, double.NaN,
37+
double.Epsilon)] double testValue)
38+
{
39+
var pyFloat = new PyFloat(testValue);
40+
41+
object convertedValue;
42+
var converted = Converter.ToManaged(pyFloat.Handle, typeof(double), out convertedValue, false);
43+
44+
Assert.IsTrue(converted);
45+
Assert.IsTrue(((double) convertedValue).Equals(testValue));
46+
}
47+
}
48+
}

src/runtime/converter.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -770,10 +770,14 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object result, bo
770770
goto type_error;
771771
}
772772
double dd = Runtime.PyFloat_AsDouble(op);
773+
Runtime.CheckExceptionOccurred();
773774
Runtime.XDecref(op);
774775
if (dd > Single.MaxValue || dd < Single.MinValue)
775776
{
776-
goto overflow;
777+
if (!double.IsInfinity(dd))
778+
{
779+
goto overflow;
780+
}
777781
}
778782
result = (float)dd;
779783
return true;
@@ -785,11 +789,8 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object result, bo
785789
goto type_error;
786790
}
787791
double d = Runtime.PyFloat_AsDouble(op);
792+
Runtime.CheckExceptionOccurred();
788793
Runtime.XDecref(op);
789-
if (d > Double.MaxValue || d < Double.MinValue)
790-
{
791-
goto overflow;
792-
}
793794
result = d;
794795
return true;
795796
}

0 commit comments

Comments
 (0)