| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -346,15 +346,25 @@ private static ClassInfo GetClassInfo(Type type, ClassBase impl) | |||
| 346 | 346 | } | |
| 347 | 347 | } | |
| 348 | 348 | ||
| 349 | - // only [Flags] enums support bitwise operations | ||
| 350 | - if (type.IsEnum && type.IsFlagsEnum()) | ||
| 349 | + if (type.IsEnum) | ||
| 351 | 350 | { | |
| 352 | 351 | var opsImpl = typeof(EnumOps<>).MakeGenericType(type); | |
| 353 | 352 | foreach (var op in opsImpl.GetMethods(OpsHelper.BindingFlags)) | |
| 354 | 353 | { | |
| 355 | 354 | local.Add(op.Name); | |
| 356 | 355 | } | |
| 357 | 356 | 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 | + } | ||
| 358 | 368 | } | |
| 359 | 369 | ||
| 360 | 370 | // Now again to filter w/o losing overloaded member info | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,6 +21,7 @@ interface ITypeOffsets | |||
| 21 | 21 | int nb_multiply { get; } | |
| 22 | 22 | int nb_true_divide { get; } | |
| 23 | 23 | int nb_and { get; } | |
| 24 | + int nb_int { get; } | ||
| 24 | 25 | int nb_or { get; } | |
| 25 | 26 | int nb_xor { get; } | |
| 26 | 27 | int nb_lshift { get; } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,6 +30,7 @@ static partial class TypeOffset | |||
| 30 | 30 | internal static int nb_and { get; private set; } | |
| 31 | 31 | internal static int nb_or { get; private set; } | |
| 32 | 32 | internal static int nb_xor { get; private set; } | |
| 33 | + internal static int nb_int { get; private set; } | ||
| 33 | 34 | internal static int nb_lshift { get; private set; } | |
| 34 | 35 | internal static int nb_rshift { get; private set; } | |
| 35 | 36 | internal static int nb_remainder { get; private set; } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,8 @@ | |||
| 1 | 1 | using System; | |
| 2 | 2 | using System.Collections.Generic; | |
| 3 | 3 | using System.Diagnostics; | |
| 4 | + using System.Linq; | ||
| 4 | 5 | using System.Reflection; | |
| 5 | - using System.Runtime.InteropServices; | ||
| 6 | 6 | using System.Text; | |
| 7 | 7 | ||
| 8 | 8 | namespace Python.Runtime | |
@@ -51,6 +51,8 @@ static OperatorMethod() | |||
| 51 | 51 | ["op_OnesComplement"] = new SlotDefinition("__invert__", TypeOffset.nb_invert), | |
| 52 | 52 | ["op_UnaryNegation"] = new SlotDefinition("__neg__", TypeOffset.nb_negative), | |
| 53 | 53 | ["op_UnaryPlus"] = new SlotDefinition("__pos__", TypeOffset.nb_positive), | |
| 54 | + | ||
| 55 | + ["__int__"] = new SlotDefinition("__int__", TypeOffset.nb_int), | ||
| 54 | 56 | }; | |
| 55 | 57 | ComparisonOpMap = new Dictionary<string, string> | |
| 56 | 58 | { | |
@@ -97,14 +99,11 @@ public static bool IsComparisonOp(MethodBase method) | |||
| 97 | 99 | /// </summary> | |
| 98 | 100 | public static void FixupSlots(BorrowedReference pyType, Type clrType) | |
| 99 | 101 | { | |
| 100 | - const BindingFlags flags = BindingFlags.Public | BindingFlags.Static; | ||
| 101 | 102 | Debug.Assert(_opType != null); | |
| 102 | 103 | ||
| 103 | - var staticMethods = | ||
| 104 | - clrType.IsEnum ? typeof(EnumOps<>).MakeGenericType(clrType).GetMethods(flags) | ||
| 105 | - : clrType.GetMethods(flags); | ||
| 104 | + var operatorCandidates = GetOperatorCandidates(clrType); | ||
| 106 | 105 | ||
| 107 | - foreach (var method in staticMethods) | ||
| 106 | + foreach (var method in operatorCandidates) | ||
| 108 | 107 | { | |
| 109 | 108 | // We only want to override slots for operators excluding | |
| 110 | 109 | // comparison operators, which are handled by ClassBase.tp_richcompare. | |
@@ -124,6 +123,18 @@ public static void FixupSlots(BorrowedReference pyType, Type clrType) | |||
| 124 | 123 | } | |
| 125 | 124 | } | |
| 126 | 125 | ||
| 126 | + static IEnumerable<MethodInfo> GetOperatorCandidates(Type clrType) | ||
| 127 | + { | ||
| 128 | + const BindingFlags flags = BindingFlags.Public | BindingFlags.Static; | ||
| 129 | + if (clrType.IsEnum) | ||
| 130 | + { | ||
| 131 | + return typeof(EnumOps<>).MakeGenericType(clrType).GetMethods(flags) | ||
| 132 | + .Concat(typeof(FlagEnumOps<>).MakeGenericType(clrType).GetMethods(flags)); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + return clrType.GetMethods(flags); | ||
| 136 | + } | ||
| 137 | + | ||
| 127 | 138 | public static string GetPyMethodName(string clrName) | |
| 128 | 139 | { | |
| 129 | 140 | if (OpMethodMap.ContainsKey(clrName)) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,7 +38,7 @@ public static Expression EnumUnderlyingValue(Expression enumValue) | |||
| 38 | 38 | internal class OpsAttribute: Attribute { } | |
| 39 | 39 | ||
| 40 | 40 | [Ops] | |
| 41 | - internal static class EnumOps<T> where T : Enum | ||
| 41 | + internal static class FlagEnumOps<T> where T : Enum | ||
| 42 | 42 | { | |
| 43 | 43 | static readonly Func<T, T, T> and = BinaryOp(Expression.And); | |
| 44 | 44 | static readonly Func<T, T, T> or = BinaryOp(Expression.Or); | |
@@ -74,4 +74,16 @@ static Func<T, T> UnaryOp(Func<Expression, UnaryExpression> op) | |||
| 74 | 74 | }); | |
| 75 | 75 | } | |
| 76 | 76 | } | |
| 77 | + | ||
| 78 | + [Ops] | ||
| 79 | + internal static class EnumOps<T> where T : Enum | ||
| 80 | + { | ||
| 81 | + [ForbidPythonThreads] | ||
| 82 | + #pragma warning disable IDE1006 // Naming Styles - must match Python | ||
| 83 | + public static PyInt __int__(T value) | ||
| 84 | + #pragma warning restore IDE1006 // Naming Styles | ||
| 85 | + => typeof(T).GetEnumUnderlyingType() == typeof(UInt64) | ||
| 86 | + ? new PyInt(Convert.ToUInt64(value)) | ||
| 87 | + : new PyInt(Convert.ToInt64(value)); | ||
| 88 | + } | ||
| 77 | 89 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -72,7 +72,9 @@ public enum LongEnum : long | |||
| 72 | 72 | Two, | |
| 73 | 73 | Three, | |
| 74 | 74 | Four, | |
| 75 | - Five | ||
| 75 | + Five, | ||
| 76 | + Max = long.MaxValue, | ||
| 77 | + Min = long.MinValue, | ||
| 76 | 78 | } | |
| 77 | 79 | ||
| 78 | 80 | public enum ULongEnum : ulong | |
@@ -82,7 +84,8 @@ public enum ULongEnum : ulong | |||
| 82 | 84 | Two, | |
| 83 | 85 | Three, | |
| 84 | 86 | Four, | |
| 85 | - Five | ||
| 87 | + Five, | ||
| 88 | + Max = ulong.MaxValue, | ||
| 86 | 89 | } | |
| 87 | 90 | ||
| 88 | 91 | [Flags] | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -87,6 +87,15 @@ def test_ulong_enum(): | |||
| 87 | 87 | assert Test.ULongEnum.Two == Test.ULongEnum(2) | |
| 88 | 88 | ||
| 89 | 89 | ||
| 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 | + | ||
| 90 | 99 | def test_instantiate_enum_fails(): | |
| 91 | 100 | """Test that instantiation of an enum class fails.""" | |
| 92 | 101 | from System import DayOfWeek | |
| Back | FazBrowse Home | New Git URL |
0 commit comments