From 14833364db4f0b30951b4f82988254c0fe745651 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 12 Aug 2022 08:21:35 +0200 Subject: [PATCH 1/4] Fill nb_index slot for integer types --- src/runtime/Native/ITypeOffsets.cs | 1 + src/runtime/Native/TypeOffset.cs | 1 + src/runtime/Types/ClassBase.cs | 3 +++ src/runtime/Types/OperatorMethod.cs | 1 + src/runtime/Util/OpsHelper.cs | 2 +- tests/test_conversion.py | 7 +++++++ 6 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/runtime/Native/ITypeOffsets.cs b/src/runtime/Native/ITypeOffsets.cs index 0920a312a..7d71b4b91 100644 --- a/src/runtime/Native/ITypeOffsets.cs +++ b/src/runtime/Native/ITypeOffsets.cs @@ -31,6 +31,7 @@ interface ITypeOffsets int nb_invert { get; } int nb_inplace_add { get; } int nb_inplace_subtract { get; } + int nb_index { get; } int ob_size { get; } int ob_type { get; } int qualname { get; } diff --git a/src/runtime/Native/TypeOffset.cs b/src/runtime/Native/TypeOffset.cs index 847f1766d..803b86bfa 100644 --- a/src/runtime/Native/TypeOffset.cs +++ b/src/runtime/Native/TypeOffset.cs @@ -38,6 +38,7 @@ static partial class TypeOffset internal static int nb_invert { get; private set; } internal static int nb_inplace_add { get; private set; } internal static int nb_inplace_subtract { get; private set; } + internal static int nb_index { get; private set; } internal static int ob_size { get; private set; } internal static int ob_type { get; private set; } internal static int qualname { get; private set; } diff --git a/src/runtime/Types/ClassBase.cs b/src/runtime/Types/ClassBase.cs index 943841e25..7296a1900 100644 --- a/src/runtime/Types/ClassBase.cs +++ b/src/runtime/Types/ClassBase.cs @@ -604,6 +604,7 @@ public virtual void InitializeSlots(BorrowedReference pyType, SlotsHolder slotsH case TypeCode.Int32: case TypeCode.Int64: TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.nb_int, new Interop.B_N(DoConvertInt), slotsHolder); + TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.nb_index, new Interop.B_N(DoConvertInt), slotsHolder); TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.nb_float, new Interop.B_N(DoConvertFloat), slotsHolder); break; case TypeCode.Byte: @@ -611,10 +612,12 @@ public virtual void InitializeSlots(BorrowedReference pyType, SlotsHolder slotsH case TypeCode.UInt32: case TypeCode.UInt64: TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.nb_int, new Interop.B_N(DoConvertUInt), slotsHolder); + TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.nb_index, new Interop.B_N(DoConvertUInt), slotsHolder); TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.nb_float, new Interop.B_N(DoConvertFloat), slotsHolder); break; case TypeCode.Double: case TypeCode.Single: + TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.nb_int, new Interop.B_N(DoConvertInt), slotsHolder); TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.nb_float, new Interop.B_N(DoConvertFloat), slotsHolder); break; } diff --git a/src/runtime/Types/OperatorMethod.cs b/src/runtime/Types/OperatorMethod.cs index 88939a51d..6e5ed6dda 100644 --- a/src/runtime/Types/OperatorMethod.cs +++ b/src/runtime/Types/OperatorMethod.cs @@ -54,6 +54,7 @@ static OperatorMethod() ["__int__"] = new SlotDefinition("__int__", TypeOffset.nb_int), ["__float__"] = new SlotDefinition("__float__", TypeOffset.nb_float), + ["__index__"] = new SlotDefinition("__float__", TypeOffset.nb_index), }; ComparisonOpMap = new Dictionary { diff --git a/src/runtime/Util/OpsHelper.cs b/src/runtime/Util/OpsHelper.cs index 12d0c7aa6..97907bf34 100644 --- a/src/runtime/Util/OpsHelper.cs +++ b/src/runtime/Util/OpsHelper.cs @@ -82,7 +82,7 @@ internal static class EnumOps where T : Enum { [ForbidPythonThreads] #pragma warning disable IDE1006 // Naming Styles - must match Python - public static PyInt __int__(T value) + public static PyInt __index__(T value) #pragma warning restore IDE1006 // Naming Styles => typeof(T).GetEnumUnderlyingType() == typeof(UInt64) ? new PyInt(Convert.ToUInt64(value)) diff --git a/tests/test_conversion.py b/tests/test_conversion.py index 69e7ec63f..4b16401b0 100644 --- a/tests/test_conversion.py +++ b/tests/test_conversion.py @@ -721,6 +721,7 @@ def test_intptr_construction(): UIntPtr(v) def test_explicit_conversion(): + from operator import index from System import ( Int64, UInt64, Int32, UInt32, Int16, UInt16, Byte, SByte, Boolean ) @@ -730,10 +731,13 @@ def test_explicit_conversion(): assert int(Boolean(True)) == 1 for t in [UInt64, UInt32, UInt16, Byte]: + assert index(t(127)) == 127 assert int(t(127)) == 127 assert float(t(127)) == 127.0 for t in [Int64, Int32, Int16, SByte]: + assert index(t(127)) == 127 + assert index(t(-127)) == -127 assert int(t(127)) == 127 assert int(t(-127)) == -127 assert float(t(127)) == 127.0 @@ -745,3 +749,6 @@ def test_explicit_conversion(): for t in [Single, Double]: assert float(t(0.125)) == 0.125 + assert int(t(123.4)) == 123 + with pytest.raises(TypeError): + index(t(123.4)) From c7068a522a8c84584515a0bfc2c97c2bfc5e88b8 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 12 Aug 2022 08:27:12 +0200 Subject: [PATCH 2/4] Fix tests for min/max values --- tests/test_conversion.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_conversion.py b/tests/test_conversion.py index 4b16401b0..bb686dd52 100644 --- a/tests/test_conversion.py +++ b/tests/test_conversion.py @@ -743,9 +743,9 @@ def test_explicit_conversion(): assert float(t(127)) == 127.0 assert float(t(-127)) == -127.0 - assert int(Int64.MaxValue) == 2**63 - 1 - assert int(Int64.MinValue) == -2**63 - assert int(UInt64.MaxValue) == 2**64 - 1 + assert int(Int64(Int64.MaxValue)) == 2**63 - 1 + assert int(Int64(Int64.MinValue)) == -2**63 + assert int(UInt64(UInt64.MaxValue)) == 2**64 - 1 for t in [Single, Double]: assert float(t(0.125)) == 0.125 From 86c8cce95e64b0f4378c6814d9f58c9e0e0ff8dc Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 12 Aug 2022 20:47:11 +0200 Subject: [PATCH 3/4] Fix SlotDefinition constructiom --- src/runtime/Types/OperatorMethod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/Types/OperatorMethod.cs b/src/runtime/Types/OperatorMethod.cs index 6e5ed6dda..e3cc23370 100644 --- a/src/runtime/Types/OperatorMethod.cs +++ b/src/runtime/Types/OperatorMethod.cs @@ -54,7 +54,7 @@ static OperatorMethod() ["__int__"] = new SlotDefinition("__int__", TypeOffset.nb_int), ["__float__"] = new SlotDefinition("__float__", TypeOffset.nb_float), - ["__index__"] = new SlotDefinition("__float__", TypeOffset.nb_index), + ["__index__"] = new SlotDefinition("__index__", TypeOffset.nb_index), }; ComparisonOpMap = new Dictionary { From ccb3f7ee038fa088422ddfa6fe4b4b863e17b75a Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Sat, 13 Aug 2022 08:50:09 +0200 Subject: [PATCH 4/4] Readd explicit `__int__` for enums --- src/runtime/Util/OpsHelper.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/runtime/Util/OpsHelper.cs b/src/runtime/Util/OpsHelper.cs index 97907bf34..7c35f27eb 100644 --- a/src/runtime/Util/OpsHelper.cs +++ b/src/runtime/Util/OpsHelper.cs @@ -87,5 +87,9 @@ public static PyInt __index__(T value) => typeof(T).GetEnumUnderlyingType() == typeof(UInt64) ? new PyInt(Convert.ToUInt64(value)) : new PyInt(Convert.ToInt64(value)); + [ForbidPythonThreads] +#pragma warning disable IDE1006 // Naming Styles - must match Python + public static PyInt __int__(T value) => __index__(value); +#pragma warning restore IDE1006 // Naming Styles } }