diff --git a/.travis.yml b/.travis.yml
index d728d9a2d..2062a35da 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,10 +2,11 @@ dist: xenial
sudo: false
language: python
python:
- - 2.7
- - 3.5
- - 3.6
+ - 3.8
- 3.7
+ - 3.6
+ - 3.5
+ - 2.7
env:
matrix:
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][]
diff --git a/appveyor.yml b/appveyor.yml
index 445f9bb5a..363e67389 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -15,24 +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
- BUILD_OPTS: --xplat
- - PYTHON_VERSION: 2.7
- PYTHON_VERSION: 3.5
- - PYTHON_VERSION: 3.6
+ BUILD_OPTS: --xplat
+ - PYTHON_VERSION: 2.7
+ BUILD_OPTS: --xplat
+ - PYTHON_VERSION: 3.8
- PYTHON_VERSION: 3.7
-
-matrix:
- allow_failures:
- - PYTHON_VERSION: 3.4
- BUILD_OPTS: --xplat
- - PYTHON_VERSION: 3.4
+ - PYTHON_VERSION: 3.6
+ - PYTHON_VERSION: 3.5
+ - PYTHON_VERSION: 2.7
init:
# Update Environment Variables based on matrix/platform
diff --git a/src/embed_tests/TestRuntime.cs b/src/embed_tests/TestRuntime.cs
index 157fe4cb7..4129d3df3 100644
--- a/src/embed_tests/TestRuntime.cs
+++ b/src/embed_tests/TestRuntime.cs
@@ -29,10 +29,7 @@ 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));
// 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 3d2610fea..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,16 +119,16 @@ public class Runtime
{ "Linux", OperatingSystemType.Linux },
};
- ///
- /// Gets the operating system as reported by python's platform.system().
- ///
- public static OperatingSystemType OperatingSystem { get; private set; }
+ [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().
///
- public static string OperatingSystemName { get; private set; }
-
+ public static OperatingSystemType OperatingSystem { get; private set; }
///
/// Map lower-case version of the python machine name to the processor
@@ -154,11 +155,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;
@@ -356,6 +352,7 @@ internal static void Initialize(bool initSigs = false)
///
private static void InitializePlatformData()
{
+#if !NETSTANDARD
IntPtr op;
IntPtr fn;
IntPtr platformModule = PyImport_ImportModule("platform");
@@ -363,13 +360,13 @@ 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);
fn = PyObject_GetAttrString(platformModule, "machine");
op = PyObject_Call(fn, emptyTuple, IntPtr.Zero);
- MachineName = GetManagedString(op);
+ string machineName = GetManagedString(op);
XDecref(op);
XDecref(fn);
@@ -379,18 +376,47 @@ 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;
}
OperatingSystem = OSType;
MachineType MType;
- if (!MachineTypeMapping.TryGetValue(MachineName.ToLower(), out MType))
+ if (!MachineTypeMapping.TryGetValue(machineName.ToLower(), out MType))
{
MType = MachineType.Other;
}
Machine = MType;
+#else
+ 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:
+ 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()
@@ -1966,6 +1992,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(BorrowedReference cell);
+
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int PyCell_Set(BorrowedReference cell, IntPtr value);
//====================================================================
// Miscellaneous
diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs
index bb920b74f..7d73b0138 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
+ 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__");
+ }
+
return py_type;
}
catch (Exception e)
@@ -617,7 +625,9 @@ 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 {Runtime.OperatingSystem}"
+ );
}
}
}
@@ -651,7 +661,9 @@ 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 {Runtime.OperatingSystem}"
+ );
}
}