From b6da4fe4a066f88b7bd60d951d30ad61524ae4fd Mon Sep 17 00:00:00 2001 From: Alex Earl Date: Mon, 6 Jul 2020 10:23:54 -0700 Subject: [PATCH 1/2] Allow conversion of number to enum type when assignable In .NET you can do the following: ``` enum FooEnum { One = 1, Three = 3, Four = 4, } FooEnum x = (FooEnum)2; ``` This patch allows this from Python code as well. --- src/runtime/converter.cs | 10 ++++++++++ src/testing/methodtest.cs | 14 +++++++++++++- src/tests/test_array.py | 6 +++--- src/tests/test_conversion.py | 12 ++++++------ src/tests/test_enum.py | 9 ++++----- src/tests/test_method.py | 15 +++++++++++++++ 6 files changed, 51 insertions(+), 15 deletions(-) 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.""" From 9320ab8f5d51c49865126cc199653e5fe68782fe Mon Sep 17 00:00:00 2001 From: Alex Earl Date: Mon, 6 Jul 2020 10:28:09 -0700 Subject: [PATCH 2/2] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) 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 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy