Fix conversion of 'float' and 'double' values (#487)
* 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. * Fix failing 'test_double_conversion' test Fix incorrect part of 'test_double_conversion' test in test_conversion.py. An 'OverflowError' was expected for valid values, which represent Python 'inf' and '-inf'. The problem was identified with support of conversion for Python 'inf' and '-inf' to .NET System.Double PositiveInfinity and NegativeInfinity. See also: #487.
This commit is contained in:
Родитель
bfce5e299d
Коммит
d39f9f6e0c
|
@ -27,6 +27,7 @@
|
|||
- Joe Frayne ([@jfrayne](https://github.com/jfrayne))
|
||||
- John Burnett ([@johnburnett](https://github.com/johnburnett))
|
||||
- Luke Stratman ([@lstratman](https://github.com/lstratman))
|
||||
- Konstantin Posudevskiy ([@konstantin-posudevskiy](https://github.com/konstantin-posudevskiy))
|
||||
- Matthias Dittrich ([@matthid](https://github.com/matthid))
|
||||
- Patrick Stewart ([@patstew](https://github.com/patstew))
|
||||
- Raphael Nestler ([@rnestler](https://github.com/rnestler))
|
||||
|
|
|
@ -20,6 +20,8 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
|
|||
- Fixed crash on exit of the Python interpreter if a python class
|
||||
derived from a .NET class has a `__namespace__` or `__assembly__`
|
||||
attribute (#481)
|
||||
- Fixed conversion of 'float' and 'double' values (#486)
|
||||
|
||||
|
||||
## [2.3.0][] - 2017-03-11
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
<Compile Include="pyimport.cs" />
|
||||
<Compile Include="pyinitialize.cs" />
|
||||
<Compile Include="pyrunstring.cs" />
|
||||
<Compile Include="TestConverter.cs" />
|
||||
<Compile Include="TestCustomMarshal.cs" />
|
||||
<Compile Include="TestExample.cs" />
|
||||
<Compile Include="TestPyAnsiString.cs" />
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
using NUnit.Framework;
|
||||
using Python.Runtime;
|
||||
|
||||
namespace Python.EmbeddingTest
|
||||
{
|
||||
public class TestConverter
|
||||
{
|
||||
[OneTimeSetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
PythonEngine.Initialize();
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Dispose()
|
||||
{
|
||||
PythonEngine.Shutdown();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConvertSingleToManaged(
|
||||
[Values(float.PositiveInfinity, float.NegativeInfinity, float.MinValue, float.MaxValue, float.NaN,
|
||||
float.Epsilon)] float testValue)
|
||||
{
|
||||
var pyFloat = new PyFloat(testValue);
|
||||
|
||||
object convertedValue;
|
||||
var converted = Converter.ToManaged(pyFloat.Handle, typeof(float), out convertedValue, false);
|
||||
|
||||
Assert.IsTrue(converted);
|
||||
Assert.IsTrue(((float) convertedValue).Equals(testValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConvertDoubleToManaged(
|
||||
[Values(double.PositiveInfinity, double.NegativeInfinity, double.MinValue, double.MaxValue, double.NaN,
|
||||
double.Epsilon)] double testValue)
|
||||
{
|
||||
var pyFloat = new PyFloat(testValue);
|
||||
|
||||
object convertedValue;
|
||||
var converted = Converter.ToManaged(pyFloat.Handle, typeof(double), out convertedValue, false);
|
||||
|
||||
Assert.IsTrue(converted);
|
||||
Assert.IsTrue(((double) convertedValue).Equals(testValue));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -770,10 +770,14 @@ namespace Python.Runtime
|
|||
goto type_error;
|
||||
}
|
||||
double dd = Runtime.PyFloat_AsDouble(op);
|
||||
Runtime.CheckExceptionOccurred();
|
||||
Runtime.XDecref(op);
|
||||
if (dd > Single.MaxValue || dd < Single.MinValue)
|
||||
{
|
||||
goto overflow;
|
||||
if (!double.IsInfinity(dd))
|
||||
{
|
||||
goto overflow;
|
||||
}
|
||||
}
|
||||
result = (float)dd;
|
||||
return true;
|
||||
|
@ -785,11 +789,8 @@ namespace Python.Runtime
|
|||
goto type_error;
|
||||
}
|
||||
double d = Runtime.PyFloat_AsDouble(op);
|
||||
Runtime.CheckExceptionOccurred();
|
||||
Runtime.XDecref(op);
|
||||
if (d > Double.MaxValue || d < Double.MinValue)
|
||||
{
|
||||
goto overflow;
|
||||
}
|
||||
result = d;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -466,17 +466,6 @@ def test_double_conversion():
|
|||
with pytest.raises(TypeError):
|
||||
ConversionTest().DoubleField = None
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
ConversionTest().DoubleField = 1.7976931348623159e308
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
ConversionTest().DoubleField = -1.7976931348623159e308
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
_ = System.Double(1.7976931348623159e308)
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
_ = System.Double(-1.7976931348623159e308)
|
||||
|
||||
|
||||
def test_decimal_conversion():
|
||||
|
|
Загрузка…
Ссылка в новой задаче