From d4eac3afb96112be76d97683d28fbaa7bbfa1dbf Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Sun, 10 May 2020 16:34:22 +0200 Subject: [PATCH 1/8] Reactivate Python 3.8 CI build --- .travis.yml | 1 + appveyor.yml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index d728d9a2d..b5e358c30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: - 3.5 - 3.6 - 3.7 + - 3.8 env: matrix: diff --git a/appveyor.yml b/appveyor.yml index 445f9bb5a..73c84381b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,10 +23,13 @@ environment: BUILD_OPTS: --xplat - PYTHON_VERSION: 3.7 BUILD_OPTS: --xplat + - PYTHON_VERSION: 3.8 + BUILD_OPTS: --xplat - PYTHON_VERSION: 2.7 - PYTHON_VERSION: 3.5 - PYTHON_VERSION: 3.6 - PYTHON_VERSION: 3.7 + - PYTHON_VERSION: 3.8 matrix: allow_failures: From b17b9d3a0e0ce13d32995dc16c36d34664ab8317 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 15 May 2020 00:44:43 +0200 Subject: [PATCH 2/8] Set __classcell__ if it exists If `PyCell_Set` is not called with a cell it will raise an exception, which is perfectly valid here. --- src/runtime/runtime.cs | 9 +++++++++ src/runtime/typemanager.cs | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 3d2610fea..5d5e6e68e 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -1966,6 +1966,15 @@ internal static IntPtr PyMem_Realloc(IntPtr ptr, long size) [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] internal static extern void PyErr_Print(); + //==================================================================== + // Cell API + //==================================================================== + + [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] + internal static extern NewReference PyCell_Get(IntPtr cell); + + [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] + internal static extern int PyCell_Set(IntPtr cell, IntPtr value); //==================================================================== // Miscellaneous diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs index bb920b74f..8658c937a 100644 --- a/src/runtime/typemanager.cs +++ b/src/runtime/typemanager.cs @@ -280,6 +280,14 @@ internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr IntPtr cls_dict = Marshal.ReadIntPtr(py_type, TypeOffset.tp_dict); Runtime.PyDict_Update(cls_dict, py_dict); + // Update the __classcell__ if it exists + IntPtr cell = Runtime.PyDict_GetItemString(cls_dict, "__classcell__"); + if (cell != IntPtr.Zero) + { + Runtime.PyCell_Set(cell, py_type); + Runtime.PyDict_DelItemString(cls_dict, "__classcell__"); + } + return py_type; } catch (Exception e) From a9b91a3405d972cf3f8b96c669919a4537113d9a Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 15 May 2020 19:08:13 +0200 Subject: [PATCH 3/8] Make the newest python versions run first in CI --- .travis.yml | 8 ++++---- appveyor.yml | 22 ++++++++-------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index b5e358c30..2062a35da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,11 @@ dist: xenial sudo: false language: python python: - - 2.7 - - 3.5 - - 3.6 - - 3.7 - 3.8 + - 3.7 + - 3.6 + - 3.5 + - 2.7 env: matrix: diff --git a/appveyor.yml b/appveyor.yml index 73c84381b..363e67389 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,27 +15,21 @@ environment: CODECOV_ENV: PYTHON_VERSION, PLATFORM matrix: - - PYTHON_VERSION: 2.7 + - PYTHON_VERSION: 3.8 BUILD_OPTS: --xplat - - PYTHON_VERSION: 3.5 + - PYTHON_VERSION: 3.7 BUILD_OPTS: --xplat - PYTHON_VERSION: 3.6 BUILD_OPTS: --xplat - - PYTHON_VERSION: 3.7 + - PYTHON_VERSION: 3.5 BUILD_OPTS: --xplat - - PYTHON_VERSION: 3.8 + - PYTHON_VERSION: 2.7 BUILD_OPTS: --xplat - - PYTHON_VERSION: 2.7 - - PYTHON_VERSION: 3.5 - - PYTHON_VERSION: 3.6 - - PYTHON_VERSION: 3.7 - PYTHON_VERSION: 3.8 - -matrix: - allow_failures: - - PYTHON_VERSION: 3.4 - BUILD_OPTS: --xplat - - PYTHON_VERSION: 3.4 + - PYTHON_VERSION: 3.7 + - PYTHON_VERSION: 3.6 + - PYTHON_VERSION: 3.5 + - PYTHON_VERSION: 2.7 init: # Update Environment Variables based on matrix/platform From e213a9745da46b02ab9c29b5949890aa9da7ca75 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 15 May 2020 19:09:03 +0200 Subject: [PATCH 4/8] Implement InitializePlatformData without calling Python --- src/runtime/runtime.cs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 5d5e6e68e..eea04b64d 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -356,6 +356,7 @@ internal static void Initialize(bool initSigs = false) /// private static void InitializePlatformData() { +#if !NETSTANDARD IntPtr op; IntPtr fn; IntPtr platformModule = PyImport_ImportModule("platform"); @@ -391,6 +392,34 @@ private static void InitializePlatformData() MType = MachineType.Other; } Machine = MType; +#else + OperatingSystem = OperatingSystemType.Other; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + OperatingSystem = OperatingSystemType.Linux; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + OperatingSystem = OperatingSystemType.Darwin; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + OperatingSystem = OperatingSystemType.Windows; + + switch (RuntimeInformation.ProcessArchitecture) + { + case Architecture.X86: + Machine = MachineType.i386; + break; + case Architecture.X64: + Machine = MachineType.x86_64; + break; + case Architecture.Arm: + Machine = MachineType.armv7l; + break; + case Architecture.Arm64: + Machine = MachineType.aarch64; + break; + default: + Machine = MachineType.Other; + break; + } +#endif } internal static void Shutdown() From a7949b9ff0d0e3fd6fd64b7fc0b82111dfbaebbb Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 15 May 2020 19:23:49 +0200 Subject: [PATCH 5/8] Stop exposing Python's MachineName on Runtime --- src/embed_tests/TestRuntime.cs | 2 -- src/runtime/runtime.cs | 9 ++------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/embed_tests/TestRuntime.cs b/src/embed_tests/TestRuntime.cs index 157fe4cb7..6ab8e18c7 100644 --- a/src/embed_tests/TestRuntime.cs +++ b/src/embed_tests/TestRuntime.cs @@ -29,8 +29,6 @@ public static void PlatformCache() Runtime.Runtime.Initialize(); Assert.That(Runtime.Runtime.Machine, Is.Not.EqualTo(MachineType.Other)); - Assert.That(!string.IsNullOrEmpty(Runtime.Runtime.MachineName)); - Assert.That(Runtime.Runtime.OperatingSystem, Is.Not.EqualTo(OperatingSystemType.Other)); Assert.That(!string.IsNullOrEmpty(Runtime.Runtime.OperatingSystemName)); diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index eea04b64d..5ed3ed824 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -154,11 +154,6 @@ public class Runtime /// public static MachineType Machine { get; private set; }/* set in Initialize using python's platform.machine */ - /// - /// Gets the machine architecture as reported by python's platform.machine(). - /// - public static string MachineName { get; private set; } - internal static bool IsPython2 = pyversionnumber < 30; internal static bool IsPython3 = pyversionnumber >= 30; @@ -370,7 +365,7 @@ private static void InitializePlatformData() fn = PyObject_GetAttrString(platformModule, "machine"); op = PyObject_Call(fn, emptyTuple, IntPtr.Zero); - MachineName = GetManagedString(op); + string machineName = GetManagedString(op); XDecref(op); XDecref(fn); @@ -387,7 +382,7 @@ private static void InitializePlatformData() OperatingSystem = OSType; MachineType MType; - if (!MachineTypeMapping.TryGetValue(MachineName.ToLower(), out MType)) + if (!MachineTypeMapping.TryGetValue(machineName.ToLower(), out MType)) { MType = MachineType.Other; } From c6ae15b6cb71bd22e67b4d32e3267f3e74012e1f Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 15 May 2020 19:50:16 +0200 Subject: [PATCH 6/8] Drop OperatingSystemName from the interface as well --- src/embed_tests/TestRuntime.cs | 1 - src/runtime/runtime.cs | 15 +++++---------- src/runtime/typemanager.cs | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/embed_tests/TestRuntime.cs b/src/embed_tests/TestRuntime.cs index 6ab8e18c7..4129d3df3 100644 --- a/src/embed_tests/TestRuntime.cs +++ b/src/embed_tests/TestRuntime.cs @@ -30,7 +30,6 @@ public static void PlatformCache() Assert.That(Runtime.Runtime.Machine, Is.Not.EqualTo(MachineType.Other)); Assert.That(Runtime.Runtime.OperatingSystem, Is.Not.EqualTo(OperatingSystemType.Other)); - Assert.That(!string.IsNullOrEmpty(Runtime.Runtime.OperatingSystemName)); // Don't shut down the runtime: if the python engine was initialized // but not shut down by another test, we'd end up in a bad state. diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 5ed3ed824..2893f141a 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -123,12 +123,6 @@ public class Runtime /// public static OperatingSystemType OperatingSystem { get; private set; } - /// - /// Gets the operating system as reported by python's platform.system(). - /// - public static string OperatingSystemName { get; private set; } - - /// /// Map lower-case version of the python machine name to the processor /// type. There are aliases, e.g. x86_64 and amd64 are two names for @@ -359,7 +353,7 @@ private static void InitializePlatformData() fn = PyObject_GetAttrString(platformModule, "system"); op = PyObject_Call(fn, emptyTuple, IntPtr.Zero); - OperatingSystemName = GetManagedString(op); + string operatingSystemName = GetManagedString(op); XDecref(op); XDecref(fn); @@ -375,7 +369,7 @@ private static void InitializePlatformData() // Now convert the strings into enum values so we can do switch // statements rather than constant parsing. OperatingSystemType OSType; - if (!OperatingSystemTypeMapping.TryGetValue(OperatingSystemName, out OSType)) + if (!OperatingSystemTypeMapping.TryGetValue(operatingSystemName, out OSType)) { OSType = OperatingSystemType.Other; } @@ -388,14 +382,15 @@ private static void InitializePlatformData() } Machine = MType; #else - OperatingSystem = OperatingSystemType.Other; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) OperatingSystem = OperatingSystemType.Linux; else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) OperatingSystem = OperatingSystemType.Darwin; else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) OperatingSystem = OperatingSystemType.Windows; - + else + OperatingSystem = OperatingSystemType.Other; + switch (RuntimeInformation.ProcessArchitecture) { case Architecture.X86: diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs index 8658c937a..f984e5d87 100644 --- a/src/runtime/typemanager.cs +++ b/src/runtime/typemanager.cs @@ -625,7 +625,7 @@ int MAP_ANONYMOUS case OperatingSystemType.Linux: return 0x20; default: - throw new NotImplementedException($"mmap is not supported on {Runtime.OperatingSystemName}"); + throw new NotImplementedException($"mmap is not supported on this operating system"); } } } @@ -659,7 +659,7 @@ internal static IMemoryMapper CreateMemoryMapper() case OperatingSystemType.Windows: return new WindowsMemoryMapper(); default: - throw new NotImplementedException($"No support for {Runtime.OperatingSystemName}"); + throw new NotImplementedException($"No support for this operating system"); } } From 8e54d2686937017fc442e8e204bd84ff1fea91c1 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Sat, 16 May 2020 00:17:30 +0200 Subject: [PATCH 7/8] Code review adjustments - Use `BorrowedReference` where applicable - Readd `OperatingSystemName` and `MachineName` for now --- src/runtime/runtime.cs | 11 +++++++++-- src/runtime/typemanager.cs | 12 ++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 2893f141a..0e391a134 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -1,3 +1,4 @@ +using System.Reflection.Emit; using System; using System.Diagnostics.Contracts; using System.Runtime.InteropServices; @@ -118,6 +119,12 @@ public class Runtime { "Linux", OperatingSystemType.Linux }, }; + [Obsolete] + public static string OperatingSystemName => OperatingSystem.ToString(); + + [Obsolete] + public static string MachineName => Machine.ToString(); + /// /// Gets the operating system as reported by python's platform.system(). /// @@ -1990,10 +1997,10 @@ internal static IntPtr PyMem_Realloc(IntPtr ptr, long size) //==================================================================== [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] - internal static extern NewReference PyCell_Get(IntPtr cell); + internal static extern NewReference PyCell_Get(BorrowedReference cell); [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] - internal static extern int PyCell_Set(IntPtr cell, IntPtr value); + internal static extern int PyCell_Set(BorrowedReference cell, IntPtr value); //==================================================================== // Miscellaneous diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs index f984e5d87..7d73b0138 100644 --- a/src/runtime/typemanager.cs +++ b/src/runtime/typemanager.cs @@ -281,8 +281,8 @@ internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr Runtime.PyDict_Update(cls_dict, py_dict); // Update the __classcell__ if it exists - IntPtr cell = Runtime.PyDict_GetItemString(cls_dict, "__classcell__"); - if (cell != IntPtr.Zero) + var cell = new BorrowedReference(Runtime.PyDict_GetItemString(cls_dict, "__classcell__")); + if (!cell.IsNull) { Runtime.PyCell_Set(cell, py_type); Runtime.PyDict_DelItemString(cls_dict, "__classcell__"); @@ -625,7 +625,9 @@ int MAP_ANONYMOUS case OperatingSystemType.Linux: return 0x20; default: - throw new NotImplementedException($"mmap is not supported on this operating system"); + throw new NotImplementedException( + $"mmap is not supported on {Runtime.OperatingSystem}" + ); } } } @@ -659,7 +661,9 @@ internal static IMemoryMapper CreateMemoryMapper() case OperatingSystemType.Windows: return new WindowsMemoryMapper(); default: - throw new NotImplementedException($"No support for this operating system"); + throw new NotImplementedException( + $"No support for {Runtime.OperatingSystem}" + ); } } From ed2b7e8605c2c3e3b546b97dec70c8ad888ce2c5 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Sat, 16 May 2020 18:59:24 +0200 Subject: [PATCH 8/8] Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3f801841..3cbf85d45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. - Added PythonException.Format method to format exceptions the same as traceback.format_exception - Added Runtime.None to be able to pass None as parameter into Python from .NET - Added PyObject.IsNone() to check if a Python object is None in .NET. +- Support for Python 3.8 ### Changed @@ -29,6 +30,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. - Added support for kwarg parameters when calling .NET methods from Python - Changed method for finding MSBuild using vswhere - Reworked `Finalizer`. Now objects drop into its queue upon finalization, which is periodically drained when new objects are created. +- Marked `Runtime.OperatingSystemName` and `Runtime.MachineName` as `Obsolete`, should never have been `public` in the first place. They also don't necessarily return a result that matches the `platform` module's. ### Fixed @@ -37,6 +39,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. - Fixes bug where delegates get casts (dotnetcore) - Determine size of interpreter longs at runtime - Handling exceptions ocurred in ModuleObject's getattribute +- Fill `__classcell__` correctly for Python subclasses of .NET types ## [2.4.0][]