|
1 | 1 | using System;
|
2 | 2 | using System.Diagnostics;
|
| 3 | +using System.Globalization; |
3 | 4 | using System.Linq;
|
4 | 5 | using System.Reflection;
|
| 6 | +using System.Runtime.InteropServices; |
5 | 7 | using System.Runtime.Serialization;
|
6 | 8 |
|
7 | 9 | namespace Python.Runtime
|
@@ -47,6 +49,55 @@ internal NewReference GetDocString()
|
47 | 49 | return Runtime.PyString_FromString(str);
|
48 | 50 | }
|
49 | 51 |
|
| 52 | + private static string ConvertFlags(Enum value) |
| 53 | + { |
| 54 | + Type primitiveType = value.GetType().GetEnumUnderlyingType(); |
| 55 | + string format = "X" + (Marshal.SizeOf(primitiveType) * 2).ToString(CultureInfo.InvariantCulture); |
| 56 | + var primitive = (IFormattable)Convert.ChangeType(value, primitiveType); |
| 57 | + return "0x" + primitive.ToString(format, null); |
| 58 | + |
| 59 | + } |
| 60 | + |
| 61 | + private static string ConvertValue(Enum value) |
| 62 | + { |
| 63 | + Type primitiveType = value.GetType().GetEnumUnderlyingType(); |
| 64 | + return Convert.ChangeType(value, primitiveType).ToString()!; |
| 65 | + } |
| 66 | + |
| 67 | + /// <summary> |
| 68 | + /// given an enum, write a __repr__ string formatted in the same |
| 69 | + /// way as a python repr string. Something like: |
| 70 | + /// '<Color.GREEN: 2>'; |
| 71 | + /// with a binary value for [Flags] enums |
| 72 | + /// </summary> |
| 73 | + /// <param name="inst">Instace of the enum object</param> |
| 74 | + /// <returns></returns> |
| 75 | + private static string GetEnumReprString(Enum inst) |
| 76 | + { |
| 77 | + var obType = inst.GetType(); |
| 78 | + |
| 79 | + string strValue2 = obType.IsFlagsEnum() ? ConvertFlags(inst) : ConvertValue(inst); |
| 80 | + |
| 81 | + var repr = $"<{obType.Name}.{inst}: {strValue2}>"; |
| 82 | + return repr; |
| 83 | + } |
| 84 | + |
| 85 | + /// <summary> |
| 86 | + /// ClassObject __repr__ implementation. |
| 87 | + /// </summary> |
| 88 | + public new static NewReference tp_repr(BorrowedReference ob) |
| 89 | + { |
| 90 | + if (GetManagedObject(ob) is not CLRObject co) |
| 91 | + { |
| 92 | + return Exceptions.RaiseTypeError("invalid object"); |
| 93 | + } |
| 94 | + if (co.inst.GetType().IsEnum) |
| 95 | + { |
| 96 | + return Runtime.PyString_FromString(GetEnumReprString((Enum)co.inst)); |
| 97 | + } |
| 98 | + |
| 99 | + return ClassBase.tp_repr(ob); |
| 100 | + } |
50 | 101 |
|
51 | 102 | /// <summary>
|
52 | 103 | /// Implements __new__ for reflected classes and value types.
|
|
0 commit comments