From d98e2434170d0c8b94d69fcdbba457af5aa5a08b Mon Sep 17 00:00:00 2001 From: Victor Uriarte Date: Fri, 3 Feb 2017 16:07:06 -0700 Subject: [PATCH 1/3] Rename `is32bit` to `Is32Bit` for naming consistency --- src/runtime/converter.cs | 2 +- src/runtime/runtime.cs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 52637c3d5..0399a42d6 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -437,7 +437,7 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, bool setEr case TypeCode.Int32: #if PYTHON2 // Trickery to support 64-bit platforms. - if (Runtime.is32bit) + if (Runtime.Is32Bit) { op = Runtime.PyNumber_Int(value); diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 8fe435428..509192c26 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -170,14 +170,14 @@ public class Runtime internal static Object IsFinalizingLock = new Object(); internal static bool IsFinalizing = false; - internal static bool is32bit; + internal static bool Is32Bit; /// /// Initialize the runtime... /// internal static void Initialize() { - is32bit = IntPtr.Size == 4; + Is32Bit = IntPtr.Size == 4; if (Runtime.Py_IsInitialized() == 0) { @@ -501,7 +501,7 @@ internal unsafe static void XIncref(IntPtr op) void* p = (void*)op; if ((void*)0 != p) { - if (is32bit) + if (Is32Bit) { (*(int*)p)++; } @@ -524,7 +524,7 @@ internal static unsafe void XDecref(IntPtr op) void* p = (void*)op; if ((void*)0 != p) { - if (is32bit) + if (Is32Bit) { --(*(int*)p); } @@ -535,11 +535,11 @@ internal static unsafe void XDecref(IntPtr op) if ((*(int*)p) == 0) { // PyObject_HEAD: struct _typeobject *ob_type - void* t = is32bit + void* t = Is32Bit ? (void*)(*((uint*)p + 1)) : (void*)(*((ulong*)p + 1)); // PyTypeObject: destructor tp_dealloc - void* f = is32bit + void* f = Is32Bit ? (void*)(*((uint*)t + 6)) : (void*)(*((ulong*)t + 6)); if ((void*)0 == f) @@ -558,7 +558,7 @@ internal unsafe static long Refcount(IntPtr op) void* p = (void*)op; if ((void*)0 != p) { - if (is32bit) + if (Is32Bit) { return (*(int*)p); } @@ -887,7 +887,7 @@ internal unsafe static IntPtr #else int n = 1; #endif - if (is32bit) + if (Is32Bit) { return new IntPtr((void*)(*((uint*)p + n))); } From ea77ab0ab55fead179fa3a34776a35770152c1a1 Mon Sep 17 00:00:00 2001 From: Victor Uriarte Date: Fri, 3 Feb 2017 16:45:56 -0700 Subject: [PATCH 2/3] Replace UCS2/UCS4 build directive with Runtime.UCS --- src/runtime/converter.cs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 0399a42d6..f7cbf27be 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -613,17 +613,20 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, bool setEr if (Runtime.PyUnicode_GetSize(value) == 1) { op = Runtime.PyUnicode_AS_UNICODE(value); -#if UCS2 - // 2011-01-02: Marshal as character array because the cast - // result = (char)Marshal.ReadInt16(op); throws an OverflowException - // on negative numbers with Check Overflow option set on the project - Char[] buff = new Char[1]; - Marshal.Copy(op, buff, 0, 1); - result = buff[0]; -#elif UCS4 - // XXX this is probably NOT correct? - result = (char)Marshal.ReadInt32(op); -#endif + if (Runtime.UCS == 2) // Don't trust linter, statement not always true. + { + // 2011-01-02: Marshal as character array because the cast + // result = (char)Marshal.ReadInt16(op); throws an OverflowException + // on negative numbers with Check Overflow option set on the project + Char[] buff = new Char[1]; + Marshal.Copy(op, buff, 0, 1); + result = buff[0]; + } + else // UCS4 + { + // XXX this is probably NOT correct? + result = (char)Marshal.ReadInt32(op); + } return true; } goto type_error; From 587f318136427b9174820fec8418f3ae4f9dcfae Mon Sep 17 00:00:00 2001 From: Victor Uriarte Date: Fri, 3 Feb 2017 17:06:20 -0700 Subject: [PATCH 3/3] Add IsPython2 and IsPython3 --- src/runtime/converter.cs | 20 ++++++++------------ src/runtime/exceptions.cs | 14 +++++--------- src/runtime/importhook.cs | 20 +++++++++++++------- src/runtime/runtime.cs | 24 +++++++++++++++++------- 4 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index f7cbf27be..392e02ae8 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -82,14 +82,14 @@ internal static IntPtr GetPythonTypeByAlias(Type op) { return Runtime.PyUnicodeType; } -#if PYTHON3 - else if ((op == int16Type) || - (op == int32Type) || - (op == int64Type)) + + else if (Runtime.IsPython3 && ((op == int16Type) || + (op == int32Type) || + (op == int64Type))) { return Runtime.PyIntType; } -#endif + else if ((op == int16Type) || (op == int32Type)) { @@ -435,9 +435,8 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, bool setEr return true; case TypeCode.Int32: -#if PYTHON2 // Trickery to support 64-bit platforms. - - if (Runtime.Is32Bit) + // Trickery to support 64-bit platforms. + if (Runtime.IsPython2 && Runtime.Is32Bit) { op = Runtime.PyNumber_Int(value); @@ -461,11 +460,8 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, bool setEr result = ival; return true; } - else + else // Python3 always use PyLong API { -#elif PYTHON3 // When using Python3 always use the PyLong API - { -#endif op = Runtime.PyNumber_Long(value); if (op == IntPtr.Zero) { diff --git a/src/runtime/exceptions.cs b/src/runtime/exceptions.cs index dbdd9a67b..01a8ab585 100644 --- a/src/runtime/exceptions.cs +++ b/src/runtime/exceptions.cs @@ -81,17 +81,14 @@ private Exceptions() /// internal static void Initialize() { -#if PYTHON3 - exceptions_module = Runtime.PyImport_ImportModule("builtins"); -#elif PYTHON2 - exceptions_module = Runtime.PyImport_ImportModule("exceptions"); -#endif + string exceptionsModuleName = Runtime.IsPython3 ? "builtins" : "exceptions"; + exceptions_module = Runtime.PyImport_ImportModule(exceptionsModuleName); + Exceptions.ErrorCheck(exceptions_module); warnings_module = Runtime.PyImport_ImportModule("warnings"); Exceptions.ErrorCheck(warnings_module); Type type = typeof(Exceptions); - foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | - BindingFlags.Static)) + foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Static)) { IntPtr op = Runtime.PyObject_GetAttrString(exceptions_module, fi.Name); if (op != IntPtr.Zero) @@ -116,8 +113,7 @@ internal static void Shutdown() if (Runtime.Py_IsInitialized() != 0) { Type type = typeof(Exceptions); - foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | - BindingFlags.Static)) + foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Static)) { var op = (IntPtr)fi.GetValue(type); if (op != IntPtr.Zero) diff --git a/src/runtime/importhook.cs b/src/runtime/importhook.cs index df3877c29..bb70a6167 100644 --- a/src/runtime/importhook.cs +++ b/src/runtime/importhook.cs @@ -35,11 +35,11 @@ internal static void Initialize() // but it provides the most "Pythonic" way of dealing with CLR // modules (Python doesn't provide a way to emulate packages). IntPtr dict = Runtime.PyImport_GetModuleDict(); -#if PYTHON3 - IntPtr mod = Runtime.PyImport_ImportModule("builtins"); -#elif PYTHON2 - IntPtr mod = Runtime.PyDict_GetItemString(dict, "__builtin__"); -#endif + + IntPtr mod = Runtime.IsPython3 + ? Runtime.PyImport_ImportModule("builtins") + : Runtime.PyDict_GetItemString(dict, "__builtin__"); + py_import = Runtime.PyObject_GetAttrString(mod, "__import__"); hook = new MethodWrapper(typeof(ImportHook), "__import__", "TernaryFunc"); Runtime.PyObject_SetAttrString(mod, "__import__", hook.ptr); @@ -86,7 +86,14 @@ internal static void Shutdown() public static IntPtr GetCLRModule(IntPtr? fromList = null) { root.InitializePreload(); -#if PYTHON3 + + if (Runtime.IsPython2) + { + Runtime.XIncref(py_clr_module); + return py_clr_module; + } + + // Python 3 // update the module dictionary with the contents of the root dictionary root.LoadNames(); IntPtr py_mod_dict = Runtime.PyModule_GetDict(py_clr_module); @@ -135,7 +142,6 @@ public static IntPtr GetCLRModule(IntPtr? fromList = null) } } } -#endif Runtime.XIncref(py_clr_module); return py_clr_module; } diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 509192c26..c6f3551df 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -171,6 +171,8 @@ public class Runtime internal static bool IsFinalizing = false; internal static bool Is32Bit; + internal static bool IsPython2; + internal static bool IsPython3; /// /// Initialize the runtime... @@ -178,6 +180,8 @@ public class Runtime internal static void Initialize() { Is32Bit = IntPtr.Size == 4; + IsPython2 = pyversionnumber < 30; + IsPython3 = pyversionnumber >= 30; if (Runtime.Py_IsInitialized() == 0) { @@ -189,13 +193,19 @@ internal static void Initialize() Runtime.PyEval_InitThreads(); } -#if PYTHON3 - IntPtr op = Runtime.PyImport_ImportModule("builtins"); - IntPtr dict = Runtime.PyObject_GetAttrString(op, "__dict__"); -#elif PYTHON2 - IntPtr dict = Runtime.PyImport_GetModuleDict(); - IntPtr op = Runtime.PyDict_GetItemString(dict, "__builtin__"); -#endif + IntPtr op; + IntPtr dict; + if (IsPython3) + { + op = Runtime.PyImport_ImportModule("builtins"); + dict = Runtime.PyObject_GetAttrString(op, "__dict__"); + + } + else // Python2 + { + dict = Runtime.PyImport_GetModuleDict(); + op = Runtime.PyDict_GetItemString(dict, "__builtin__"); + } PyNotImplemented = Runtime.PyObject_GetAttrString(op, "NotImplemented"); PyBaseObjectType = Runtime.PyObject_GetAttrString(op, "object");