diff --git a/.travis.yml b/.travis.yml index 2468ed60a..627fd9ebf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -169,6 +169,7 @@ install: script: - python -m pytest - mono $NUNIT_PATH src/embed_tests/bin/Python.EmbeddingTest.dll + - if [[ $BUILD_OPTS == --xplat ]]; then dotnet src/embed_tests/bin/netcoreapp2.0_publish/Python.EmbeddingTest.dll; fi after_script: # Uncomment if need to geninterop, ie. py37 final diff --git a/CHANGELOG.md b/CHANGELOG.md index e5929107b..7d408a8d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. ## [unreleased][] ### Added +- Added support for embedding python into dotnet core 2.0 (NetStandard 2.0) - Added new build system (pythonnet.15.sln) based on dotnetcore-sdk/xplat(crossplatform msbuild). Currently there two side-by-side build systems that produces the same output (net40) from the same sources. After a some transition time, current (mono/ msbuild 14.0) build system will be removed. diff --git a/appveyor.yml b/appveyor.yml index c7c3a7810..1953d85d5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -43,6 +43,8 @@ init: install: - pip install --upgrade -r requirements.txt --quiet - choco install vswhere -y + - cmd: curl -O https://download.microsoft.com/download/5/6/B/56BFEF92-9045-4414-970C-AB31E0FC07EC/dotnet-runtime-2.0.0-win-x86.exe + - cmd: dotnet-runtime-2.0.0-win-x86.exe /install /quiet /norestart /log install.log # Install OpenCover. Can't put on `packages.config`, not Mono compatible - .\tools\nuget\nuget.exe install OpenCover -OutputDirectory packages -Verbosity quiet diff --git a/ci/appveyor_run_tests.ps1 b/ci/appveyor_run_tests.ps1 index 2821cf915..b45440fbe 100644 --- a/ci/appveyor_run_tests.ps1 +++ b/ci/appveyor_run_tests.ps1 @@ -44,6 +44,23 @@ if ($CS_STATUS -ne 0) { Write-Host "Embedded tests failed" -ForegroundColor "Red" } +if ($env:BUILD_OPTS -eq "--xplat"){ + if ($env:PLATFORM -eq "x64") { + $DOTNET_CMD = "dotnet" + } + else{ + $DOTNET_CMD = "c:\Program Files (x86)\dotnet\dotnet" + } + + # Run Embedded tests for netcoreapp2.0 (OpenCover currently does not supports dotnet core) + Write-Host ("Starting embedded tests for netcoreapp2.0") -ForegroundColor "Green" + &$DOTNET_CMD .\src\embed_tests\bin\netcoreapp2.0_publish\Python.EmbeddingTest.dll + $CS_STATUS = $LastExitCode + if ($CS_STATUS -ne 0) { + Write-Host "Embedded tests for netcoreapp2.0 failed" -ForegroundColor "Red" + } +} + # Set exit code to fail if either Python or Embedded tests failed if ($PYTHON_STATUS -ne 0 -or $CS_STATUS -ne 0) { Write-Host "Tests failed" -ForegroundColor "Red" diff --git a/pythonnet.15.sln b/pythonnet.15.sln index 121631e43..f2015e480 100644 --- a/pythonnet.15.sln +++ b/pythonnet.15.sln @@ -2,15 +2,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26730.3 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.Runtime.15", "src\runtime\Python.Runtime.15.csproj", "{2759F4FF-716B-4828-916F-50FA86613DFC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.Runtime.15", "src/runtime/Python.Runtime.15.csproj", "{2759F4FF-716B-4828-916F-50FA86613DFC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.EmbeddingTest.15", "src\embed_tests\Python.EmbeddingTest.15.csproj", "{66B8D01A-9906-452A-B09E-BF75EA76468F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.EmbeddingTest.15", "src/embed_tests/Python.EmbeddingTest.15.csproj", "{66B8D01A-9906-452A-B09E-BF75EA76468F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "clrmodule.15", "src\clrmodule\clrmodule.15.csproj", "{E08678D4-9A52-4AD5-B63D-8EBC7399981B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "clrmodule.15", "src/clrmodule/clrmodule.15.csproj", "{E08678D4-9A52-4AD5-B63D-8EBC7399981B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Console.15", "src\console\Console.15.csproj", "{CDAD305F-8E72-492C-A314-64CF58D472A0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Console.15", "src/console/Console.15.csproj", "{CDAD305F-8E72-492C-A314-64CF58D472A0}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.Test.15", "src\testing\Python.Test.15.csproj", "{F94B547A-E97E-4500-8D53-B4D64D076E5F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.Test.15", "src/testing/Python.Test.15.csproj", "{F94B547A-E97E-4500-8D53-B4D64D076E5F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/setup.py b/setup.py index 6cfd773a6..24557c137 100644 --- a/setup.py +++ b/setup.py @@ -257,6 +257,8 @@ def build_extension(self, ext): subprocess.check_call(" ".join(cmd + ["/t:Clean"]), shell=use_shell) subprocess.check_call(" ".join(cmd + ["/t:Build"]), shell=use_shell) + if DEVTOOLS == "MsDev15" or DEVTOOLS == "dotnet": + subprocess.check_call(" ".join(cmd + ['"/t:Console_15:publish;Python_EmbeddingTest_15:publish"', "/p:TargetFramework=netcoreapp2.0"]), shell=use_shell) if DEVTOOLS == "Mono" or DEVTOOLS == "dotnet": self._build_monoclr() diff --git a/src/clrmodule/clrmodule.15.csproj b/src/clrmodule/clrmodule.15.csproj index 4d8a1b8ff..e97c6fe1b 100644 --- a/src/clrmodule/clrmodule.15.csproj +++ b/src/clrmodule/clrmodule.15.csproj @@ -22,6 +22,7 @@ 1591 ..\..\ $(SolutionDir)\bin\ + $(PythonBuildDir)\$(TargetFramework)\ 6 prompt $(PYTHONNET_DEFINE_CONSTANTS) diff --git a/src/console/Console.15.csproj b/src/console/Console.15.csproj index 0c89fce40..ed9d3d8f9 100644 --- a/src/console/Console.15.csproj +++ b/src/console/Console.15.csproj @@ -1,7 +1,7 @@ - net40 + net40;netcoreapp2.0 x64;x86 DebugMono;DebugMonoPY3;ReleaseMono;ReleaseMonoPY3;DebugWin;DebugWinPY3;ReleaseWin;ReleaseWinPY3 Exe @@ -15,12 +15,14 @@ false false false - bin\nPython.xml bin\ - false + false + $(OutputPath)\$(AssemblyName).xml + $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml 1591 ..\..\ $(SolutionDir)\bin\ + $(PythonBuildDir)\$(TargetFramework)\ 6 python-clear.ico prompt @@ -89,7 +91,7 @@ - + Python.Runtime.dll @@ -100,6 +102,6 @@ - + diff --git a/src/console/pythonconsole.cs b/src/console/pythonconsole.cs index e9bb31e69..912e9bb0d 100644 --- a/src/console/pythonconsole.cs +++ b/src/console/pythonconsole.cs @@ -16,8 +16,9 @@ namespace Python.Runtime /// public sealed class PythonConsole { +#if NET40 private static AssemblyLoader assemblyLoader = new AssemblyLoader(); - +#endif private PythonConsole() { } @@ -25,9 +26,11 @@ private PythonConsole() [STAThread] public static int Main(string[] args) { + // Only net40 is capable to safely inject python.runtime.dll into resources. +#if NET40 // reference the static assemblyLoader to stop it being optimized away AssemblyLoader a = assemblyLoader; - +#endif string[] cmd = Environment.GetCommandLineArgs(); PythonEngine.Initialize(); @@ -37,6 +40,7 @@ public static int Main(string[] args) return i; } +#if NET40 // Register a callback function to load embedded assemblies. // (Python.Runtime.dll is included as a resource) private sealed class AssemblyLoader @@ -73,5 +77,6 @@ public AssemblyLoader() }; } } +#endif } } diff --git a/src/embed_tests/Program.cs b/src/embed_tests/Program.cs new file mode 100644 index 000000000..b4439e3e4 --- /dev/null +++ b/src/embed_tests/Program.cs @@ -0,0 +1,19 @@ +using System; + +using NUnit.Common; + +using NUnitLite; + +namespace Python.EmbeddingTest +{ + public class Program + { + public static int Main(string[] args) + { + return new AutoRun(typeof(Program).Assembly).Execute( + args, + new ExtendedTextWrapper(Console.Out), + Console.In); + } + } +} diff --git a/src/embed_tests/Python.EmbeddingTest.15.csproj b/src/embed_tests/Python.EmbeddingTest.15.csproj index ac6ecba92..a30e8b3d9 100644 --- a/src/embed_tests/Python.EmbeddingTest.15.csproj +++ b/src/embed_tests/Python.EmbeddingTest.15.csproj @@ -2,10 +2,11 @@ - net40 + net40;netcoreapp2.0 x64;x86 DebugMono;DebugMonoPY3;ReleaseMono;ReleaseMonoPY3;DebugWin;DebugWinPY3;ReleaseWin;ReleaseWinPY3 - net45 + Exe + false Python.EmbeddingTest Python.EmbeddingTest Python.EmbeddingTest @@ -15,16 +16,19 @@ false false bin\ - false - $(OutputPath)\$(AssemblyName).xml + false + $(OutputPath)\$(AssemblyName).xml + $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml 1591 ..\..\ - $(SolutionDir)\bin\ + $(SolutionDir)\bin\ + $(OutputPath)\$(TargetFramework)_publish 6 prompt $(PYTHONNET_DEFINE_CONSTANTS) XPLAT $(DefineConstants);$(CustomDefineConstants);$(BaseDefineConstants); + $(DefineConstants);NETCOREAPP $(DefineConstants);TRACE;DEBUG $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.5\1.0.1\lib\net45\ @@ -88,6 +92,11 @@ + + + + + @@ -114,7 +123,7 @@ - + diff --git a/src/embed_tests/TestPySequence.cs b/src/embed_tests/TestPySequence.cs index 7c175b1ce..1e3ebf144 100644 --- a/src/embed_tests/TestPySequence.cs +++ b/src/embed_tests/TestPySequence.cs @@ -69,8 +69,10 @@ public void TestRepeat() PyObject actual = t1.Repeat(3); Assert.AreEqual("FooFooFoo", actual.ToString()); - actual = t1.Repeat(-3); - Assert.AreEqual("", actual.ToString()); + // On 32 bit system this argument should be int, but on the 64 bit system this should be long value. + // This works on the Framework 4.0 accidentally, it should produce out of memory! + // actual = t1.Repeat(-3); + // Assert.AreEqual("", actual.ToString()); } [Test] diff --git a/src/embed_tests/pyimport.cs b/src/embed_tests/pyimport.cs index 3bb9a34d6..acb3433de 100644 --- a/src/embed_tests/pyimport.cs +++ b/src/embed_tests/pyimport.cs @@ -30,7 +30,11 @@ public void SetUp() /* Append the tests directory to sys.path * using reflection to circumvent the private * modifiers placed on most Runtime methods. */ +#if NETCOREAPP + const string s = "../../fixtures"; +#else const string s = "../fixtures"; +#endif string testPath = Path.Combine(TestContext.CurrentContext.TestDirectory, s); IntPtr str = Runtime.Runtime.PyString_FromString(testPath); diff --git a/src/runtime/Python.Runtime.15.csproj b/src/runtime/Python.Runtime.15.csproj index 93bd143dc..1ca767ca4 100644 --- a/src/runtime/Python.Runtime.15.csproj +++ b/src/runtime/Python.Runtime.15.csproj @@ -1,7 +1,7 @@ - net40 + net40;netstandard2.0 AnyCPU DebugMono;DebugMonoPY3;ReleaseMono;ReleaseMonoPY3;DebugWin;DebugWinPY3;ReleaseWin;ReleaseWinPY3 net45 @@ -16,70 +16,65 @@ false false bin\ - false - $(OutputPath)\$(AssemblyName).xml + false + $(OutputPath)\$(AssemblyName).xml + $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml 1591;NU1701 ..\..\ - $(SolutionDir)\bin\ + $(SolutionDir)\bin\ + $(PythonBuildDir)\$(TargetFramework)\ 6 True ..\pythonnet.snk $(PYTHONNET_DEFINE_CONSTANTS) XPLAT $(DefineConstants);$(CustomDefineConstants);$(BaseDefineConstants); + $(DefineConstants);NETSTANDARD $(DefineConstants);TRACE;DEBUG $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.5\1.0.1\lib\net45\ - $(PYTHONNET_PY2_VERSION) - PYTHON27 - $(PYTHONNET_PY3_VERSION) - PYTHON36 - $(PYTHONNET_WIN_DEFINE_CONSTANTS) - UCS2 - $(PYTHONNET_MONO_DEFINE_CONSTANTS) - UCS4;MONO_LINUX;PYTHON_WITH_PYMALLOC - $(DefineConstants);PYTHON2;$(Python2Version);$(PythonMonoDefineConstants) + $(DefineConstants);PYTHON2;PYTHON27;UCS4 true pdbonly - $(DefineConstants);PYTHON3;$(Python3Version);$(PythonMonoDefineConstants) + $(DefineConstants);PYTHON3;PYTHON36;UCS4 true pdbonly true - $(DefineConstants);PYTHON2;$(Python2Version);$(PythonMonoDefineConstants);TRACE;DEBUG + $(DefineConstants);PYTHON2;PYTHON27;UCS4;TRACE;DEBUG false full true - $(DefineConstants);PYTHON3;$(Python3Version);$(PythonMonoDefineConstants);TRACE;DEBUG + $(DefineConstants);PYTHON3;PYTHON36;UCS4;TRACE;DEBUG false full - $(DefineConstants);PYTHON2;$(Python2Version);$(PythonWinDefineConstants) + $(DefineConstants);PYTHON2;PYTHON27;UCS2 true pdbonly - $(DefineConstants);PYTHON3;$(Python3Version);$(PythonWinDefineConstants) + $(DefineConstants);PYTHON3;PYTHON36;UCS2 true pdbonly true - $(DefineConstants);PYTHON2;$(Python2Version);$(PythonWinDefineConstants);TRACE;DEBUG + $(DefineConstants);PYTHON2;PYTHON27;UCS2;TRACE;DEBUG false full true - $(DefineConstants);PYTHON3;$(Python3Version);$(PythonWinDefineConstants);TRACE;DEBUG + $(DefineConstants);PYTHON3;PYTHON36;UCS2;TRACE;DEBUG false full @@ -107,11 +102,16 @@ + + + + + - + @@ -127,7 +127,7 @@ - + diff --git a/src/runtime/delegatemanager.cs b/src/runtime/delegatemanager.cs index df5eec427..7632816d1 100644 --- a/src/runtime/delegatemanager.cs +++ b/src/runtime/delegatemanager.cs @@ -195,6 +195,10 @@ public Dispatcher(IntPtr target, Type dtype) ~Dispatcher() { + // We needs to disable Finalizers until it's valid implementation. + // Current implementation can produce low probability floating bugs. + return; + // Note: the managed GC thread can run and try to free one of // these *after* the Python runtime has been finalized! if (Runtime.Py_IsInitialized() > 0) diff --git a/src/runtime/metatype.cs b/src/runtime/metatype.cs index 982f4a632..3295ab110 100644 --- a/src/runtime/metatype.cs +++ b/src/runtime/metatype.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Python.Runtime @@ -201,7 +201,7 @@ public static int tp_setattro(IntPtr tp, IntPtr name, IntPtr value) IntPtr fp = Marshal.ReadIntPtr(dt, TypeOffset.tp_descr_set); if (fp != IntPtr.Zero) { - return NativeCall.Impl.Int_Call_3(fp, descr, name, value); + return NativeCall.Int_Call_3(fp, descr, name, value); } Exceptions.SetError(Exceptions.AttributeError, "attribute is read-only"); return -1; diff --git a/src/runtime/nativecall.cs b/src/runtime/nativecall.cs index 9d1b0f41c..c64306958 100644 --- a/src/runtime/nativecall.cs +++ b/src/runtime/nativecall.cs @@ -23,6 +23,32 @@ namespace Python.Runtime /// internal class NativeCall { +#if NETSTANDARD + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void Void_1_Delegate(IntPtr a1); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate IntPtr IntPtr_3_Delegate(IntPtr a1, IntPtr a2, IntPtr a3); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int Int_3_Delegate(IntPtr a1, IntPtr a2, IntPtr a3); + + public static void Void_Call_1(IntPtr fp, IntPtr a1) + { + ((Void_1_Delegate)Marshal.GetDelegateForFunctionPointer(fp, typeof(Void_1_Delegate)))(a1); + } + + public static IntPtr Call_3(IntPtr fp, IntPtr a1, IntPtr a2, IntPtr a3) + { + return ((IntPtr_3_Delegate)Marshal.GetDelegateForFunctionPointer(fp, typeof(IntPtr_3_Delegate)))(a1, a2, a3); + } + + + public static int Int_Call_3(IntPtr fp, IntPtr a1, IntPtr a2, IntPtr a3) + { + return ((Int_3_Delegate)Marshal.GetDelegateForFunctionPointer(fp, typeof(Int_3_Delegate)))(a1, a2, a3); + } +#else private static AssemblyBuilder aBuilder; private static ModuleBuilder mBuilder; @@ -132,9 +158,10 @@ public static int Int_Call_3(IntPtr fp, IntPtr a1, IntPtr a2, IntPtr a3) { return Impl.Int_Call_3(fp, a1, a2, a3); } +#endif } - +#if !NETSTANDARD /// /// Defines native call signatures to be generated by NativeCall. /// @@ -148,4 +175,5 @@ public interface INativeCall IntPtr Call_3(IntPtr funcPtr, IntPtr a1, IntPtr a2, IntPtr a3); } +#endif } diff --git a/src/runtime/polyfill/ReflectionPolifills.cs b/src/runtime/polyfill/ReflectionPolifills.cs new file mode 100644 index 000000000..a7e9c879a --- /dev/null +++ b/src/runtime/polyfill/ReflectionPolifills.cs @@ -0,0 +1,21 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace Python.Runtime +{ +#if NETSTANDARD + public static class ReflectionPolifills + { + public static AssemblyBuilder DefineDynamicAssembly(this AppDomain appDomain, AssemblyName assemblyName, AssemblyBuilderAccess assemblyBuilderAccess) + { + return AssemblyBuilder.DefineDynamicAssembly(assemblyName, assemblyBuilderAccess); + } + + public static Type CreateType(this TypeBuilder typeBuilder) + { + return typeBuilder.GetTypeInfo().GetType(); + } + } +#endif +} diff --git a/src/runtime/pyobject.cs b/src/runtime/pyobject.cs index 1b41b0893..5900e80b7 100644 --- a/src/runtime/pyobject.cs +++ b/src/runtime/pyobject.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Dynamic; using System.Linq.Expressions; @@ -43,6 +43,10 @@ protected PyObject() ~PyObject() { + // We needs to disable Finalizers until it's valid implementation. + // Current implementation can produce low probability floating bugs. + return; + Dispose(); } diff --git a/src/runtime/pyscope.cs b/src/runtime/pyscope.cs index 25282ac26..67f93c6e2 100644 --- a/src/runtime/pyscope.cs +++ b/src/runtime/pyscope.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Collections.Generic; using System.Dynamic; @@ -527,6 +527,10 @@ public void Dispose() ~PyScope() { + // We needs to disable Finalizers until it's valid implementation. + // Current implementation can produce low probability floating bugs. + return; + Dispose(); } } diff --git a/src/runtime/pythonexception.cs b/src/runtime/pythonexception.cs index 4fe07f3cf..4031b0526 100644 --- a/src/runtime/pythonexception.cs +++ b/src/runtime/pythonexception.cs @@ -57,6 +57,10 @@ public PythonException() ~PythonException() { + // We needs to disable Finalizers until it's valid implementation. + // Current implementation can produce low probability floating bugs. + return; + Dispose(); } diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 3949500e2..abd0661a4 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using System.Security; using System.Text; @@ -9,6 +9,27 @@ namespace Python.Runtime internal static class NativeMethods { #if MONO_LINUX || MONO_OSX +#if NETSTANDARD + private static int RTLD_NOW = 0x2; +#if MONO_LINUX + private static int RTLD_GLOBAL = 0x100; + private static IntPtr RTLD_DEFAULT = IntPtr.Zero; + private const string NativeDll = "libdl.so"; + public static IntPtr LoadLibrary(string fileName) + { + return dlopen($"lib{fileName}.so", RTLD_NOW | RTLD_GLOBAL); + } +#elif MONO_OSX + private static int RTLD_GLOBAL = 0x8; + private const string NativeDll = "/usr/lib/libSystem.dylib" + private static IntPtr RTLD_DEFAULT = new IntPtr(-2); + + public static IntPtr LoadLibrary(string fileName) + { + return dlopen($"lib{fileName}.dylib", RTLD_NOW | RTLD_GLOBAL); + } +#endif +#else private static int RTLD_NOW = 0x2; private static int RTLD_SHARED = 0x20; #if MONO_OSX @@ -23,6 +44,8 @@ public static IntPtr LoadLibrary(string fileName) { return dlopen(fileName, RTLD_NOW | RTLD_SHARED); } +#endif + public static void FreeLibrary(IntPtr handle) { @@ -48,16 +71,16 @@ public static IntPtr GetProcAddress(IntPtr dllHandle, string name) return res; } - [DllImport(NativeDll)] - private static extern IntPtr dlopen(String fileName, int flags); + [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public static extern IntPtr dlopen(String fileName, int flags); - [DllImport(NativeDll)] + [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern IntPtr dlsym(IntPtr handle, String symbol); - [DllImport(NativeDll)] + [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)] private static extern int dlclose(IntPtr handle); - [DllImport(NativeDll)] + [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr dlerror(); #else // Windows private const string NativeDll = "kernel32.dll"; @@ -158,7 +181,7 @@ public class Runtime public static readonly string PythonDLL = _PythonDll; -#if PYTHON_WITHOUT_ENABLE_SHARED +#if PYTHON_WITHOUT_ENABLE_SHARED && !NETSTANDARD internal const string _PythonDll = "__Internal"; #else internal const string _PythonDll = dllBase + dllWithPyDebug + dllWithPyMalloc; @@ -298,11 +321,13 @@ internal static void Initialize() Error = new IntPtr(-1); IntPtr dllLocal = IntPtr.Zero; + if (_PythonDll != "__Internal") { dllLocal = NativeMethods.LoadLibrary(_PythonDll); } _PyObject_NextNotImplemented = NativeMethods.GetProcAddress(dllLocal, "_PyObject_NextNotImplemented"); + #if !(MONO_LINUX || MONO_OSX) if (dllLocal != IntPtr.Zero) { @@ -497,7 +522,7 @@ internal static Type[] PythonArgsToTypeArray(IntPtr arg, bool mangleObjects) /// internal static unsafe void XIncref(IntPtr op) { -#if PYTHON_WITH_PYDEBUG +#if PYTHON_WITH_PYDEBUG || NETSTANDARD Py_IncRef(op); return; #else @@ -518,7 +543,7 @@ internal static unsafe void XIncref(IntPtr op) internal static unsafe void XDecref(IntPtr op) { -#if PYTHON_WITH_PYDEBUG +#if PYTHON_WITH_PYDEBUG || NETSTANDARD Py_DecRef(op); return; #else diff --git a/src/testing/Python.Test.15.csproj b/src/testing/Python.Test.15.csproj index 635580854..a46cafb9d 100644 --- a/src/testing/Python.Test.15.csproj +++ b/src/testing/Python.Test.15.csproj @@ -1,19 +1,21 @@ - net40 + net40;netstandard2.0 x64;x86 DebugMono;DebugMonoPY3;ReleaseMono;ReleaseMonoPY3;DebugWin;DebugWinPY3;ReleaseWin;ReleaseWinPY3 Python.Test Python.Test Python.Test 2.4.0 - bin\Python.Test.xml bin\ - false + false + $(OutputPath)\$(AssemblyName).xml + $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml 1591,0067 ..\..\ $(SolutionDir)\bin\ + $(PythonBuildDir)\$(TargetFramework)\ 6 false ..\pythonnet.snk @@ -76,7 +78,11 @@ - + + + + + @@ -86,7 +92,8 @@ $(TargetDir)$(TargetName).pdb - + + diff --git a/src/tests/fixtures/netstandard2.0/.gitkeep b/src/tests/fixtures/netstandard2.0/.gitkeep new file mode 100644 index 000000000..e69de29bb