Skip to content

Commit 0916b0b

Browse files
committed
provide __int__ instance method on .NET enum types to support int(Enum.Member)
implements pythonnet#1585
1 parent 8d6a918 commit 0916b0b

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed

src/runtime/classmanager.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,26 @@ private static ClassInfo GetClassInfo(Type type)
345345
}
346346
}
347347

348-
// only [Flags] enums support bitwise operations
349-
if (type.IsEnum && type.IsFlagsEnum())
348+
349+
if (type.IsEnum)
350350
{
351351
var opsImpl = typeof(EnumOps<>).MakeGenericType(type);
352352
foreach (var op in opsImpl.GetMethods(OpsHelper.BindingFlags))
353353
{
354354
local.Add(op.Name);
355355
}
356356
info = info.Concat(opsImpl.GetMethods(OpsHelper.BindingFlags)).ToArray();
357+
358+
// only [Flags] enums support bitwise operations
359+
if (type.IsFlagsEnum())
360+
{
361+
opsImpl = typeof(FlagEnumOps<>).MakeGenericType(type);
362+
foreach (var op in opsImpl.GetMethods(OpsHelper.BindingFlags))
363+
{
364+
local.Add(op.Name);
365+
}
366+
info = info.Concat(opsImpl.GetMethods(OpsHelper.BindingFlags)).ToArray();
367+
}
357368
}
358369

359370
// Now again to filter w/o losing overloaded member info

src/runtime/operatormethod.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public static void FixupSlots(BorrowedReference pyType, Type clrType)
101101
Debug.Assert(_opType != null);
102102

103103
var staticMethods =
104-
clrType.IsEnum ? typeof(EnumOps<>).MakeGenericType(clrType).GetMethods(flags)
104+
clrType.IsEnum ? typeof(FlagEnumOps<>).MakeGenericType(clrType).GetMethods(flags)
105105
: clrType.GetMethods(flags);
106106

107107
foreach (var method in staticMethods)

src/runtime/opshelper.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static Expression EnumUnderlyingValue(Expression enumValue)
3838
internal class OpsAttribute: Attribute { }
3939

4040
[Ops]
41-
internal static class EnumOps<T> where T : Enum
41+
internal static class FlagEnumOps<T> where T : Enum
4242
{
4343
static readonly Func<T, T, T> and = BinaryOp(Expression.And);
4444
static readonly Func<T, T, T> or = BinaryOp(Expression.Or);
@@ -74,4 +74,14 @@ static Func<T, T> UnaryOp(Func<Expression, UnaryExpression> op)
7474
});
7575
}
7676
}
77+
78+
[Ops]
79+
internal static class EnumOps<T> where T : Enum
80+
{
81+
[ForbidPythonThreads]
82+
public static PyInt __int__(T value)
83+
=> typeof(T).GetEnumUnderlyingType() == typeof(UInt64)
84+
? new PyInt(Convert.ToUInt64(value))
85+
: new PyInt(Convert.ToInt64(value));
86+
}
7787
}

src/testing/enumtest.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ public enum LongEnum : long
7272
Two,
7373
Three,
7474
Four,
75-
Five
75+
Five,
76+
Max = long.MaxValue,
77+
Min = long.MinValue,
7678
}
7779

7880
public enum ULongEnum : ulong
@@ -82,7 +84,8 @@ public enum ULongEnum : ulong
8284
Two,
8385
Three,
8486
Four,
85-
Five
87+
Five,
88+
Max = ulong.MaxValue,
8689
}
8790

8891
[Flags]

tests/test_enum.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ def test_ulong_enum():
8787
assert Test.ULongEnum.Two == Test.ULongEnum(2)
8888

8989

90+
def test_long_enum_to_int():
91+
assert int(Test.LongEnum.Max) == 9223372036854775807
92+
assert int(Test.LongEnum.Min) == -9223372036854775808
93+
94+
95+
def test_ulong_enum_to_int():
96+
assert int(Test.ULongEnum.Max) == 18446744073709551615
97+
98+
9099
def test_instantiate_enum_fails():
91100
"""Test that instantiation of an enum class fails."""
92101
from System import DayOfWeek

0 commit comments

Comments
 (0)