diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e82f40e3..b77865e53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. ### Changed - Drop support for Python 2 +- Added support for conversion from numerical types to enum in argument passing ### Fixed diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 734422ed0..90358395c 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -893,6 +893,16 @@ private static bool ToEnum(IntPtr value, Type obType, out object result, bool se return true; } + // .NET allows you to assign a value to an enum + // even if that value is not defined in the enum + // as long as it is assignable to the underlying + // type. + if(etype.IsAssignableFrom(result.GetType())) + { + result = Enum.ToObject(obType, result); + return true; + } + if (setError) { Exceptions.SetError(Exceptions.ValueError, "invalid enumeration value"); diff --git a/src/testing/methodtest.cs b/src/testing/methodtest.cs index 91836b727..bb835e970 100644 --- a/src/testing/methodtest.cs +++ b/src/testing/methodtest.cs @@ -62,6 +62,18 @@ public TypeCode TestEnumConversion(TypeCode v) return v; } + public enum TestEnum : int + { + One = 1, + Three = 3, + Four = 4, + } + + public TestEnum TestEnumValueTypeConversion(TestEnum v) + { + return v; + } + public FileAccess TestFlagsConversion(FileAccess v) { return v; @@ -683,7 +695,7 @@ public static string OptionalAndDefaultParams2([Optional]int a, [Optional]int b, return string.Format("{0}{1}{2}{3}", a, b, c, d); } - + } diff --git a/src/tests/test_array.py b/src/tests/test_array.py index 427958ec7..ae1f20330 100644 --- a/src/tests/test_array.py +++ b/src/tests/test_array.py @@ -679,9 +679,9 @@ def test_enum_array(): items[-1] = ShortEnum.Zero assert items[-1] == ShortEnum.Zero - with pytest.raises(ValueError): - ob = Test.EnumArrayTest() - ob.items[0] = 99 + ob = Test.EnumArrayTest() + ob.items[0] = 99 + assert ob.items[0] == 99 with pytest.raises(TypeError): ob = Test.EnumArrayTest() diff --git a/src/tests/test_conversion.py b/src/tests/test_conversion.py index 74613abd1..0bd412ce0 100644 --- a/src/tests/test_conversion.py +++ b/src/tests/test_conversion.py @@ -616,13 +616,13 @@ def test_enum_conversion(): assert ob.EnumField == ShortEnum.One assert ob.EnumField == 1 - with pytest.raises(ValueError): - ob = ConversionTest() - ob.EnumField = 10 + ob = ConversionTest() + ob.EnumField = 10 + assert ob.EnumField == 10 - with pytest.raises(ValueError): - ob = ConversionTest() - ob.EnumField = 255 + ob = ConversionTest() + ob.EnumField = 255 + assert ob.EnumField == 255 with pytest.raises(OverflowError): ob = ConversionTest() diff --git a/src/tests/test_enum.py b/src/tests/test_enum.py index 27fe7e9ef..edd968fb8 100644 --- a/src/tests/test_enum.py +++ b/src/tests/test_enum.py @@ -122,9 +122,8 @@ def test_enum_with_flags_attr_conversion(): # This works because the FlagsField enum has FlagsAttribute. Test.FieldTest().FlagsField = 99 - # This should fail because our test enum doesn't have it. - with pytest.raises(ValueError): - Test.FieldTest().EnumField = 99 + # This works because .NET allows assigning the underlying type + Test.FieldTest().EnumField = 99 def test_enum_conversion(): @@ -135,8 +134,8 @@ def test_enum_conversion(): ob.EnumField = Test.ShortEnum.One assert ob.EnumField == 1 - with pytest.raises(ValueError): - Test.FieldTest().EnumField = 20 + ob.EnumField = 20 + assert ob.EnumField == 20 with pytest.raises(OverflowError): Test.FieldTest().EnumField = 100000 diff --git a/src/tests/test_method.py b/src/tests/test_method.py index d9c033802..0716608fb 100644 --- a/src/tests/test_method.py +++ b/src/tests/test_method.py @@ -162,6 +162,21 @@ def test_method_call_enum_conversion(): r = ob.TestEnumConversion(TypeCode.Int32) assert r == TypeCode.Int32 +def test_method_call_enum_valuetype_conversion(): + """Test enum which inherits from a value type + gets converted to enum in method call""" + ob = MethodTest() + r = ob.TestEnumValueTypeConversion(1) + assert r == MethodTest.TestEnum.One + + r = ob.TestEnumValueTypeConversion(3) + assert r == MethodTest.TestEnum.Three + + r = ob.TestEnumValueTypeConversion(2) + assert r == 2 + + with pytest.raises(TypeError): + r = ob.TestEnumValueTypeConversion('Hi') def test_method_call_flags_conversion(): """Test flags conversion in method call."""