diff --git a/.travis.yml b/.travis.yml
index bf336dc9f..627fd9ebf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,18 +1,145 @@
+dist: trusty
sudo: false
-
language: python
-python:
- - 2.7
- - 3.3
- - 3.4
- - 3.5
- - 3.6
- - 3.7-dev
-
+
matrix:
- allow_failures:
- - python: 3.7-dev
+ include:
+ - python: 2.7
+ env:
+ - BUILD_OPTS=--xplat
+ - NUNIT_PATH=~/.nuget/packages/nunit.consolerunner/3.*/tools/nunit3-console.exe
+ addons:
+ apt:
+ sources:
+ - sourceline: deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main
+ key_url: https://packages.microsoft.com/keys/microsoft.asc
+ - sourceline: deb http://download.mono-project.com/repo/ubuntu trusty main
+ key_url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xA6A19B38D3D831EF
+ packages:
+ - mono-devel
+ - ca-certificates-mono
+ - dotnet-hostfxr-2.0.0
+ - dotnet-runtime-2.0.0
+ - dotnet-sdk-2.0.0
+ - python: 3.3
+ env:
+ - BUILD_OPTS=--xplat
+ - NUNIT_PATH=~/.nuget/packages/nunit.consolerunner/3.*/tools/nunit3-console.exe
+ addons:
+ apt:
+ sources:
+ - sourceline: deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main
+ key_url: https://packages.microsoft.com/keys/microsoft.asc
+ - sourceline: deb http://download.mono-project.com/repo/ubuntu trusty main
+ key_url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xA6A19B38D3D831EF
+ packages:
+ - mono-devel
+ - ca-certificates-mono
+ - dotnet-hostfxr-2.0.0
+ - dotnet-runtime-2.0.0
+ - dotnet-sdk-2.0.0
+ - python: 3.4
+ env:
+ - BUILD_OPTS=--xplat
+ - NUNIT_PATH=~/.nuget/packages/nunit.consolerunner/3.*/tools/nunit3-console.exe
+ addons:
+ apt:
+ sources:
+ - sourceline: deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main
+ key_url: https://packages.microsoft.com/keys/microsoft.asc
+ - sourceline: deb http://download.mono-project.com/repo/ubuntu trusty main
+ key_url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xA6A19B38D3D831EF
+ packages:
+ - mono-devel
+ - ca-certificates-mono
+ - dotnet-hostfxr-2.0.0
+ - dotnet-runtime-2.0.0
+ - dotnet-sdk-2.0.0
+ - python: 3.5
+ env:
+ - BUILD_OPTS=--xplat
+ - NUNIT_PATH=~/.nuget/packages/nunit.consolerunner/3.*/tools/nunit3-console.exe
+ addons:
+ apt:
+ sources:
+ - sourceline: deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main
+ key_url: https://packages.microsoft.com/keys/microsoft.asc
+ - sourceline: deb http://download.mono-project.com/repo/ubuntu trusty main
+ key_url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xA6A19B38D3D831EF
+ packages:
+ - mono-devel
+ - ca-certificates-mono
+ - dotnet-hostfxr-2.0.0
+ - dotnet-runtime-2.0.0
+ - dotnet-sdk-2.0.0
+ - python: 3.6
+ env:
+ - BUILD_OPTS=--xplat
+ - NUNIT_PATH=~/.nuget/packages/nunit.consolerunner/3.*/tools/nunit3-console.exe
+ addons:
+ apt:
+ sources:
+ - sourceline: deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main
+ key_url: https://packages.microsoft.com/keys/microsoft.asc
+ - sourceline: deb http://download.mono-project.com/repo/ubuntu trusty main
+ key_url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xA6A19B38D3D831EF
+ packages:
+ - mono-devel
+ - ca-certificates-mono
+ - dotnet-hostfxr-2.0.0
+ - dotnet-runtime-2.0.0
+ - dotnet-sdk-2.0.0
+ - python: "3.7-dev"
+ env:
+ - BUILD_OPTS=--xplat
+ - NUNIT_PATH=~/.nuget/packages/nunit.consolerunner/3.*/tools/nunit3-console.exe
+ addons:
+ apt:
+ sources:
+ - sourceline: deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main
+ key_url: https://packages.microsoft.com/keys/microsoft.asc
+ - sourceline: deb http://download.mono-project.com/repo/ubuntu trusty main
+ key_url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xA6A19B38D3D831EF
+ packages:
+ - mono-devel
+ - ca-certificates-mono
+ - dotnet-hostfxr-2.0.0
+ - dotnet-runtime-2.0.0
+ - dotnet-sdk-2.0.0
+ - python: 2.7
+ env:
+ - BUILD_OPTS=
+ - NUNIT_PATH=./packages/NUnit.*/tools/nunit3-console.exe
+ - python: 3.3
+ env:
+ - BUILD_OPTS=
+ - NUNIT_PATH=./packages/NUnit.*/tools/nunit3-console.exe
+ - python: 3.4
+ env:
+ - BUILD_OPTS=
+ - NUNIT_PATH=./packages/NUnit.*/tools/nunit3-console.exe
+ - python: 3.5
+ env:
+ - BUILD_OPTS=
+ - NUNIT_PATH=./packages/NUnit.*/tools/nunit3-console.exe
+ - python: 3.6
+ env:
+ - BUILD_OPTS=
+ - NUNIT_PATH=./packages/NUnit.*/tools/nunit3-console.exe
+ - python: "3.7-dev"
+ env:
+ - BUILD_OPTS=
+ - NUNIT_PATH=./packages/NUnit.*/tools/nunit3-console.exe
+ allow_failures:
+ - python: "3.7-dev"
+ env:
+ - BUILD_OPTS=
+ - NUNIT_PATH=./packages/NUnit.*/tools/nunit3-console.exe
+ - python: "3.7-dev"
+ env:
+ - BUILD_OPTS=--xplat
+ - NUNIT_PATH=~/.nuget/packages/nunit.consolerunner/3.*/tools/nunit3-console.exe
env:
global:
- LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so
@@ -23,8 +150,8 @@ env:
addons:
apt:
sources:
- - mono
- - mono-libtiff-compat
+ - sourceline: deb http://download.mono-project.com/repo/ubuntu trusty main
+ key_url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xA6A19B38D3D831EF
packages:
- mono-devel
- ca-certificates-mono
@@ -35,12 +162,14 @@ before_install:
- export LD_LIBRARY_PATH=$PY_LIBDIR:$LD_LIBRARY_PATH
install:
+ - pip install --upgrade setuptools # TEMP - due to setuptools 36.2.0 bug
- pip install --upgrade -r requirements.txt
- - coverage run setup.py install
+ - coverage run setup.py install $BUILD_OPTS
script:
- python -m pytest
- - mono ./packages/NUnit.*/tools/nunit3-console.exe src/embed_tests/bin/Python.EmbeddingTest.dll
+ - 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/AUTHORS.md b/AUTHORS.md
index d715eed6f..78bb25f9e 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -27,9 +27,11 @@
- Joe Frayne ([@jfrayne](https://github.com/jfrayne))
- John Burnett ([@johnburnett](https://github.com/johnburnett))
- Luke Stratman ([@lstratman](https://github.com/lstratman))
+- Konstantin Posudevskiy ([@konstantin-posudevskiy](https://github.com/konstantin-posudevskiy))
- Matthias Dittrich ([@matthid](https://github.com/matthid))
- Patrick Stewart ([@patstew](https://github.com/patstew))
- Raphael Nestler ([@rnestler](https://github.com/rnestler))
+- Rickard Holmberg ([@rickardraysearch](https://github.com/rickardraysearch))
- Sam Winstanley ([@swinstanley](https://github.com/swinstanley))
- Sean Freitag ([@cowboygneox](https://github.com/cowboygneox))
- Serge Weinstock ([@sweinst](https://github.com/sweinst))
@@ -43,3 +45,5 @@
- ([@rico-chet](https://github.com/rico-chet))
- ([@rmadsen-ks](https://github.com/rmadsen-ks))
- ([@stonebig](https://github.com/stonebig))
+- ([@testrunner123](https://github.com/testrunner123))
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6c245b17b..7d408a8d1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,18 +8,27 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
## [unreleased][]
### Added
-- Added clr.GetClrType (#432)(#433)
-- Added `Foo` feature
-- Allowed passing None for nullable args (#460)
+- 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.
+- NUnit upgraded to 3.7 (eliminates travis-ci random bug)
+- Added `clr.GetClrType` (#432, #433)
+- Allowed passing `None` for nullable args (#460)
+- Added keyword arguments based on C# syntax for calling CPython methods (#461)
### Changed
-- Changed `Bar` feature
-
### Fixed
- Fixed Visual Studio 2017 compat (#434) for setup.py
-- Fixed `FooBar` bug
+- Fixed crash on exit of the Python interpreter if a python class
+ derived from a .NET class has a `__namespace__` or `__assembly__`
+ attribute (#481)
+- Fixed conversion of 'float' and 'double' values (#486)
+- Fixed 'clrmethod' for python 2 (#492)
+- Fixed double calling of constructor when deriving from .NET class (#495)
+
## [2.3.0][] - 2017-03-11
diff --git a/NuGet.config b/NuGet.config
new file mode 100644
index 000000000..719fbc83c
--- /dev/null
+++ b/NuGet.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index da43abacd..89dcf2206 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# pythonnet - Python for .NET
+[](https://gitter.im/pythonnet/pythonnet?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
[![appveyor shield][]](https://ci.appveyor.com/project/pythonnet/pythonnet/branch/master)
[![travis shield][]](https://travis-ci.org/pythonnet/pythonnet)
[![codecov shield][]](https://codecov.io/github/pythonnet/pythonnet)
@@ -42,7 +44,7 @@ from System.Windows.Forms import Form
a `using (Py.GIL()) {/* Your code here */}` block.
- Import python modules using `dynamic mod = Py.Import("mod")`,
then you can call functions as normal, eg `mod.func(args)`.
-- Use `mod.func(args, Py.kw("keywordargname", keywordargvalue))`
+- Use `mod.func(args, Py.kw("keywordargname", keywordargvalue))` or `mod.func(args, keywordargname=keywordargvalue)`
to apply keyword arguments.
- All python objects should be declared as `dynamic` type.
- Mathematical operations involving python and literal/managed types must
@@ -67,7 +69,7 @@ static void Main(string[] args)
dynamic a = np.array(new List { 1, 2, 3 });
Console.WriteLine(a.dtype);
- dynamic b = np.array(new List { 6, 5, 4 }, Py.kw("dtype", np.int32));
+ dynamic b = np.array(new List { 6, 5, 4 }, dtype: np.int32);
Console.WriteLine(b.dtype);
Console.WriteLine(a * b);
@@ -87,6 +89,10 @@ int32
[ 6. 10. 12.]
```
+Information on installation, FAQ, troubleshooting, debugging, and projects using pythonnet can be found in the Wiki:
+
+https://github.com/pythonnet/pythonnet/wiki
+
[appveyor shield]: https://img.shields.io/appveyor/ci/pythonnet/pythonnet/master.svg?label=AppVeyor
[codecov shield]: https://img.shields.io/codecov/c/github/pythonnet/pythonnet/master.svg?label=Codecov
diff --git a/appveyor.yml b/appveyor.yml
index c108801e7..1953d85d5 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,6 +1,9 @@
version: '{branch}-{build}'
build: off
+image:
+ - Visual Studio 2017
+
platform:
- x86
- x64
@@ -12,6 +15,16 @@ environment:
CODECOV_ENV: PYTHON_VERSION, PLATFORM
matrix:
+ - PYTHON_VERSION: 2.7
+ BUILD_OPTS: --xplat
+ - PYTHON_VERSION: 3.3
+ BUILD_OPTS: --xplat
+ - PYTHON_VERSION: 3.4
+ BUILD_OPTS: --xplat
+ - PYTHON_VERSION: 3.5
+ BUILD_OPTS: --xplat
+ - PYTHON_VERSION: 3.6
+ BUILD_OPTS: --xplat
- PYTHON_VERSION: 2.7
- PYTHON_VERSION: 3.3
- PYTHON_VERSION: 3.4
@@ -29,6 +42,9 @@ 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
@@ -37,7 +53,7 @@ build_script:
# Create clean `sdist`. Only used for releases
- python setup.py --quiet sdist
# Build `wheel` with coverage of `setup.py`
- - coverage run setup.py bdist_wheel
+ - coverage run setup.py bdist_wheel %BUILD_OPTS%
test_script:
- pip install --no-index --find-links=.\dist\ pythonnet
@@ -47,11 +63,11 @@ test_script:
on_finish:
# Temporary disable multiple upload due to codecov limit of 20 per commit.
# https://docs.codecov.io/blog/week-8-2017
- # - coverage xml -i
+ - coverage xml -i
# - codecov --file coverage.xml --flags setup_windows
# - codecov --file py.coverage --flags python_tests
# - codecov --file cs.coverage --flags embedded_tests
- - codecov --flags setup_windows
+ - codecov --file py.coverage cs.coverage coverage.xml --flags setup_windows
artifacts:
- path: dist\*
diff --git a/ci/appveyor_run_tests.ps1 b/ci/appveyor_run_tests.ps1
index 4245d1577..b45440fbe 100644
--- a/ci/appveyor_run_tests.ps1
+++ b/ci/appveyor_run_tests.ps1
@@ -11,7 +11,12 @@ if ($FALSE -and $env:PLATFORM -eq "x86"){
# Executable paths for OpenCover
# Note if OpenCover fails, it won't affect the exit codes.
$OPENCOVER = Resolve-Path .\packages\OpenCover.*\tools\OpenCover.Console.exe
-$CS_RUNNER = Resolve-Path .\packages\NUnit.*\tools\"$CS_RUNNER".exe
+if ($env:BUILD_OPTS -eq "--xplat"){
+ $CS_RUNNER = Resolve-Path $env:USERPROFILE\.nuget\packages\nunit.consolerunner\*\tools\"$CS_RUNNER".exe
+}
+else{
+ $CS_RUNNER = Resolve-Path .\packages\NUnit.*\tools\"$CS_RUNNER".exe
+}
$PY = Get-Command python
# Can't use ".\build\*\Python.EmbeddingTest.dll". Missing framework files.
@@ -39,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
new file mode 100644
index 000000000..f2015e480
--- /dev/null
+++ b/pythonnet.15.sln
@@ -0,0 +1,194 @@
+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}"
+EndProject
+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}"
+EndProject
+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}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ DebugMono|x64 = DebugMono|x64
+ DebugMono|x86 = DebugMono|x86
+ DebugMonoPY3|x64 = DebugMonoPY3|x64
+ DebugMonoPY3|x86 = DebugMonoPY3|x86
+ DebugWin|x64 = DebugWin|x64
+ DebugWin|x86 = DebugWin|x86
+ DebugWinPY3|x64 = DebugWinPY3|x64
+ DebugWinPY3|x86 = DebugWinPY3|x86
+ ReleaseMono|x64 = ReleaseMono|x64
+ ReleaseMono|x86 = ReleaseMono|x86
+ ReleaseMonoPY3|x64 = ReleaseMonoPY3|x64
+ ReleaseMonoPY3|x86 = ReleaseMonoPY3|x86
+ ReleaseWin|x64 = ReleaseWin|x64
+ ReleaseWin|x86 = ReleaseWin|x86
+ ReleaseWinPY3|x64 = ReleaseWinPY3|x64
+ ReleaseWinPY3|x86 = ReleaseWinPY3|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugMono|x64.Build.0 = DebugMono|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugMono|x86.Build.0 = DebugMono|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugMonoPY3|x64.ActiveCfg = DebugMonoPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugMonoPY3|x64.Build.0 = DebugMonoPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugMonoPY3|x86.ActiveCfg = DebugMonoPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugMonoPY3|x86.Build.0 = DebugMonoPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugWin|x64.ActiveCfg = DebugWin|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugWin|x64.Build.0 = DebugWin|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugWin|x86.ActiveCfg = DebugWin|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugWin|x86.Build.0 = DebugWin|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugWinPY3|x64.ActiveCfg = DebugWinPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugWinPY3|x64.Build.0 = DebugWinPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugWinPY3|x86.ActiveCfg = DebugWinPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.DebugWinPY3|x86.Build.0 = DebugWinPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseMono|x64.Build.0 = ReleaseMono|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseMono|x86.Build.0 = ReleaseMono|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseMonoPY3|x64.ActiveCfg = ReleaseMonoPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseMonoPY3|x64.Build.0 = ReleaseMonoPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseMonoPY3|x86.ActiveCfg = ReleaseMonoPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseMonoPY3|x86.Build.0 = ReleaseMonoPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseWin|x64.ActiveCfg = ReleaseWin|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseWinPY3|x64.ActiveCfg = ReleaseWinPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseWinPY3|x64.Build.0 = ReleaseWinPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseWinPY3|x86.ActiveCfg = ReleaseWinPY3|Any CPU
+ {2759F4FF-716B-4828-916F-50FA86613DFC}.ReleaseWinPY3|x86.Build.0 = ReleaseWinPY3|Any CPU
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugMono|x64.ActiveCfg = DebugMono|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugMono|x64.Build.0 = DebugMono|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugMono|x86.ActiveCfg = DebugMono|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugMono|x86.Build.0 = DebugMono|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugMonoPY3|x64.ActiveCfg = DebugMonoPY3|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugMonoPY3|x64.Build.0 = DebugMonoPY3|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugMonoPY3|x86.ActiveCfg = DebugMonoPY3|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugMonoPY3|x86.Build.0 = DebugMonoPY3|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugWin|x64.ActiveCfg = DebugWin|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugWin|x64.Build.0 = DebugWin|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugWin|x86.ActiveCfg = DebugWin|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugWin|x86.Build.0 = DebugWin|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugWinPY3|x64.ActiveCfg = DebugWinPY3|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugWinPY3|x64.Build.0 = DebugWinPY3|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugWinPY3|x86.ActiveCfg = DebugWinPY3|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.DebugWinPY3|x86.Build.0 = DebugWinPY3|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseMono|x64.ActiveCfg = ReleaseMono|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseMono|x64.Build.0 = ReleaseMono|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseMono|x86.ActiveCfg = ReleaseMono|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseMono|x86.Build.0 = ReleaseMono|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseMonoPY3|x64.ActiveCfg = ReleaseMonoPY3|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseMonoPY3|x64.Build.0 = ReleaseMonoPY3|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseMonoPY3|x86.ActiveCfg = ReleaseMonoPY3|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseMonoPY3|x86.Build.0 = ReleaseMonoPY3|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseWin|x64.Build.0 = ReleaseWin|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseWin|x86.ActiveCfg = ReleaseWin|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseWin|x86.Build.0 = ReleaseWin|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseWinPY3|x64.ActiveCfg = ReleaseWinPY3|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseWinPY3|x64.Build.0 = ReleaseWinPY3|x64
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseWinPY3|x86.ActiveCfg = ReleaseWinPY3|x86
+ {66B8D01A-9906-452A-B09E-BF75EA76468F}.ReleaseWinPY3|x86.Build.0 = ReleaseWinPY3|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugMono|x64.ActiveCfg = DebugMono|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugMono|x86.ActiveCfg = DebugMono|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugMonoPY3|x64.ActiveCfg = DebugMonoPY3|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugMonoPY3|x86.ActiveCfg = DebugMonoPY3|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugWin|x64.ActiveCfg = DebugWin|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugWin|x64.Build.0 = DebugWin|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugWin|x86.ActiveCfg = DebugWin|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugWin|x86.Build.0 = DebugWin|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugWinPY3|x64.ActiveCfg = DebugWinPY3|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugWinPY3|x64.Build.0 = DebugWinPY3|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugWinPY3|x86.ActiveCfg = DebugWinPY3|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.DebugWinPY3|x86.Build.0 = DebugWinPY3|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseMono|x64.ActiveCfg = ReleaseMono|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseMono|x86.ActiveCfg = ReleaseMono|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseMonoPY3|x64.ActiveCfg = ReleaseMonoPY3|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseMonoPY3|x86.ActiveCfg = ReleaseMonoPY3|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseWin|x64.Build.0 = ReleaseWin|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseWin|x86.ActiveCfg = ReleaseWin|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseWin|x86.Build.0 = ReleaseWin|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseWinPY3|x64.ActiveCfg = ReleaseWinPY3|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseWinPY3|x64.Build.0 = ReleaseWinPY3|x64
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseWinPY3|x86.ActiveCfg = ReleaseWinPY3|x86
+ {E08678D4-9A52-4AD5-B63D-8EBC7399981B}.ReleaseWinPY3|x86.Build.0 = ReleaseWinPY3|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugMono|x64.ActiveCfg = DebugMono|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugMono|x64.Build.0 = DebugMono|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugMono|x86.ActiveCfg = DebugMono|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugMono|x86.Build.0 = DebugMono|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugMonoPY3|x64.ActiveCfg = DebugMonoPY3|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugMonoPY3|x64.Build.0 = DebugMonoPY3|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugMonoPY3|x86.ActiveCfg = DebugMonoPY3|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugMonoPY3|x86.Build.0 = DebugMonoPY3|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugWin|x64.ActiveCfg = DebugWin|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugWin|x64.Build.0 = DebugWin|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugWin|x86.ActiveCfg = DebugWin|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugWin|x86.Build.0 = DebugWin|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugWinPY3|x64.ActiveCfg = DebugWinPY3|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugWinPY3|x64.Build.0 = DebugWinPY3|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugWinPY3|x86.ActiveCfg = DebugWinPY3|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.DebugWinPY3|x86.Build.0 = DebugWinPY3|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseMono|x64.ActiveCfg = ReleaseMono|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseMono|x64.Build.0 = ReleaseMono|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseMono|x86.ActiveCfg = ReleaseMono|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseMono|x86.Build.0 = ReleaseMono|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseMonoPY3|x64.ActiveCfg = ReleaseMonoPY3|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseMonoPY3|x64.Build.0 = ReleaseMonoPY3|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseMonoPY3|x86.ActiveCfg = ReleaseMonoPY3|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseMonoPY3|x86.Build.0 = ReleaseMonoPY3|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseWin|x64.Build.0 = ReleaseWin|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseWin|x86.ActiveCfg = ReleaseWin|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseWin|x86.Build.0 = ReleaseWin|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseWinPY3|x64.ActiveCfg = ReleaseWinPY3|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseWinPY3|x64.Build.0 = ReleaseWinPY3|x64
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseWinPY3|x86.ActiveCfg = ReleaseWinPY3|x86
+ {CDAD305F-8E72-492C-A314-64CF58D472A0}.ReleaseWinPY3|x86.Build.0 = ReleaseWinPY3|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugMono|x64.ActiveCfg = DebugMono|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugMono|x64.Build.0 = DebugMono|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugMono|x86.ActiveCfg = DebugMono|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugMono|x86.Build.0 = DebugMono|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugMonoPY3|x64.ActiveCfg = DebugMonoPY3|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugMonoPY3|x64.Build.0 = DebugMonoPY3|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugMonoPY3|x86.ActiveCfg = DebugMonoPY3|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugMonoPY3|x86.Build.0 = DebugMonoPY3|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugWin|x64.ActiveCfg = DebugWin|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugWin|x64.Build.0 = DebugWin|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugWin|x86.ActiveCfg = DebugWin|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugWin|x86.Build.0 = DebugWin|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugWinPY3|x64.ActiveCfg = DebugWinPY3|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugWinPY3|x64.Build.0 = DebugWinPY3|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugWinPY3|x86.ActiveCfg = DebugWinPY3|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.DebugWinPY3|x86.Build.0 = DebugWinPY3|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseMono|x64.ActiveCfg = ReleaseMono|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseMono|x64.Build.0 = ReleaseMono|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseMono|x86.ActiveCfg = ReleaseMono|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseMono|x86.Build.0 = ReleaseMono|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseMonoPY3|x64.ActiveCfg = ReleaseMonoPY3|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseMonoPY3|x64.Build.0 = ReleaseMonoPY3|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseMonoPY3|x86.ActiveCfg = ReleaseMonoPY3|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseMonoPY3|x86.Build.0 = ReleaseMonoPY3|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseWin|x64.Build.0 = ReleaseWin|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseWin|x86.ActiveCfg = ReleaseWin|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseWin|x86.Build.0 = ReleaseWin|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseWinPY3|x64.ActiveCfg = ReleaseWinPY3|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseWinPY3|x64.Build.0 = ReleaseWinPY3|x64
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseWinPY3|x86.ActiveCfg = ReleaseWinPY3|x86
+ {F94B547A-E97E-4500-8D53-B4D64D076E5F}.ReleaseWinPY3|x86.Build.0 = ReleaseWinPY3|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A6347B90-BBE6-4E45-90BF-1BD8B76069E3}
+ EndGlobalSection
+EndGlobal
diff --git a/requirements.txt b/requirements.txt
index bcceedf25..18f9bf902 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,11 +2,10 @@
pytest
coverage
+# Coverage upload
+codecov
+
# Platform specific requirements
pip; sys_platform == 'win32'
wheel; sys_platform == 'win32'
pycparser; sys_platform != 'win32'
-
-# Coverage upload
-# codecov v2.0.6 isn't on PyPi
-https://github.com/codecov/codecov-python/tarball/v2.0.6
diff --git a/setup.py b/setup.py
index c23f6b5bd..24557c137 100644
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,8 @@
import sys
import sysconfig
from distutils import spawn
-from distutils.command import build_ext, install_data, install_lib
+from distutils.command import install, build, build_ext, install_data, install_lib
+from wheel import bdist_wheel
from setuptools import Extension, setup
@@ -131,9 +132,28 @@ def _get_long_description():
except ImportError:
return '.Net and Mono integration for Python'
+def _update_xlat_devtools():
+ global DEVTOOLS
+ if DEVTOOLS == "MsDev":
+ DEVTOOLS = "MsDev15"
+ elif DEVTOOLS == "Mono":
+ DEVTOOLS = "dotnet"
class BuildExtPythonnet(build_ext.build_ext):
+ user_options = build_ext.build_ext.user_options + [
+ ('xplat', None, None)
+ ]
+ def initialize_options(self):
+ build_ext.build_ext.initialize_options(self)
+ self.xplat = None
+
+ def finalize_options(self):
+ build_ext.build_ext.finalize_options(self)
+
def build_extension(self, ext):
+ if self.xplat:
+ _update_xlat_devtools()
+
"""Builds the .pyd file using msbuild or xbuild"""
if ext.name != "clr":
return build_ext.build_ext.build_extension(self, ext)
@@ -164,7 +184,7 @@ def build_extension(self, ext):
if CONFIG == "Debug":
defines.extend(["DEBUG", "TRACE"])
- if sys.platform != "win32" and DEVTOOLS == "Mono":
+ if sys.platform != "win32" and (DEVTOOLS == "Mono" or DEVTOOLS == "dotnet"):
on_darwin = sys.platform == "darwin"
defines.append("MONO_OSX" if on_darwin else "MONO_LINUX")
@@ -196,20 +216,33 @@ def build_extension(self, ext):
if DEVTOOLS == "MsDev":
_xbuild = '"{0}"'.format(self._find_msbuild_tool("msbuild.exe"))
_config = "{0}Win".format(CONFIG)
-
+ _solution_file = 'pythonnet.sln'
+ _custom_define_constants = False
+ elif DEVTOOLS == "MsDev15":
+ _xbuild = '"{0}"'.format(self._find_msbuild_tool_15())
+ _config = "{0}Win".format(CONFIG)
+ _solution_file = 'pythonnet.15.sln'
+ _custom_define_constants = True
elif DEVTOOLS == "Mono":
- _xbuild = "xbuild"
+ _xbuild = 'xbuild'
_config = "{0}Mono".format(CONFIG)
+ _solution_file = 'pythonnet.sln'
+ _custom_define_constants = False
+ elif DEVTOOLS == "dotnet":
+ _xbuild = 'dotnet msbuild'
+ _config = "{0}Mono".format(CONFIG)
+ _solution_file = 'pythonnet.15.sln'
+ _custom_define_constants = True
else:
raise NotImplementedError(
- "DevTool {0} not supported (use MsDev/Mono)".format(DEVTOOLS))
+ "DevTool {0} not supported (use MsDev/MsDev15/Mono/dotnet)".format(DEVTOOLS))
cmd = [
_xbuild,
- 'pythonnet.sln',
+ _solution_file,
'/p:Configuration={}'.format(_config),
'/p:Platform={}'.format(ARCH),
- '/p:DefineConstants="{}"'.format('%3B'.join(defines)),
+ '/p:{}DefineConstants="{}"'.format('Custom' if _custom_define_constants else '','%3B'.join(defines)),
'/p:PythonBuildDir="{}"'.format(os.path.abspath(dest_dir)),
'/p:PythonInteropFile="{}"'.format(os.path.basename(interop_file)),
'/verbosity:{}'.format(VERBOSITY),
@@ -220,15 +253,18 @@ def build_extension(self, ext):
cmd.append('/p:PythonManifest="{0}"'.format(manifest))
self.debug_print("Building: {0}".format(" ".join(cmd)))
- use_shell = True if DEVTOOLS == "Mono" else False
+ use_shell = True if DEVTOOLS == "Mono" or DEVTOOLS == "dotnet" else False
+
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":
+ if DEVTOOLS == "Mono" or DEVTOOLS == "dotnet":
self._build_monoclr()
def _get_manifest(self, build_dir):
- if DEVTOOLS != "MsDev":
+ if DEVTOOLS != "MsDev" and DEVTOOLS != "MsDev15":
return
mt = self._find_msbuild_tool("mt.exe", use_windows_sdk=True)
manifest = os.path.abspath(os.path.join(build_dir, "app.manifest"))
@@ -261,19 +297,30 @@ def _build_monoclr(self):
def _install_packages(self):
"""install packages using nuget"""
- nuget = os.path.join("tools", "nuget", "nuget.exe")
- use_shell = False
- if DEVTOOLS == "Mono":
- nuget = "mono {0}".format(nuget)
- use_shell = True
+ use_shell = DEVTOOLS == "Mono" or DEVTOOLS == "dotnet"
+
+ if DEVTOOLS == "MsDev15" or DEVTOOLS == "dotnet":
+ if DEVTOOLS == "MsDev15":
+ _config = "{0}Win".format(CONFIG)
+ elif DEVTOOLS == "dotnet":
+ _config = "{0}Mono".format(CONFIG)
+
+ cmd = "dotnet msbuild /t:Restore pythonnet.15.sln /p:Configuration={0} /p:Platform={1}".format(_config, ARCH)
+ self.debug_print("Updating packages with xplat: {0}".format(cmd))
+ subprocess.check_call(cmd, shell=use_shell)
+ else:
+ nuget = os.path.join("tools", "nuget", "nuget.exe")
+
+ if DEVTOOLS == "Mono":
+ nuget = "mono {0}".format(nuget)
- cmd = "{0} update -self".format(nuget)
- self.debug_print("Updating NuGet: {0}".format(cmd))
- subprocess.check_call(cmd, shell=use_shell)
+ cmd = "{0} update -self".format(nuget)
+ self.debug_print("Updating NuGet: {0}".format(cmd))
+ subprocess.check_call(cmd, shell=use_shell)
- cmd = "{0} restore pythonnet.sln -o packages".format(nuget)
- self.debug_print("Installing packages: {0}".format(cmd))
- subprocess.check_call(cmd, shell=use_shell)
+ cmd = "{0} restore pythonnet.sln -o packages".format(nuget)
+ self.debug_print("Installing packages: {0}".format(cmd))
+ subprocess.check_call(cmd, shell=use_shell)
def _find_msbuild_tool(self, tool="msbuild.exe", use_windows_sdk=False):
"""Return full path to one of the Microsoft build tools"""
@@ -319,6 +366,20 @@ def _find_msbuild_tool(self, tool="msbuild.exe", use_windows_sdk=False):
raise RuntimeError("{0} could not be found".format(tool))
+ def _find_msbuild_tool_15(self):
+ """Return full path to one of the Microsoft build tools"""
+ try:
+ basePathes = subprocess.check_output(
+ ["vswhere", "-latest",
+ "-version", "[15.0, 16.0)",
+ "-requires", "Microsoft.Component.MSBuild",
+ "-property", "InstallationPath"]).splitlines()
+ if len(basePathes):
+ return os.path.join(basePathes[0].decode(sys.stdout.encoding or "utf-8"), "MSBuild", "15.0", "Bin", "MSBuild.exe")
+ else:
+ raise RuntimeError("MSBuild >=15.0 could not be found.")
+ except subprocess.CalledProcessError as e:
+ raise RuntimeError("MSBuild >=15.0 could not be found. {0}".format(e.output))
class InstallLibPythonnet(install_lib.install_lib):
def install(self):
@@ -356,8 +417,39 @@ def run(self):
return install_data.install_data.run(self)
+class InstallPythonnet(install.install):
+ user_options = install.install.user_options + [
+ ('xplat', None, None)
+ ]
+ def initialize_options(self):
+ install.install.initialize_options(self)
+ self.xplat = None
+
+ def finalize_options(self):
+ install.install.finalize_options(self)
-###############################################################################
+ def run(self):
+ if self.xplat:
+ _update_xlat_devtools()
+ return install.install.run(self)
+
+class BDistWheelPythonnet(bdist_wheel.bdist_wheel):
+ user_options = bdist_wheel.bdist_wheel.user_options + [
+ ('xplat', None, None)
+ ]
+ def initialize_options(self):
+ bdist_wheel.bdist_wheel.initialize_options(self)
+ self.xplat = None
+
+ def finalize_options(self):
+ bdist_wheel.bdist_wheel.finalize_options(self)
+
+ def run(self):
+ if self.xplat:
+ _update_xlat_devtools()
+ return bdist_wheel.bdist_wheel.run(self)
+
+ ###############################################################################
setupdir = os.path.dirname(__file__)
if setupdir:
os.chdir(setupdir)
@@ -385,9 +477,11 @@ def run(self):
]),
],
cmdclass={
+ "install": InstallPythonnet,
"build_ext": BuildExtPythonnet,
"install_lib": InstallLibPythonnet,
"install_data": InstallDataPythonnet,
+ "bdist_wheel": BDistWheelPythonnet
},
classifiers=[
'Development Status :: 5 - Production/Stable',
diff --git a/src/clrmodule/clrmodule.15.csproj b/src/clrmodule/clrmodule.15.csproj
new file mode 100644
index 000000000..e97c6fe1b
--- /dev/null
+++ b/src/clrmodule/clrmodule.15.csproj
@@ -0,0 +1,102 @@
+
+
+
+
+
+ net40
+ x64;x86
+ DebugMono;DebugMonoPY3;ReleaseMono;ReleaseMonoPY3;DebugWin;DebugWinPY3;ReleaseWin;ReleaseWinPY3
+ clrmodule
+ clrmodule
+ clrmodule
+ 2.4.0
+ false
+ false
+ false
+ false
+ false
+ false
+ bin\clrmodule.xml
+ bin\
+ false
+ 1591
+ ..\..\
+ $(SolutionDir)\bin\
+ $(PythonBuildDir)\$(TargetFramework)\
+ 6
+ prompt
+ $(PYTHONNET_DEFINE_CONSTANTS)
+ XPLAT
+ $(DefineConstants);$(CustomDefineConstants);$(BaseDefineConstants);
+ $(DefineConstants);TRACE;DEBUG
+
+
+
+ x86
+
+
+ x64
+
+
+
+ true
+ $(DefineConstants);PYTHON2;TRACE;DEBUG
+ full
+
+
+ $(DefineConstants);PYTHON2
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);PYTHON2;TRACE;DEBUG
+ full
+
+
+ $(DefineConstants);PYTHON2
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);PYTHON3;TRACE;DEBUG
+ full
+
+
+ $(DefineConstants);PYTHON3
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);PYTHON3;TRACE;DEBUG
+ full
+
+
+ $(DefineConstants);PYTHON3
+ true
+ pdbonly
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(TargetPath)
+ $(TargetDir)$(TargetName).pdb
+
+
+
+
+
+
+
+
diff --git a/src/console/Console.15.csproj b/src/console/Console.15.csproj
new file mode 100644
index 000000000..ed9d3d8f9
--- /dev/null
+++ b/src/console/Console.15.csproj
@@ -0,0 +1,107 @@
+
+
+
+ net40;netcoreapp2.0
+ x64;x86
+ DebugMono;DebugMonoPY3;ReleaseMono;ReleaseMonoPY3;DebugWin;DebugWinPY3;ReleaseWin;ReleaseWinPY3
+ Exe
+ nPython
+ Python.Runtime
+ nPython
+ 2.4.0
+ false
+ false
+ false
+ false
+ false
+ false
+ bin\
+ false
+ $(OutputPath)\$(AssemblyName).xml
+ $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml
+ 1591
+ ..\..\
+ $(SolutionDir)\bin\
+ $(PythonBuildDir)\$(TargetFramework)\
+ 6
+ python-clear.ico
+ prompt
+ $(PYTHONNET_DEFINE_CONSTANTS)
+ XPLAT
+ $(DefineConstants);$(CustomDefineConstants);$(BaseDefineConstants);
+ $(DefineConstants);TRACE;DEBUG
+ $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.5\1.0.1\lib\net45\
+
+
+ x86
+
+
+ x64
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants)
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants)
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants)
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants)
+ true
+ pdbonly
+
+
+ $(PythonManifest)
+
+
+
+
+
+
+ Properties\SharedAssemblyInfo.cs
+
+
+
+
+
+ Python.Runtime.dll
+
+
+
+
+
+
+
+
+
+
+
+
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
new file mode 100644
index 000000000..a30e8b3d9
--- /dev/null
+++ b/src/embed_tests/Python.EmbeddingTest.15.csproj
@@ -0,0 +1,130 @@
+
+
+
+
+ net40;netcoreapp2.0
+ x64;x86
+ DebugMono;DebugMonoPY3;ReleaseMono;ReleaseMonoPY3;DebugWin;DebugWinPY3;ReleaseWin;ReleaseWinPY3
+ Exe
+ false
+ Python.EmbeddingTest
+ Python.EmbeddingTest
+ Python.EmbeddingTest
+ 2.4.0
+ false
+ false
+ false
+ false
+ bin\
+ false
+ $(OutputPath)\$(AssemblyName).xml
+ $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml
+ 1591
+ ..\..\
+ $(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\
+
+
+ x86
+
+
+ x64
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants);
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants);
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants);
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants);
+ true
+ pdbonly
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(TargetPath)
+ $(TargetDir)$(TargetName).pdb
+
+
+
+
+
+
+
+
diff --git a/src/embed_tests/Python.EmbeddingTest.csproj b/src/embed_tests/Python.EmbeddingTest.csproj
index 2edf4f515..fe02b0526 100644
--- a/src/embed_tests/Python.EmbeddingTest.csproj
+++ b/src/embed_tests/Python.EmbeddingTest.csproj
@@ -70,8 +70,8 @@
-
- ..\..\packages\NUnit.3.6.0\lib\net40\nunit.framework.dll
+
+ ..\..\packages\NUnit.3.7.1\lib\net40\nunit.framework.dll
@@ -84,6 +84,7 @@
+
@@ -100,6 +101,7 @@
+
diff --git a/src/embed_tests/TestConverter.cs b/src/embed_tests/TestConverter.cs
new file mode 100644
index 000000000..346c8afdc
--- /dev/null
+++ b/src/embed_tests/TestConverter.cs
@@ -0,0 +1,48 @@
+using NUnit.Framework;
+using Python.Runtime;
+
+namespace Python.EmbeddingTest
+{
+ public class TestConverter
+ {
+ [OneTimeSetUp]
+ public void SetUp()
+ {
+ PythonEngine.Initialize();
+ }
+
+ [OneTimeTearDown]
+ public void Dispose()
+ {
+ PythonEngine.Shutdown();
+ }
+
+ [Test]
+ public void TestConvertSingleToManaged(
+ [Values(float.PositiveInfinity, float.NegativeInfinity, float.MinValue, float.MaxValue, float.NaN,
+ float.Epsilon)] float testValue)
+ {
+ var pyFloat = new PyFloat(testValue);
+
+ object convertedValue;
+ var converted = Converter.ToManaged(pyFloat.Handle, typeof(float), out convertedValue, false);
+
+ Assert.IsTrue(converted);
+ Assert.IsTrue(((float) convertedValue).Equals(testValue));
+ }
+
+ [Test]
+ public void TestConvertDoubleToManaged(
+ [Values(double.PositiveInfinity, double.NegativeInfinity, double.MinValue, double.MaxValue, double.NaN,
+ double.Epsilon)] double testValue)
+ {
+ var pyFloat = new PyFloat(testValue);
+
+ object convertedValue;
+ var converted = Converter.ToManaged(pyFloat.Handle, typeof(double), out convertedValue, false);
+
+ Assert.IsTrue(converted);
+ Assert.IsTrue(((double) convertedValue).Equals(testValue));
+ }
+ }
+}
diff --git a/src/embed_tests/TestPyScope.cs b/src/embed_tests/TestPyScope.cs
new file mode 100644
index 000000000..49c15a3a1
--- /dev/null
+++ b/src/embed_tests/TestPyScope.cs
@@ -0,0 +1,372 @@
+using System;
+using NUnit.Framework;
+using Python.Runtime;
+
+namespace Python.EmbeddingTest
+{
+ public class PyScopeTest
+ {
+ private PyScope ps;
+
+ [SetUp]
+ public void SetUp()
+ {
+ using (Py.GIL())
+ {
+ ps = Py.CreateScope("test");
+ }
+ }
+
+ [TearDown]
+ public void Dispose()
+ {
+ using (Py.GIL())
+ {
+ ps.Dispose();
+ ps = null;
+ }
+ }
+
+ ///
+ /// Eval a Python expression and obtain its return value.
+ ///
+ [Test]
+ public void TestEval()
+ {
+ using (Py.GIL())
+ {
+ ps.Set("a", 1);
+ var result = ps.Eval("a + 2");
+ Assert.AreEqual(3, result);
+ }
+ }
+
+ ///
+ /// Exec Python statements and obtain the variables created.
+ ///
+ [Test]
+ public void TestExec()
+ {
+ using (Py.GIL())
+ {
+ ps.Set("bb", 100); //declare a global variable
+ ps.Set("cc", 10); //declare a local variable
+ ps.Exec("aa = bb + cc + 3");
+ var result = ps.Get("aa");
+ Assert.AreEqual(113, result);
+ }
+ }
+
+ ///
+ /// Compile an expression into an ast object;
+ /// Execute the ast and obtain its return value.
+ ///
+ [Test]
+ public void TestCompileExpression()
+ {
+ using (Py.GIL())
+ {
+ ps.Set("bb", 100); //declare a global variable
+ ps.Set("cc", 10); //declare a local variable
+ PyObject script = PythonEngine.Compile("bb + cc + 3", "", RunFlagType.Eval);
+ var result = ps.Execute(script);
+ Assert.AreEqual(113, result);
+ }
+ }
+
+ ///
+ /// Compile Python statements into an ast object;
+ /// Execute the ast;
+ /// Obtain the local variables created.
+ ///
+ [Test]
+ public void TestCompileStatements()
+ {
+ using (Py.GIL())
+ {
+ ps.Set("bb", 100); //declare a global variable
+ ps.Set("cc", 10); //declare a local variable
+ PyObject script = PythonEngine.Compile("aa = bb + cc + 3", "", RunFlagType.File);
+ ps.Execute(script);
+ var result = ps.Get("aa");
+ Assert.AreEqual(113, result);
+ }
+ }
+
+ ///
+ /// Create a function in the scope, then the function can read variables in the scope.
+ /// It cannot write the variables unless it uses the 'global' keyword.
+ ///
+ [Test]
+ public void TestScopeFunction()
+ {
+ using (Py.GIL())
+ {
+ ps.Set("bb", 100);
+ ps.Set("cc", 10);
+ ps.Exec(
+ "def func1():\n" +
+ " bb = cc + 10\n");
+ dynamic func1 = ps.Get("func1");
+ func1(); //call the function, it can be called any times
+ var result = ps.Get("bb");
+ Assert.AreEqual(100, result);
+
+ ps.Set("bb", 100);
+ ps.Set("cc", 10);
+ ps.Exec(
+ "def func2():\n" +
+ " global bb\n" +
+ " bb = cc + 10\n");
+ dynamic func2 = ps.Get("func2");
+ func2();
+ result = ps.Get("bb");
+ Assert.AreEqual(20, result);
+ }
+ }
+
+ ///
+ /// Create a class in the scope, the class can read variables in the scope.
+ /// Its methods can write the variables with the help of 'global' keyword.
+ ///
+ [Test]
+ public void TestScopeClass()
+ {
+ using (Py.GIL())
+ {
+ dynamic _ps = ps;
+ _ps.bb = 100;
+ ps.Exec(
+ "class Class1():\n" +
+ " def __init__(self, value):\n" +
+ " self.value = value\n" +
+ " def call(self, arg):\n" +
+ " return self.value + bb + arg\n" + //use scope variables
+ " def update(self, arg):\n" +
+ " global bb\n" +
+ " bb = self.value + arg\n" //update scope variable
+ );
+ dynamic obj1 = _ps.Class1(20);
+ var result = obj1.call(10).As();
+ Assert.AreEqual(130, result);
+
+ obj1.update(10);
+ result = ps.Get("bb");
+ Assert.AreEqual(30, result);
+ }
+ }
+
+ ///
+ /// Import a python module into the session.
+ /// Equivalent to the Python "import" statement.
+ ///
+ [Test]
+ public void TestImportModule()
+ {
+ using (Py.GIL())
+ {
+ dynamic sys = ps.Import("sys");
+ Assert.IsTrue(ps.Contains("sys"));
+
+ ps.Exec("sys.attr1 = 2");
+ var value1 = ps.Eval("sys.attr1");
+ var value2 = sys.attr1.As();
+ Assert.AreEqual(2, value1);
+ Assert.AreEqual(2, value2);
+
+ //import as
+ ps.Import("sys", "sys1");
+ Assert.IsTrue(ps.Contains("sys1"));
+ }
+ }
+
+ ///
+ /// Create a scope and import variables from a scope,
+ /// exec Python statements in the scope then discard it.
+ ///
+ [Test]
+ public void TestImportScope()
+ {
+ using (Py.GIL())
+ {
+ ps.Set("bb", 100);
+ ps.Set("cc", 10);
+
+ using (var scope = Py.CreateScope())
+ {
+ scope.Import(ps, "ps");
+ scope.Exec("aa = ps.bb + ps.cc + 3");
+ var result = scope.Get("aa");
+ Assert.AreEqual(113, result);
+ }
+
+ Assert.IsFalse(ps.Contains("aa"));
+ }
+ }
+
+ ///
+ /// Create a scope and import variables from a scope,
+ /// exec Python statements in the scope then discard it.
+ ///
+ [Test]
+ public void TestImportAllFromScope()
+ {
+ using (Py.GIL())
+ {
+ ps.Set("bb", 100);
+ ps.Set("cc", 10);
+
+ using (var scope = ps.NewScope())
+ {
+ scope.Exec("aa = bb + cc + 3");
+ var result = scope.Get("aa");
+ Assert.AreEqual(113, result);
+ }
+
+ Assert.IsFalse(ps.Contains("aa"));
+ }
+ }
+
+ ///
+ /// Create a scope and import variables from a scope,
+ /// call the function imported.
+ ///
+ [Test]
+ public void TestImportScopeFunction()
+ {
+ using (Py.GIL())
+ {
+ ps.Set("bb", 100);
+ ps.Set("cc", 10);
+ ps.Exec(
+ "def func1():\n" +
+ " return cc + bb\n");
+
+ using (PyScope scope = ps.NewScope())
+ {
+ //'func1' is imported from the origion scope
+ scope.Exec(
+ "def func2():\n" +
+ " return func1() - cc - bb\n");
+ dynamic func2 = scope.Get("func2");
+
+ var result1 = func2().As();
+ Assert.AreEqual(0, result1);
+
+ scope.Set("cc", 20);//it has no effect on the globals of 'func1'
+ var result2 = func2().As();
+ Assert.AreEqual(-10, result2);
+ scope.Set("cc", 10); //rollback
+
+ ps.Set("cc", 20);
+ var result3 = func2().As();
+ Assert.AreEqual(10, result3);
+ ps.Set("cc", 10); //rollback
+ }
+ }
+ }
+
+ ///
+ /// Import a python module into the session with a new name.
+ /// Equivalent to the Python "import .. as .." statement.
+ ///
+ [Test]
+ public void TestImportScopeByName()
+ {
+ using (Py.GIL())
+ {
+ ps.Set("bb", 100);
+
+ using (var scope = Py.CreateScope())
+ {
+ scope.ImportAll("test");
+ //scope.ImportModule("test");
+
+ Assert.IsTrue(scope.Contains("bb"));
+ }
+ }
+ }
+
+ ///
+ /// Use the locals() and globals() method just like in python module
+ ///
+ [Test]
+ public void TestVariables()
+ {
+ (ps.Variables() as dynamic)["ee"] = new PyInt(200);
+ var a0 = ps.Get("ee");
+ Assert.AreEqual(200, a0);
+
+ ps.Exec("locals()['ee'] = 210");
+ var a1 = ps.Get("ee");
+ Assert.AreEqual(210, a1);
+
+ ps.Exec("globals()['ee'] = 220");
+ var a2 = ps.Get("ee");
+ Assert.AreEqual(220, a2);
+
+ using (var item = ps.Variables())
+ {
+ item["ee"] = new PyInt(230);
+ }
+ var a3 = ps.Get("ee");
+ Assert.AreEqual(230, a3);
+ }
+
+ ///
+ /// Share a pyscope by multiple threads.
+ ///
+ [Test]
+ public void TestThread()
+ {
+ //After the proposal here https://github.com/pythonnet/pythonnet/pull/419 complished,
+ //the BeginAllowThreads statement blow and the last EndAllowThreads statement
+ //should be removed.
+ dynamic _ps = ps;
+ var ts = PythonEngine.BeginAllowThreads();
+ using (Py.GIL())
+ {
+ _ps.res = 0;
+ _ps.bb = 100;
+ _ps.th_cnt = 0;
+ //add function to the scope
+ //can be call many times, more efficient than ast
+ ps.Exec(
+ "def update():\n" +
+ " global res, th_cnt\n" +
+ " res += bb + 1\n" +
+ " th_cnt += 1\n"
+ );
+ }
+ int th_cnt = 3;
+ for (int i =0; i< th_cnt; i++)
+ {
+ System.Threading.Thread th = new System.Threading.Thread(()=>
+ {
+ using (Py.GIL())
+ {
+ //ps.GetVariable("update")(); //call the scope function dynamicly
+ _ps.update();
+ }
+ });
+ th.Start();
+ }
+ //equivalent to Thread.Join, make the main thread join the GIL competition
+ int cnt = 0;
+ while(cnt != th_cnt)
+ {
+ using (Py.GIL())
+ {
+ cnt = ps.Get("th_cnt");
+ }
+ System.Threading.Thread.Sleep(10);
+ }
+ using (Py.GIL())
+ {
+ var result = ps.Get("res");
+ Assert.AreEqual(101* th_cnt, result);
+ }
+ PythonEngine.EndAllowThreads(ts);
+ }
+ }
+}
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/TestRuntime.cs b/src/embed_tests/TestRuntime.cs
index 22e6db0a9..2e0598da7 100644
--- a/src/embed_tests/TestRuntime.cs
+++ b/src/embed_tests/TestRuntime.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using NUnit.Framework;
using Python.Runtime;
@@ -47,5 +47,46 @@ public static void RefCountTest()
Runtime.Runtime.Py_Finalize();
}
+
+ [Test]
+ public static void PyCheck_Iter_PyObject_IsIterable_Test()
+ {
+ Runtime.Runtime.Py_Initialize();
+
+ // Tests that a python list is an iterable, but not an iterator
+ var pyList = Runtime.Runtime.PyList_New(0);
+ Assert.IsFalse(Runtime.Runtime.PyIter_Check(pyList));
+ Assert.IsTrue(Runtime.Runtime.PyObject_IsIterable(pyList));
+
+ // Tests that a python list iterator is both an iterable and an iterator
+ var pyListIter = Runtime.Runtime.PyObject_GetIter(pyList);
+ Assert.IsTrue(Runtime.Runtime.PyObject_IsIterable(pyListIter));
+ Assert.IsTrue(Runtime.Runtime.PyIter_Check(pyListIter));
+
+ // Tests that a python float is neither an iterable nor an iterator
+ var pyFloat = Runtime.Runtime.PyFloat_FromDouble(2.73);
+ Assert.IsFalse(Runtime.Runtime.PyObject_IsIterable(pyFloat));
+ Assert.IsFalse(Runtime.Runtime.PyIter_Check(pyFloat));
+
+ Runtime.Runtime.Py_Finalize();
+ }
+
+ [Test]
+ public static void PyCheck_Iter_PyObject_IsIterable_ThreadingLock_Test()
+ {
+ Runtime.Runtime.Py_Initialize();
+
+ // Create an instance of threading.Lock, which is one of the very few types that does not have the
+ // TypeFlags.HaveIter set in Python 2. This tests a different code path in PyObject_IsIterable and PyIter_Check.
+ var threading = Runtime.Runtime.PyImport_ImportModule("threading");
+ var threadingDict = Runtime.Runtime.PyModule_GetDict(threading);
+ var lockType = Runtime.Runtime.PyDict_GetItemString(threadingDict, "Lock");
+ var lockInstance = Runtime.Runtime.PyObject_CallObject(lockType, Runtime.Runtime.PyTuple_New(0));
+
+ Assert.IsFalse(Runtime.Runtime.PyObject_IsIterable(lockInstance));
+ Assert.IsFalse(Runtime.Runtime.PyIter_Check(lockInstance));
+
+ Runtime.Runtime.Py_Finalize();
+ }
}
}
diff --git a/src/embed_tests/packages.config b/src/embed_tests/packages.config
index 4cb01d3be..8c175f441 100644
--- a/src/embed_tests/packages.config
+++ b/src/embed_tests/packages.config
@@ -1,5 +1,5 @@
-
-
+
+
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/CustomMarshaler.cs b/src/runtime/CustomMarshaler.cs
index 90bb77a71..b51911816 100644
--- a/src/runtime/CustomMarshaler.cs
+++ b/src/runtime/CustomMarshaler.cs
@@ -91,13 +91,13 @@ public static int GetUnicodeByteLength(IntPtr p)
var len = 0;
while (true)
{
- int c = Runtime.UCS == 2
+ int c = Runtime._UCS == 2
? Marshal.ReadInt16(p, len * 2)
: Marshal.ReadInt32(p, len * 4);
if (c == 0)
{
- return len * Runtime.UCS;
+ return len * Runtime._UCS;
}
checked
{
@@ -163,7 +163,7 @@ public override IntPtr MarshalManagedToNative(object managedObj)
}
int totalStrLength = argv.Sum(arg => arg.Length + 1);
- int memSize = argv.Length * IntPtr.Size + totalStrLength * Runtime.UCS;
+ int memSize = argv.Length * IntPtr.Size + totalStrLength * Runtime._UCS;
IntPtr mem = Marshal.AllocHGlobal(memSize);
try
diff --git a/src/runtime/Python.Runtime.15.csproj b/src/runtime/Python.Runtime.15.csproj
new file mode 100644
index 000000000..1ca767ca4
--- /dev/null
+++ b/src/runtime/Python.Runtime.15.csproj
@@ -0,0 +1,133 @@
+
+
+
+ net40;netstandard2.0
+ AnyCPU
+ DebugMono;DebugMonoPY3;ReleaseMono;ReleaseMonoPY3;DebugWin;DebugWinPY3;ReleaseWin;ReleaseWinPY3
+ net45
+ Python.Runtime
+ Python.Runtime
+ Python.Runtime
+ 2.4.0
+ false
+ false
+ false
+ false
+ false
+ false
+ bin\
+ false
+ $(OutputPath)\$(AssemblyName).xml
+ $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml
+ 1591;NU1701
+ ..\..\
+ $(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\
+
+
+
+ $(DefineConstants);PYTHON2;PYTHON27;UCS4
+ true
+ pdbonly
+
+
+ $(DefineConstants);PYTHON3;PYTHON36;UCS4
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);PYTHON2;PYTHON27;UCS4;TRACE;DEBUG
+ false
+ full
+
+
+ true
+ $(DefineConstants);PYTHON3;PYTHON36;UCS4;TRACE;DEBUG
+ false
+ full
+
+
+ $(DefineConstants);PYTHON2;PYTHON27;UCS2
+ true
+ pdbonly
+
+
+ $(DefineConstants);PYTHON3;PYTHON36;UCS2
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);PYTHON2;PYTHON27;UCS2;TRACE;DEBUG
+ false
+ full
+
+
+ true
+ $(DefineConstants);PYTHON3;PYTHON36;UCS2;TRACE;DEBUG
+ false
+ full
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ clr.py
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(TargetPath)
+ $(TargetDir)$(TargetName).pdb
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/runtime/Python.Runtime.csproj b/src/runtime/Python.Runtime.csproj
index 2fd66ad73..82825a626 100644
--- a/src/runtime/Python.Runtime.csproj
+++ b/src/runtime/Python.Runtime.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -20,12 +20,14 @@
false
..\pythonnet.snk
-
+
+
+
PYTHON2;PYTHON27;UCS4
true
@@ -127,6 +129,7 @@
+
@@ -135,6 +138,7 @@
+
@@ -163,4 +167,4 @@
-
+
\ No newline at end of file
diff --git a/src/runtime/Util.cs b/src/runtime/Util.cs
new file mode 100644
index 000000000..dd4418cc9
--- /dev/null
+++ b/src/runtime/Util.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Python.Runtime
+{
+ internal class Util
+ {
+ internal static Int64 ReadCLong(IntPtr tp, int offset)
+ {
+ // On Windows, a C long is always 32 bits.
+ if (Runtime.IsWindows || Runtime.Is32Bit)
+ {
+ return Marshal.ReadInt32(tp, offset);
+ }
+ else
+ {
+ return Marshal.ReadInt64(tp, offset);
+ }
+ }
+
+ internal static void WriteCLong(IntPtr type, int offset, Int64 flags)
+ {
+ if (Runtime.IsWindows || Runtime.Is32Bit)
+ {
+ Marshal.WriteInt32(type, offset, (Int32)(flags & 0xffffffffL));
+ }
+ else
+ {
+ Marshal.WriteInt64(type, offset, flags);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/runtime/classderived.cs b/src/runtime/classderived.cs
index c180f9acc..16d3b99db 100644
--- a/src/runtime/classderived.cs
+++ b/src/runtime/classderived.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -808,7 +808,6 @@ public static void InvokeCtor(IPythonDerivedType obj, string origCtorName, objec
obj,
args);
- var disposeList = new List();
CLRObject self = null;
IntPtr gs = Runtime.PyGILState_Ensure();
try
@@ -821,42 +820,9 @@ public static void InvokeCtor(IPythonDerivedType obj, string origCtorName, objec
// object to be collected.
FieldInfo fi = obj.GetType().GetField("__pyobj__");
fi.SetValue(obj, self);
-
- Runtime.XIncref(self.pyHandle);
- var pyself = new PyObject(self.pyHandle);
- disposeList.Add(pyself);
-
- Runtime.XIncref(Runtime.PyNone);
- var pynone = new PyObject(Runtime.PyNone);
- disposeList.Add(pynone);
-
- // call __init__
- PyObject init = pyself.GetAttr("__init__", pynone);
- disposeList.Add(init);
- if (init.Handle != Runtime.PyNone)
- {
- // if __init__ hasn't been overridden then it will be a managed object
- ManagedType managedMethod = ManagedType.GetManagedObject(init.Handle);
- if (null == managedMethod)
- {
- var pyargs = new PyObject[args.Length];
- for (var i = 0; i < args.Length; ++i)
- {
- pyargs[i] = new PyObject(Converter.ToPython(args[i], args[i]?.GetType()));
- disposeList.Add(pyargs[i]);
- }
-
- disposeList.Add(init.Invoke(pyargs));
- }
- }
}
finally
{
- foreach (PyObject x in disposeList)
- {
- x?.Dispose();
- }
-
// Decrement the python object's reference count.
// This doesn't actually destroy the object, it just sets the reference to this object
// to be a weak reference and it will be destroyed when the C# object is destroyed.
diff --git a/src/runtime/clrobject.cs b/src/runtime/clrobject.cs
index 472e5dcbb..fb3d0e0d7 100644
--- a/src/runtime/clrobject.cs
+++ b/src/runtime/clrobject.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Runtime.InteropServices;
namespace Python.Runtime
@@ -11,7 +11,7 @@ internal CLRObject(object ob, IntPtr tp)
{
IntPtr py = Runtime.PyType_GenericAlloc(tp, 0);
- var flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
+ long flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
if ((flags & TypeFlags.Subclass) != 0)
{
IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.DictOffset(tp));
diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs
index 0bf882cc5..5179c849b 100644
--- a/src/runtime/converter.cs
+++ b/src/runtime/converter.cs
@@ -770,10 +770,14 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object result, bo
goto type_error;
}
double dd = Runtime.PyFloat_AsDouble(op);
+ Runtime.CheckExceptionOccurred();
Runtime.XDecref(op);
if (dd > Single.MaxValue || dd < Single.MinValue)
{
- goto overflow;
+ if (!double.IsInfinity(dd))
+ {
+ goto overflow;
+ }
}
result = (float)dd;
return true;
@@ -785,11 +789,8 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object result, bo
goto type_error;
}
double d = Runtime.PyFloat_AsDouble(op);
+ Runtime.CheckExceptionOccurred();
Runtime.XDecref(op);
- if (d > Double.MaxValue || d < Double.MinValue)
- {
- goto overflow;
- }
result = d;
return true;
}
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/managedtype.cs b/src/runtime/managedtype.cs
index 9ee8d223b..562b2e5f8 100644
--- a/src/runtime/managedtype.cs
+++ b/src/runtime/managedtype.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Runtime.InteropServices;
namespace Python.Runtime
@@ -28,7 +28,7 @@ internal static ManagedType GetManagedObject(IntPtr ob)
tp = ob;
}
- var flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
+ var flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
if ((flags & TypeFlags.Managed) != 0)
{
IntPtr op = tp == ob
@@ -63,7 +63,7 @@ internal static bool IsManagedType(IntPtr ob)
tp = ob;
}
- var flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
+ var flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
if ((flags & TypeFlags.Managed) != 0)
{
return true;
diff --git a/src/runtime/metatype.cs b/src/runtime/metatype.cs
index bfb71e26d..3295ab110 100644
--- a/src/runtime/metatype.cs
+++ b/src/runtime/metatype.cs
@@ -105,7 +105,7 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
flags |= TypeFlags.BaseType;
flags |= TypeFlags.Subclass;
flags |= TypeFlags.HaveGC;
- Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
+ Util.WriteCLong(type, TypeOffset.tp_flags, flags);
TypeManager.CopySlot(base_type, type, TypeOffset.tp_dealloc);
@@ -157,23 +157,13 @@ public static IntPtr tp_call(IntPtr tp, IntPtr args, IntPtr kw)
return IntPtr.Zero;
}
- IntPtr py__init__ = Runtime.PyString_FromString("__init__");
- IntPtr type = Runtime.PyObject_TYPE(obj);
- IntPtr init = Runtime._PyType_Lookup(type, py__init__);
- Runtime.XDecref(py__init__);
+ var init = Runtime.PyObject_GetAttrString(obj, "__init__");
Runtime.PyErr_Clear();
if (init != IntPtr.Zero)
{
- IntPtr bound = Runtime.GetBoundArgTuple(obj, args);
- if (bound == IntPtr.Zero)
- {
- Runtime.XDecref(obj);
- return IntPtr.Zero;
- }
-
- IntPtr result = Runtime.PyObject_Call(init, bound, kw);
- Runtime.XDecref(bound);
+ IntPtr result = Runtime.PyObject_Call(init, args, kw);
+ Runtime.XDecref(init);
if (result == IntPtr.Zero)
{
@@ -211,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;
@@ -247,7 +237,7 @@ public static void tp_dealloc(IntPtr tp)
{
// Fix this when we dont cheat on the handle for subclasses!
- var flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
+ var flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
if ((flags & TypeFlags.Subclass) == 0)
{
IntPtr gc = Marshal.ReadIntPtr(tp, TypeOffset.magic());
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 80704c59e..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();
}
@@ -96,6 +100,27 @@ public object AsManagedObject(Type t)
}
return result;
}
+
+ ///
+ /// As Method
+ ///
+ ///
+ /// Return a managed object of the given type, based on the
+ /// value of the Python object.
+ ///
+ public T As()
+ {
+ if (typeof(T) == typeof(PyObject) || typeof(T) == typeof(object))
+ {
+ return (T)(this as object);
+ }
+ object result;
+ if (!Converter.ToManaged(obj, typeof(T), out result, false))
+ {
+ throw new InvalidCastException("cannot convert object to target type");
+ }
+ return (T)result;
+ }
///
@@ -781,7 +806,7 @@ public bool IsCallable()
///
public bool IsIterable()
{
- return Runtime.PyIter_Check(obj);
+ return Runtime.PyObject_IsIterable(obj);
}
diff --git a/src/runtime/pyscope.cs b/src/runtime/pyscope.cs
new file mode 100644
index 000000000..67f93c6e2
--- /dev/null
+++ b/src/runtime/pyscope.cs
@@ -0,0 +1,657 @@
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.Dynamic;
+
+namespace Python.Runtime
+{
+ public class PyScopeException : Exception
+ {
+ public PyScopeException(string message)
+ : base(message)
+ {
+
+ }
+ }
+
+ ///
+ /// Classes/methods have this attribute must be used with GIL obtained.
+ ///
+ public class PyGILAttribute : Attribute
+ {
+ }
+
+ [PyGIL]
+ public class PyScope : DynamicObject, IDisposable
+ {
+ public readonly string Name;
+
+ ///
+ /// the python Module object the scope associated with.
+ ///
+ internal readonly IntPtr obj;
+
+ ///
+ /// the variable dict of the scope.
+ ///
+ internal readonly IntPtr variables;
+
+ private bool _isDisposed;
+
+ ///
+ /// The Manager this scope associated with.
+ /// It provides scopes this scope can import.
+ ///
+ internal readonly PyScopeManager Manager;
+
+ ///
+ /// event which will be triggered after the scope disposed.
+ ///
+ public event Action OnDispose;
+
+ ///
+ /// Constructor
+ ///
+ ///
+ /// Create a scope based on a Python Module.
+ ///
+ internal PyScope(IntPtr ptr, PyScopeManager manager)
+ {
+ if (!Runtime.PyType_IsSubtype(Runtime.PyObject_TYPE(ptr), Runtime.PyModuleType))
+ {
+ throw new PyScopeException("object is not a module");
+ }
+ Manager = manager ?? PyScopeManager.Global;
+ obj = ptr;
+ //Refcount of the variables not increase
+ variables = Runtime.PyModule_GetDict(obj);
+ Runtime.CheckExceptionOccurred();
+
+ Runtime.PyDict_SetItemString(
+ variables, "__builtins__",
+ Runtime.PyEval_GetBuiltins()
+ );
+ this.Name = this.Get("__name__");
+ }
+
+ ///
+ /// return the variable dict of the scope.
+ ///
+ ///
+ public PyDict Variables()
+ {
+ Runtime.XIncref(variables);
+ return new PyDict(variables);
+ }
+
+ ///
+ /// Create a scope, and import all from this scope
+ ///
+ ///
+ public PyScope NewScope()
+ {
+ var scope = Manager.Create();
+ scope.ImportAll(this);
+ return scope;
+ }
+
+ ///
+ /// Import method
+ ///
+ ///
+ /// Import a scope or a module of given name,
+ /// scope will be looked up first.
+ ///
+ public dynamic Import(string name, string asname = null)
+ {
+ Check();
+ if (String.IsNullOrEmpty(asname))
+ {
+ asname = name;
+ }
+ PyScope scope;
+ Manager.TryGet(name, out scope);
+ if (scope != null)
+ {
+ Import(scope, asname);
+ return scope;
+ }
+ else
+ {
+ PyObject module = PythonEngine.ImportModule(name);
+ Import(module, asname);
+ return module;
+ }
+ }
+
+ ///
+ /// Import method
+ ///
+ ///
+ /// Import a scope as a variable of given name.
+ ///
+ public void Import(PyScope scope, string asname)
+ {
+ this.Set(asname, scope.obj);
+ }
+
+ ///
+ /// Import Method
+ ///
+ ///
+ /// The 'import .. as ..' statement in Python.
+ /// Import a module as a variable into the scope.
+ ///
+ public void Import(PyObject module, string asname = null)
+ {
+ if (String.IsNullOrEmpty(asname))
+ {
+ asname = module.GetAttr("__name__").As();
+ }
+ Set(asname, module);
+ }
+
+ ///
+ /// ImportAll Method
+ ///
+ ///
+ /// The 'import * from ..' statement in Python.
+ /// Import all content of a scope/module of given name into the scope, scope will be looked up first.
+ ///
+ public void ImportAll(string name)
+ {
+ PyScope scope;
+ Manager.TryGet(name, out scope);
+ if (scope != null)
+ {
+ ImportAll(scope);
+ return;
+ }
+ else
+ {
+ PyObject module = PythonEngine.ImportModule(name);
+ ImportAll(module);
+ }
+ }
+
+ ///
+ /// ImportAll Method
+ ///
+ ///
+ /// Import all variables of the scope into this scope.
+ ///
+ public void ImportAll(PyScope scope)
+ {
+ int result = Runtime.PyDict_Update(variables, scope.variables);
+ if (result < 0)
+ {
+ throw new PythonException();
+ }
+ }
+
+ ///
+ /// ImportAll Method
+ ///
+ ///
+ /// Import all variables of the module into this scope.
+ ///
+ public void ImportAll(PyObject module)
+ {
+ if (Runtime.PyObject_Type(module.obj) != Runtime.PyModuleType)
+ {
+ throw new PyScopeException("object is not a module");
+ }
+ var module_dict = Runtime.PyModule_GetDict(module.obj);
+ int result = Runtime.PyDict_Update(variables, module_dict);
+ if (result < 0)
+ {
+ throw new PythonException();
+ }
+ }
+
+ ///
+ /// ImportAll Method
+ ///
+ ///
+ /// Import all variables in the dictionary into this scope.
+ ///
+ public void ImportAll(PyDict dict)
+ {
+ int result = Runtime.PyDict_Update(variables, dict.obj);
+ if (result < 0)
+ {
+ throw new PythonException();
+ }
+ }
+
+ ///
+ /// Execute method
+ ///
+ ///
+ /// Execute a Python ast and return the result as a PyObject.
+ /// The ast can be either an expression or stmts.
+ ///
+ public PyObject Execute(PyObject script, PyDict locals = null)
+ {
+ Check();
+ IntPtr _locals = locals == null ? variables : locals.obj;
+ IntPtr ptr = Runtime.PyEval_EvalCode(script.Handle, variables, _locals);
+ Runtime.CheckExceptionOccurred();
+ if (ptr == Runtime.PyNone)
+ {
+ Runtime.XDecref(ptr);
+ return null;
+ }
+ return new PyObject(ptr);
+ }
+
+ ///
+ /// Execute method
+ ///
+ ///
+ /// Execute a Python ast and return the result as a PyObject,
+ /// and convert the result to a Managed Object of given type.
+ /// The ast can be either an expression or stmts.
+ ///
+ public T Execute(PyObject script, PyDict locals = null)
+ {
+ Check();
+ PyObject pyObj = Execute(script, locals);
+ if (pyObj == null)
+ {
+ return default(T);
+ }
+ var obj = pyObj.As();
+ return obj;
+ }
+
+ ///
+ /// Eval method
+ ///
+ ///
+ /// Evaluate a Python expression and return the result as a PyObject
+ /// or null if an exception is raised.
+ ///
+ public PyObject Eval(string code, PyDict locals = null)
+ {
+ Check();
+ IntPtr _locals = locals == null ? variables : locals.obj;
+ var flag = (IntPtr)Runtime.Py_eval_input;
+ IntPtr ptr = Runtime.PyRun_String(
+ code, flag, variables, _locals
+ );
+ Runtime.CheckExceptionOccurred();
+ return new PyObject(ptr);
+ }
+
+ ///
+ /// Evaluate a Python expression
+ ///
+ ///
+ /// Evaluate a Python expression
+ /// and convert the result to a Managed Object of given type.
+ ///
+ public T Eval(string code, PyDict locals = null)
+ {
+ Check();
+ PyObject pyObj = Eval(code, locals);
+ var obj = pyObj.As();
+ return obj;
+ }
+
+ ///
+ /// Exec Method
+ ///
+ ///
+ /// Exec a Python script and save its local variables in the current local variable dict.
+ ///
+ public void Exec(string code, PyDict locals = null)
+ {
+ Check();
+ IntPtr _locals = locals == null ? variables : locals.obj;
+ Exec(code, variables, _locals);
+ }
+
+ private void Exec(string code, IntPtr _globals, IntPtr _locals)
+ {
+ var flag = (IntPtr)Runtime.Py_file_input;
+ IntPtr ptr = Runtime.PyRun_String(
+ code, flag, _globals, _locals
+ );
+ Runtime.CheckExceptionOccurred();
+ if (ptr != Runtime.PyNone)
+ {
+ throw new PythonException();
+ }
+ Runtime.XDecref(ptr);
+ }
+
+ ///
+ /// Set Variable Method
+ ///
+ ///
+ /// Add a new variable to the variables dict if it not exist
+ /// or update its value if the variable exists.
+ ///
+ public void Set(string name, object value)
+ {
+ IntPtr _value = Converter.ToPython(value, value?.GetType());
+ Set(name, _value);
+ Runtime.XDecref(_value);
+ }
+
+ private void Set(string name, IntPtr value)
+ {
+ Check();
+ using (var pyKey = new PyString(name))
+ {
+ int r = Runtime.PyObject_SetItem(variables, pyKey.obj, value);
+ if (r < 0)
+ {
+ throw new PythonException();
+ }
+ }
+ }
+
+ ///
+ /// Remove Method
+ ///
+ ///
+ /// Remove a variable from the variables dict.
+ ///
+ public void Remove(string name)
+ {
+ Check();
+ using (var pyKey = new PyString(name))
+ {
+ int r = Runtime.PyObject_DelItem(variables, pyKey.obj);
+ if (r < 0)
+ {
+ throw new PythonException();
+ }
+ }
+ }
+
+ ///
+ /// Contains Method
+ ///
+ ///
+ /// Returns true if the variable exists in the scope.
+ ///
+ public bool Contains(string name)
+ {
+ Check();
+ using (var pyKey = new PyString(name))
+ {
+ return Runtime.PyMapping_HasKey(variables, pyKey.obj) != 0;
+ }
+ }
+
+ ///
+ /// Get Method
+ ///
+ ///
+ /// Returns the value of the variable of given name.
+ /// If the variable does not exist, throw an Exception.
+ ///
+ public PyObject Get(string name)
+ {
+ PyObject scope;
+ var state = TryGet(name, out scope);
+ if (!state)
+ {
+ throw new PyScopeException($"The scope of name '{Name}' has no attribute '{name}'");
+ }
+ return scope;
+ }
+
+ ///
+ /// TryGet Method
+ ///
+ ///
+ /// Returns the value of the variable, local variable first.
+ /// If the variable does not exist, return null.
+ ///
+ public bool TryGet(string name, out PyObject value)
+ {
+ Check();
+ using (var pyKey = new PyString(name))
+ {
+ if (Runtime.PyMapping_HasKey(variables, pyKey.obj) != 0)
+ {
+ IntPtr op = Runtime.PyObject_GetItem(variables, pyKey.obj);
+ if (op == IntPtr.Zero)
+ {
+ throw new PythonException();
+ }
+ if (op == Runtime.PyNone)
+ {
+ Runtime.XDecref(op);
+ value = null;
+ return true;
+ }
+ value = new PyObject(op);
+ return true;
+ }
+ else
+ {
+ value = null;
+ return false;
+ }
+ }
+ }
+
+ ///
+ /// Get Method
+ ///
+ ///
+ /// Obtain the value of the variable of given name,
+ /// and convert the result to a Managed Object of given type.
+ /// If the variable does not exist, throw an Exception.
+ ///
+ public T Get(string name)
+ {
+ Check();
+ PyObject pyObj = Get(name);
+ if (pyObj == null)
+ {
+ return default(T);
+ }
+ return pyObj.As();
+ }
+
+ ///
+ /// TryGet Method
+ ///
+ ///
+ /// Obtain the value of the variable of given name,
+ /// and convert the result to a Managed Object of given type.
+ /// If the variable does not exist, return false.
+ ///
+ public bool TryGet(string name, out T value)
+ {
+ Check();
+ PyObject pyObj;
+ var result = TryGet(name, out pyObj);
+ if (!result)
+ {
+ value = default(T);
+ return false;
+ }
+ if (pyObj == null)
+ {
+ if (typeof(T).IsValueType)
+ {
+ throw new PyScopeException($"The value of the attribute '{name}' is None which cannot be convert to '{typeof(T).ToString()}'");
+ }
+ else
+ {
+ value = default(T);
+ return true;
+ }
+ }
+ value = pyObj.As();
+ return true;
+ }
+
+ public override bool TryGetMember(GetMemberBinder binder, out object result)
+ {
+ result = this.Get(binder.Name);
+ return true;
+ }
+
+ public override bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ this.Set(binder.Name, value);
+ return true;
+ }
+
+ private void Check()
+ {
+ if (_isDisposed)
+ {
+ throw new PyScopeException($"The scope of name '{Name}' object has been disposed");
+ }
+ }
+
+ public void Dispose()
+ {
+ if (_isDisposed)
+ {
+ return;
+ }
+ _isDisposed = true;
+ Runtime.XDecref(obj);
+ this.OnDispose?.Invoke(this);
+ }
+
+ ~PyScope()
+ {
+ // We needs to disable Finalizers until it's valid implementation.
+ // Current implementation can produce low probability floating bugs.
+ return;
+
+ Dispose();
+ }
+ }
+
+ public class PyScopeManager
+ {
+ public readonly static PyScopeManager Global = new PyScopeManager();
+
+ private Dictionary NamedScopes = new Dictionary();
+
+ internal PyScope NewScope(string name)
+ {
+ if (name == null)
+ {
+ name = "";
+ }
+ var module = Runtime.PyModule_New(name);
+ if (module == IntPtr.Zero)
+ {
+ throw new PythonException();
+ }
+ return new PyScope(module, this);
+ }
+
+ ///
+ /// Create Method
+ ///
+ ///
+ /// Create an anonymous scope.
+ ///
+ [PyGIL]
+ public PyScope Create()
+ {
+ var scope = this.NewScope(null);
+ return scope;
+ }
+
+ ///
+ /// Create Method
+ ///
+ ///
+ /// Create an named scope of given name.
+ ///
+ [PyGIL]
+ public PyScope Create(string name)
+ {
+ if (String.IsNullOrEmpty(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+ if (name != null && Contains(name))
+ {
+ throw new PyScopeException($"A scope of name '{name}' does already exist");
+ }
+ var scope = this.NewScope(name);
+ scope.OnDispose += Remove;
+ NamedScopes[name] = scope;
+ return scope;
+ }
+
+ ///
+ /// Contains Method
+ ///
+ ///
+ /// return true if the scope exists in this manager.
+ ///
+ public bool Contains(string name)
+ {
+ return NamedScopes.ContainsKey(name);
+ }
+
+ ///
+ /// Get Method
+ ///
+ ///
+ /// Find the scope in this manager.
+ /// If the scope not exist, an Exception will be thrown.
+ ///
+ public PyScope Get(string name)
+ {
+ if (String.IsNullOrEmpty(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+ if (NamedScopes.ContainsKey(name))
+ {
+ return NamedScopes[name];
+ }
+ throw new PyScopeException($"There is no scope named '{name}' registered in this manager");
+ }
+
+ ///
+ /// Get Method
+ ///
+ ///
+ /// Try to find the scope in this manager.
+ ///
+ public bool TryGet(string name, out PyScope scope)
+ {
+ return NamedScopes.TryGetValue(name, out scope);
+ }
+
+ ///
+ /// Remove Method
+ ///
+ ///
+ /// remove the scope from this manager.
+ ///
+ public void Remove(PyScope scope)
+ {
+ NamedScopes.Remove(scope.Name);
+ }
+
+ [PyGIL]
+ public void Clear()
+ {
+ var scopes = NamedScopes.Values.ToList();
+ foreach (var scope in scopes)
+ {
+ scope.Dispose();
+ }
+ }
+ }
+}
diff --git a/src/runtime/pythonengine.cs b/src/runtime/pythonengine.cs
index 9ddd85da6..556da698f 100644
--- a/src/runtime/pythonengine.cs
+++ b/src/runtime/pythonengine.cs
@@ -294,6 +294,7 @@ public static void Shutdown()
{
if (initialized)
{
+ PyScopeManager.Global.Clear();
Marshal.FreeHGlobal(_pythonHome);
_pythonHome = IntPtr.Zero;
Marshal.FreeHGlobal(_programName);
@@ -421,6 +422,13 @@ public static PyObject ModuleFromString(string name, string code)
return new PyObject(m);
}
+ public static PyObject Compile(string code, string filename = "", RunFlagType mode = RunFlagType.File)
+ {
+ var flag = (IntPtr)mode;
+ IntPtr ptr = Runtime.Py_CompileString(code, filename, flag);
+ Runtime.CheckExceptionOccurred();
+ return new PyObject(ptr);
+ }
///
/// Eval Method
@@ -539,6 +547,18 @@ public static GILState GIL()
return new GILState();
}
+ public static PyScope CreateScope()
+ {
+ var scope = PyScopeManager.Global.Create();
+ return scope;
+ }
+
+ public static PyScope CreateScope(string name)
+ {
+ var scope = PyScopeManager.Global.Create(name);
+ return scope;
+ }
+
public class GILState : IDisposable
{
private IntPtr state;
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 9ee693cf3..abd0661a4 100644
--- a/src/runtime/runtime.cs
+++ b/src/runtime/runtime.cs
@@ -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";
@@ -80,8 +103,14 @@ public static IntPtr GetProcAddress(IntPtr dllHandle, string name)
///
public class Runtime
{
+ // C# compiler copies constants to the assemblies that references this library.
+ // We needs to replace all public constants to static readonly fields to allow
+ // binary substitution of different Python.Runtime.dll builds in a target application.
+
+ public static int UCS => _UCS;
+
#if UCS4
- public const int UCS = 4;
+ internal const int _UCS = 4;
///
/// EntryPoint to be used in DllImport to map to correct Unicode
@@ -89,7 +118,7 @@ public class Runtime
///
private const string PyUnicodeEntryPoint = "PyUnicodeUCS4_";
#elif UCS2
- public const int UCS = 2;
+ internal const int _UCS = 2;
///
/// EntryPoint to be used in DllImport to map to correct Unicode
@@ -100,32 +129,39 @@ public class Runtime
#error You must define either UCS2 or UCS4!
#endif
+ // C# compiler copies constants to the assemblies that references this library.
+ // We needs to replace all public constants to static readonly fields to allow
+ // binary substitution of different Python.Runtime.dll builds in a target application.
+
+ public static string pyversion => _pyversion;
+ public static string pyver => _pyver;
+
#if PYTHON27
- public const string pyversion = "2.7";
- public const string pyver = "27";
+ internal const string _pyversion = "2.7";
+ internal const string _pyver = "27";
#elif PYTHON33
- public const string pyversion = "3.3";
- public const string pyver = "33";
+ internal const string _pyversion = "3.3";
+ internal const string _pyver = "33";
#elif PYTHON34
- public const string pyversion = "3.4";
- public const string pyver = "34";
+ internal const string _pyversion = "3.4";
+ internal const string _pyver = "34";
#elif PYTHON35
- public const string pyversion = "3.5";
- public const string pyver = "35";
+ internal const string _pyversion = "3.5";
+ internal const string _pyver = "35";
#elif PYTHON36
- public const string pyversion = "3.6";
- public const string pyver = "36";
+ internal const string _pyversion = "3.6";
+ internal const string _pyver = "36";
#elif PYTHON37 // TODO: Add `interop37.cs` after PY37 is released
- public const string pyversion = "3.7";
- public const string pyver = "37";
+ internal const string _pyversion = "3.7";
+ internal const string _pyver = "37";
#else
#error You must define one of PYTHON33 to PYTHON37 or PYTHON27
#endif
#if MONO_LINUX || MONO_OSX // Linux/macOS use dotted version string
- internal const string dllBase = "python" + pyversion;
+ internal const string dllBase = "python" + _pyversion;
#else // Windows
- internal const string dllBase = "python" + pyver;
+ internal const string dllBase = "python" + _pyver;
#endif
#if PYTHON_WITH_PYDEBUG
@@ -139,26 +175,36 @@ public class Runtime
internal const string dllWithPyMalloc = "";
#endif
-#if PYTHON_WITHOUT_ENABLE_SHARED
- public const string PythonDll = "__Internal";
+ // C# compiler copies constants to the assemblies that references this library.
+ // We needs to replace all public constants to static readonly fields to allow
+ // binary substitution of different Python.Runtime.dll builds in a target application.
+
+ public static readonly string PythonDLL = _PythonDll;
+
+#if PYTHON_WITHOUT_ENABLE_SHARED && !NETSTANDARD
+ internal const string _PythonDll = "__Internal";
#else
- public const string PythonDll = dllBase + dllWithPyDebug + dllWithPyMalloc;
+ internal const string _PythonDll = dllBase + dllWithPyDebug + dllWithPyMalloc;
#endif
- public static readonly int pyversionnumber = Convert.ToInt32(pyver);
+ public static readonly int pyversionnumber = Convert.ToInt32(_pyver);
// set to true when python is finalizing
internal static object IsFinalizingLock = new object();
internal static bool IsFinalizing;
internal static bool Is32Bit = IntPtr.Size == 4;
+
+ // .NET core: System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
+ internal static bool IsWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
+
internal static bool IsPython2 = pyversionnumber < 30;
internal static bool IsPython3 = pyversionnumber >= 30;
///
/// Encoding to use to convert Unicode to/from Managed to Native
///
- internal static readonly Encoding PyEncoding = UCS == 2 ? Encoding.Unicode : Encoding.UTF32;
+ internal static readonly Encoding PyEncoding = _UCS == 2 ? Encoding.Unicode : Encoding.UTF32;
///
/// Initialize the runtime...
@@ -274,19 +320,19 @@ internal static void Initialize()
Error = new IntPtr(-1);
-#if PYTHON3
IntPtr dllLocal = IntPtr.Zero;
- if (PythonDll != "__Internal")
+
+ if (_PythonDll != "__Internal")
{
- NativeMethods.LoadLibrary(PythonDll);
+ dllLocal = NativeMethods.LoadLibrary(_PythonDll);
}
_PyObject_NextNotImplemented = NativeMethods.GetProcAddress(dllLocal, "_PyObject_NextNotImplemented");
+
#if !(MONO_LINUX || MONO_OSX)
if (dllLocal != IntPtr.Zero)
{
NativeMethods.FreeLibrary(dllLocal);
}
-#endif
#endif
// Initialize modules that depend on the runtime class.
@@ -349,8 +395,8 @@ internal static int AtExit()
#if PYTHON3
internal static IntPtr PyBytesType;
- internal static IntPtr _PyObject_NextNotImplemented;
#endif
+ internal static IntPtr _PyObject_NextNotImplemented;
internal static IntPtr PyNotImplemented;
internal const int Py_LT = 0;
@@ -380,29 +426,6 @@ internal static void CheckExceptionOccurred()
}
}
- internal static IntPtr GetBoundArgTuple(IntPtr obj, IntPtr args)
- {
- if (PyObject_TYPE(args) != PyTupleType)
- {
- Exceptions.SetError(Exceptions.TypeError, "tuple expected");
- return IntPtr.Zero;
- }
- int size = PyTuple_Size(args);
- IntPtr items = PyTuple_New(size + 1);
- PyTuple_SetItem(items, 0, obj);
- XIncref(obj);
-
- for (var i = 0; i < size; i++)
- {
- IntPtr item = PyTuple_GetItem(args, i);
- XIncref(item);
- PyTuple_SetItem(items, i + 1, item);
- }
-
- return items;
- }
-
-
internal static IntPtr ExtendTuple(IntPtr t, params IntPtr[] args)
{
int size = PyTuple_Size(t);
@@ -499,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
@@ -520,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
@@ -570,7 +593,7 @@ internal static unsafe long Refcount(IntPtr op)
/// Limit this function usage for Testing and Py_Debug builds
///
/// PyObject Ptr
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void Py_IncRef(IntPtr ob);
///
@@ -578,157 +601,160 @@ internal static unsafe long Refcount(IntPtr op)
/// Limit this function usage for Testing and Py_Debug builds
///
/// PyObject Ptr
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void Py_DecRef(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void Py_Initialize();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int Py_IsInitialized();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void Py_Finalize();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_NewInterpreter();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void Py_EndInterpreter(IntPtr threadState);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyThreadState_New(IntPtr istate);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyThreadState_Get();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyThread_get_key_value(IntPtr key);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyThread_get_thread_ident();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyThread_set_key_value(IntPtr key, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyThreadState_Swap(IntPtr key);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyGILState_Ensure();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyGILState_Release(IntPtr gs);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyGILState_GetThisThreadState();
#if PYTHON3
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Py_Main(
int argc,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(StrArrayMarshaler))] string[] argv
);
#elif PYTHON2
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Py_Main(int argc, string[] argv);
#endif
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyEval_InitThreads();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyEval_ThreadsInitialized();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyEval_AcquireLock();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyEval_ReleaseLock();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyEval_AcquireThread(IntPtr tstate);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyEval_ReleaseThread(IntPtr tstate);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyEval_SaveThread();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyEval_RestoreThread(IntPtr tstate);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyEval_GetBuiltins();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyEval_GetGlobals();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyEval_GetLocals();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_GetProgramName();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void Py_SetProgramName(IntPtr name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_GetPythonHome();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void Py_SetPythonHome(IntPtr home);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_GetPath();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void Py_SetPath(IntPtr home);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_GetVersion();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_GetPlatform();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_GetCopyright();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_GetCompiler();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_GetBuildInfo();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyRun_SimpleString(string code);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyRun_String(string code, IntPtr st, IntPtr globals, IntPtr locals);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr PyEval_EvalCode(IntPtr co, IntPtr globals, IntPtr locals);
+
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Py_CompileString(string code, string file, IntPtr tok);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyImport_ExecCodeModule(string name, IntPtr code);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyCFunction_NewEx(IntPtr ml, IntPtr self, IntPtr mod);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyCFunction_Call(IntPtr func, IntPtr args, IntPtr kw);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyClass_New(IntPtr bases, IntPtr dict, IntPtr name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyInstance_New(IntPtr cls, IntPtr args, IntPtr kw);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyInstance_NewRaw(IntPtr cls, IntPtr dict);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyMethod_New(IntPtr func, IntPtr self, IntPtr cls);
@@ -777,44 +803,59 @@ internal static string PyObject_GetTypeName(IntPtr op)
return Marshal.PtrToStringAnsi(ppName);
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ ///
+ /// Test whether the Python object is an iterable.
+ ///
+ internal static bool PyObject_IsIterable(IntPtr pointer)
+ {
+ var ob_type = Marshal.ReadIntPtr(pointer, ObjectOffset.ob_type);
+#if PYTHON2
+ long tp_flags = Util.ReadCLong(ob_type, TypeOffset.tp_flags);
+ if ((tp_flags & TypeFlags.HaveIter) == 0)
+ return false;
+#endif
+ IntPtr tp_iter = Marshal.ReadIntPtr(ob_type, TypeOffset.tp_iter);
+ return tp_iter != IntPtr.Zero;
+ }
+
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_HasAttrString(IntPtr pointer, string name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_GetAttrString(IntPtr pointer, string name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_SetAttrString(IntPtr pointer, string name, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_HasAttr(IntPtr pointer, IntPtr name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_GetAttr(IntPtr pointer, IntPtr name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_SetAttr(IntPtr pointer, IntPtr name, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_GetItem(IntPtr pointer, IntPtr key);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_SetItem(IntPtr pointer, IntPtr key, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_DelItem(IntPtr pointer, IntPtr key);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_GetIter(IntPtr op);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_Call(IntPtr pointer, IntPtr args, IntPtr kw);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_CallObject(IntPtr pointer, IntPtr args);
#if PYTHON3
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_RichCompareBool(IntPtr value1, IntPtr value2, int opid);
internal static int PyObject_Compare(IntPtr value1, IntPtr value2)
@@ -842,47 +883,47 @@ internal static int PyObject_Compare(IntPtr value1, IntPtr value2)
return -1;
}
#elif PYTHON2
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_Compare(IntPtr value1, IntPtr value2);
#endif
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_IsInstance(IntPtr ob, IntPtr type);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_IsSubclass(IntPtr ob, IntPtr type);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyCallable_Check(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_IsTrue(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_Not(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_Size(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_Hash(IntPtr op);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_Repr(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_Str(IntPtr pointer);
#if PYTHON3
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "PyObject_Str")]
internal static extern IntPtr PyObject_Unicode(IntPtr pointer);
#elif PYTHON2
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_Unicode(IntPtr pointer);
#endif
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_Dir(IntPtr pointer);
@@ -891,21 +932,21 @@ internal static int PyObject_Compare(IntPtr value1, IntPtr value2)
//====================================================================
#if PYTHON3
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "PyNumber_Long")]
internal static extern IntPtr PyNumber_Int(IntPtr ob);
#elif PYTHON2
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Int(IntPtr ob);
#endif
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Long(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Float(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern bool PyNumber_Check(IntPtr ob);
internal static bool PyInt_Check(IntPtr ob)
@@ -931,32 +972,32 @@ internal static IntPtr PyInt_FromInt64(long value)
}
#if PYTHON3
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "PyLong_FromLong")]
private static extern IntPtr PyInt_FromLong(IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "PyLong_AsLong")]
internal static extern int PyInt_AsLong(IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "PyLong_FromString")]
internal static extern IntPtr PyInt_FromString(string value, IntPtr end, int radix);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "PyLong_GetMax")]
internal static extern int PyInt_GetMax();
#elif PYTHON2
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr PyInt_FromLong(IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyInt_AsLong(IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyInt_FromString(string value, IntPtr end, int radix);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyInt_GetMax();
#endif
@@ -965,34 +1006,34 @@ internal static bool PyLong_Check(IntPtr ob)
return PyObject_TYPE(ob) == PyLongType;
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyLong_FromLong(long value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyLong_FromUnsignedLong(uint value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyLong_FromDouble(double value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyLong_FromLongLong(long value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyLong_FromUnsignedLongLong(ulong value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyLong_FromString(string value, IntPtr end, int radix);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyLong_AsLong(IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern uint PyLong_AsUnsignedLong(IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern long PyLong_AsLongLong(IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern ulong PyLong_AsUnsignedLongLong(IntPtr value);
internal static bool PyFloat_Check(IntPtr ob)
@@ -1000,88 +1041,88 @@ internal static bool PyFloat_Check(IntPtr ob)
return PyObject_TYPE(ob) == PyFloatType;
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyFloat_FromDouble(double value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyFloat_FromString(IntPtr value, IntPtr junk);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern double PyFloat_AsDouble(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Add(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Subtract(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Multiply(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Divide(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_And(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Xor(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Or(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Lshift(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Rshift(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Power(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Remainder(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceAdd(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceSubtract(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceMultiply(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceDivide(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceAnd(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceXor(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceOr(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceLshift(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceRshift(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlacePower(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_InPlaceRemainder(IntPtr o1, IntPtr o2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Negative(IntPtr o1);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Positive(IntPtr o1);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyNumber_Invert(IntPtr o1);
@@ -1089,49 +1130,49 @@ internal static bool PyFloat_Check(IntPtr ob)
// Python sequence API
//====================================================================
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern bool PySequence_Check(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PySequence_GetItem(IntPtr pointer, int index);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PySequence_SetItem(IntPtr pointer, int index, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PySequence_DelItem(IntPtr pointer, int index);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PySequence_GetSlice(IntPtr pointer, int i1, int i2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PySequence_SetSlice(IntPtr pointer, int i1, int i2, IntPtr v);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PySequence_DelSlice(IntPtr pointer, int i1, int i2);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PySequence_Size(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PySequence_Contains(IntPtr pointer, IntPtr item);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PySequence_Concat(IntPtr pointer, IntPtr other);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PySequence_Repeat(IntPtr pointer, int count);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PySequence_Index(IntPtr pointer, IntPtr item);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PySequence_Count(IntPtr pointer, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PySequence_Tuple(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PySequence_List(IntPtr pointer);
@@ -1156,10 +1197,10 @@ internal static IntPtr PyString_FromString(string value)
}
#if PYTHON3
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyBytes_FromString(string op);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyBytes_Size(IntPtr op);
internal static IntPtr PyBytes_AS_STRING(IntPtr ob)
@@ -1167,23 +1208,23 @@ internal static IntPtr PyBytes_AS_STRING(IntPtr ob)
return ob + BytesOffset.ob_sval;
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "PyUnicode_FromStringAndSize")]
internal static extern IntPtr PyString_FromStringAndSize(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string value,
int size
);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyUnicode_FromStringAndSize(IntPtr value, int size);
#elif PYTHON2
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyString_FromStringAndSize(string value, int size);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyString_AsString(IntPtr op);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyString_Size(IntPtr pointer);
#endif
@@ -1193,13 +1234,13 @@ internal static bool PyUnicode_Check(IntPtr ob)
}
#if PYTHON3
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyUnicode_FromObject(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyUnicode_FromEncodedObject(IntPtr ob, IntPtr enc, IntPtr err);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyUnicode_FromKindAndData(
int kind,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UcsMarshaler))] string s,
@@ -1208,42 +1249,42 @@ int size
internal static IntPtr PyUnicode_FromUnicode(string s, int size)
{
- return PyUnicode_FromKindAndData(UCS, s, size);
+ return PyUnicode_FromKindAndData(_UCS, s, size);
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyUnicode_GetSize(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyUnicode_AsUnicode(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyUnicode_FromOrdinal(int c);
#elif PYTHON2
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = PyUnicodeEntryPoint + "FromObject")]
internal static extern IntPtr PyUnicode_FromObject(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = PyUnicodeEntryPoint + "FromEncodedObject")]
internal static extern IntPtr PyUnicode_FromEncodedObject(IntPtr ob, IntPtr enc, IntPtr err);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = PyUnicodeEntryPoint + "FromUnicode")]
internal static extern IntPtr PyUnicode_FromUnicode(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UcsMarshaler))] string s,
int size
);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = PyUnicodeEntryPoint + "GetSize")]
internal static extern int PyUnicode_GetSize(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = PyUnicodeEntryPoint + "AsUnicode")]
internal static extern IntPtr PyUnicode_AsUnicode(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
EntryPoint = PyUnicodeEntryPoint + "FromOrdinal")]
internal static extern IntPtr PyUnicode_FromOrdinal(int c);
#endif
@@ -1282,7 +1323,7 @@ internal static string GetManagedString(IntPtr op)
IntPtr p = PyUnicode_AsUnicode(op);
int length = PyUnicode_GetSize(op);
- int size = length * UCS;
+ int size = length * _UCS;
var buffer = new byte[size];
Marshal.Copy(p, buffer, 0, size);
return PyEncoding.GetString(buffer, 0, size);
@@ -1301,52 +1342,52 @@ internal static bool PyDict_Check(IntPtr ob)
return PyObject_TYPE(ob) == PyDictType;
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyDict_New();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyDictProxy_New(IntPtr dict);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyDict_GetItem(IntPtr pointer, IntPtr key);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyDict_GetItemString(IntPtr pointer, string key);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyDict_SetItem(IntPtr pointer, IntPtr key, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyDict_SetItemString(IntPtr pointer, string key, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyDict_DelItem(IntPtr pointer, IntPtr key);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyDict_DelItemString(IntPtr pointer, string key);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyMapping_HasKey(IntPtr pointer, IntPtr key);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyDict_Keys(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyDict_Values(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyDict_Items(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyDict_Copy(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyDict_Update(IntPtr pointer, IntPtr other);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyDict_Clear(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyDict_Size(IntPtr pointer);
@@ -1359,37 +1400,37 @@ internal static bool PyList_Check(IntPtr ob)
return PyObject_TYPE(ob) == PyListType;
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyList_New(int size);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyList_AsTuple(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyList_GetItem(IntPtr pointer, int index);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_SetItem(IntPtr pointer, int index, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_Insert(IntPtr pointer, int index, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_Append(IntPtr pointer, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_Reverse(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_Sort(IntPtr pointer);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyList_GetSlice(IntPtr pointer, int start, int end);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_SetSlice(IntPtr pointer, int start, int end, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_Size(IntPtr pointer);
@@ -1402,19 +1443,19 @@ internal static bool PyTuple_Check(IntPtr ob)
return PyObject_TYPE(ob) == PyTupleType;
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyTuple_New(int size);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyTuple_GetItem(IntPtr pointer, int index);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyTuple_SetItem(IntPtr pointer, int index, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyTuple_GetSlice(IntPtr pointer, int start, int end);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyTuple_Size(IntPtr pointer);
@@ -1422,19 +1463,19 @@ internal static bool PyTuple_Check(IntPtr ob)
// Python iterator API
//====================================================================
-#if PYTHON2
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
- internal static extern bool PyIter_Check(IntPtr pointer);
-#elif PYTHON3
internal static bool PyIter_Check(IntPtr pointer)
{
- var ob_type = (IntPtr)Marshal.PtrToStructure(pointer + ObjectOffset.ob_type, typeof(IntPtr));
- IntPtr tp_iternext = ob_type + TypeOffset.tp_iternext;
- return tp_iternext != null && tp_iternext != _PyObject_NextNotImplemented;
- }
+ var ob_type = Marshal.ReadIntPtr(pointer, ObjectOffset.ob_type);
+#if PYTHON2
+ long tp_flags = Util.ReadCLong(ob_type, TypeOffset.tp_flags);
+ if ((tp_flags & TypeFlags.HaveIter) == 0)
+ return false;
#endif
+ IntPtr tp_iternext = Marshal.ReadIntPtr(ob_type, TypeOffset.tp_iternext);
+ return tp_iternext != IntPtr.Zero && tp_iternext != _PyObject_NextNotImplemented;
+ }
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyIter_Next(IntPtr pointer);
@@ -1442,47 +1483,47 @@ internal static bool PyIter_Check(IntPtr pointer)
// Python module API
//====================================================================
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyModule_New(string name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern string PyModule_GetName(IntPtr module);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyModule_GetDict(IntPtr module);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern string PyModule_GetFilename(IntPtr module);
#if PYTHON3
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyModule_Create2(IntPtr module, int apiver);
#endif
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyImport_Import(IntPtr name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyImport_ImportModule(string name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyImport_ReloadModule(IntPtr module);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyImport_AddModule(string name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyImport_GetModuleDict();
#if PYTHON3
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PySys_SetArgvEx(
int argc,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(StrArrayMarshaler))] string[] argv,
int updatepath
);
#elif PYTHON2
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PySys_SetArgvEx(
int argc,
string[] argv,
@@ -1490,10 +1531,10 @@ int updatepath
);
#endif
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PySys_GetObject(string name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PySys_SetObject(string name, IntPtr ob);
@@ -1506,10 +1547,10 @@ internal static bool PyType_Check(IntPtr ob)
return PyObject_TypeCheck(ob, PyTypeType);
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyType_Modified(IntPtr type);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern bool PyType_IsSubtype(IntPtr t1, IntPtr t2);
internal static bool PyObject_TypeCheck(IntPtr ob, IntPtr tp)
@@ -1518,37 +1559,37 @@ internal static bool PyObject_TypeCheck(IntPtr ob, IntPtr tp)
return (t == tp) || PyType_IsSubtype(t, tp);
}
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyType_GenericNew(IntPtr type, IntPtr args, IntPtr kw);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyType_GenericAlloc(IntPtr type, int n);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyType_Ready(IntPtr type);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr _PyType_Lookup(IntPtr type, IntPtr name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_GenericGetAttr(IntPtr obj, IntPtr name);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyObject_GenericSetAttr(IntPtr obj, IntPtr name, IntPtr value);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr _PyObject_GetDictPtr(IntPtr obj);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyObject_GC_New(IntPtr tp);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyObject_GC_Del(IntPtr tp);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyObject_GC_Track(IntPtr tp);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyObject_GC_UnTrack(IntPtr tp);
@@ -1556,13 +1597,13 @@ internal static bool PyObject_TypeCheck(IntPtr ob, IntPtr tp)
// Python memory API
//====================================================================
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyMem_Malloc(int size);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyMem_Realloc(IntPtr ptr, int size);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyMem_Free(IntPtr ptr);
@@ -1570,40 +1611,40 @@ internal static bool PyObject_TypeCheck(IntPtr ob, IntPtr tp)
// Python exception API
//====================================================================
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyErr_SetString(IntPtr ob, string message);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyErr_SetObject(IntPtr ob, IntPtr message);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyErr_SetFromErrno(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyErr_SetNone(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyErr_ExceptionMatches(IntPtr exception);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyErr_GivenExceptionMatches(IntPtr ob, IntPtr val);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyErr_NormalizeException(IntPtr ob, IntPtr val, IntPtr tb);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyErr_Occurred();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyErr_Fetch(ref IntPtr ob, ref IntPtr val, ref IntPtr tb);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyErr_Restore(IntPtr ob, IntPtr val, IntPtr tb);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyErr_Clear();
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyErr_Print();
@@ -1611,10 +1652,10 @@ internal static bool PyObject_TypeCheck(IntPtr ob, IntPtr tp)
// Miscellaneous
//====================================================================
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyMethod_Self(IntPtr ob);
- [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
+ [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyMethod_Function(IntPtr ob);
}
}
diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs
index 6f373f036..6570ee083 100644
--- a/src/runtime/typemanager.cs
+++ b/src/runtime/typemanager.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
@@ -86,7 +86,7 @@ internal static IntPtr CreateType(Type impl)
int flags = TypeFlags.Default | TypeFlags.Managed |
TypeFlags.HeapType | TypeFlags.HaveGC;
- Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
+ Util.WriteCLong(type, TypeOffset.tp_flags, flags);
Runtime.PyType_Ready(type);
@@ -160,7 +160,7 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType)
flags |= TypeFlags.HeapType;
flags |= TypeFlags.BaseType;
flags |= TypeFlags.HaveGC;
- Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
+ Util.WriteCLong(type, TypeOffset.tp_flags, flags);
// Leverage followup initialization from the Python runtime. Note
// that the type of the new type must PyType_Type at the time we
@@ -206,6 +206,7 @@ internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr
if (0 != Runtime.PyMapping_HasKey(py_dict, assemblyKey.Handle))
{
var pyAssembly = new PyObject(Runtime.PyDict_GetItem(py_dict, assemblyKey.Handle));
+ Runtime.XIncref(pyAssembly.Handle);
disposeList.Add(pyAssembly);
if (!Converter.ToManagedValue(pyAssembly.Handle, typeof(string), out assembly, false))
{
@@ -218,6 +219,7 @@ internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr
if (0 != Runtime.PyMapping_HasKey(py_dict, namespaceKey.Handle))
{
var pyNamespace = new PyObject(Runtime.PyDict_GetItem(py_dict, namespaceKey.Handle));
+ Runtime.XIncref(pyNamespace.Handle);
disposeList.Add(pyNamespace);
if (!Converter.ToManagedValue(pyNamespace.Handle, typeof(string), out namespaceStr, false))
{
@@ -321,7 +323,7 @@ internal static IntPtr CreateMetaType(Type impl)
flags |= TypeFlags.Managed;
flags |= TypeFlags.HeapType;
flags |= TypeFlags.HaveGC;
- Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
+ Util.WriteCLong(type, TypeOffset.tp_flags, flags);
// We need space for 3 PyMethodDef structs, each of them
// 4 int-ptrs in size.
@@ -378,7 +380,7 @@ internal static IntPtr BasicSubType(string name, IntPtr base_, Type impl)
flags |= TypeFlags.Managed;
flags |= TypeFlags.HeapType;
flags |= TypeFlags.HaveGC;
- Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
+ Util.WriteCLong(type, TypeOffset.tp_flags, flags);
CopySlot(base_, type, TypeOffset.tp_traverse);
CopySlot(base_, type, TypeOffset.tp_clear);
diff --git a/src/testing/Python.Test.15.csproj b/src/testing/Python.Test.15.csproj
new file mode 100644
index 000000000..a46cafb9d
--- /dev/null
+++ b/src/testing/Python.Test.15.csproj
@@ -0,0 +1,99 @@
+
+
+
+ net40;netstandard2.0
+ x64;x86
+ DebugMono;DebugMonoPY3;ReleaseMono;ReleaseMonoPY3;DebugWin;DebugWinPY3;ReleaseWin;ReleaseWinPY3
+ Python.Test
+ Python.Test
+ Python.Test
+ 2.4.0
+ bin\
+ false
+ $(OutputPath)\$(AssemblyName).xml
+ $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml
+ 1591,0067
+ ..\..\
+ $(SolutionDir)\bin\
+ $(PythonBuildDir)\$(TargetFramework)\
+ 6
+ false
+ ..\pythonnet.snk
+ prompt
+ $(PYTHONNET_DEFINE_CONSTANTS)
+ XPLAT
+ $(DefineConstants);$(CustomDefineConstants);$(BaseDefineConstants);
+ $(DefineConstants);TRACE;DEBUG
+ $(NuGetPackageRoot)\microsoft.targetingpack.netframework.v4.5\1.0.1\lib\net45\
+
+
+ x86
+
+
+ x64
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants)
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants)
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants)
+ true
+ pdbonly
+
+
+ true
+ $(DefineConstants);DEBUG;TRACE
+ full
+
+
+ $(DefineConstants)
+ true
+ pdbonly
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(TargetPath)
+ $(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
diff --git a/src/tests/test_clrmethod.py b/src/tests/test_clrmethod.py
new file mode 100644
index 000000000..a6078bece
--- /dev/null
+++ b/src/tests/test_clrmethod.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+
+"""Test clrmethod and clrproperty support for calling methods and getting/setting python properties from CLR."""
+
+import Python.Test as Test
+import System
+import pytest
+import clr
+
+class ExampleClrClass(System.Object):
+ __namespace__ = "PyTest"
+ def __init__(self):
+ self._x = 3
+ @clr.clrmethod(int, [int])
+ def test(self, x):
+ return x*2
+
+ def get_X(self):
+ return self._x
+ def set_X(self, value):
+ self._x = value
+ X = clr.clrproperty(int, get_X, set_X)
+
+ @clr.clrproperty(int)
+ def Y(self):
+ return self._x * 2
+
+def test_set_and_get_property_from_py():
+ """Test setting and getting clr-accessible properties from python."""
+ t = ExampleClrClass()
+ assert t.X == 3
+ assert t.Y == 3 * 2
+ t.X = 4
+ assert t.X == 4
+ assert t.Y == 4 * 2
+
+def test_set_and_get_property_from_clr():
+ """Test setting and getting clr-accessible properties from the clr."""
+ t = ExampleClrClass()
+ assert t.GetType().GetProperty("X").GetValue(t) == 3
+ assert t.GetType().GetProperty("Y").GetValue(t) == 3 * 2
+ t.GetType().GetProperty("X").SetValue(t, 4)
+ assert t.GetType().GetProperty("X").GetValue(t) == 4
+ assert t.GetType().GetProperty("Y").GetValue(t) == 4 * 2
+
+
+def test_set_and_get_property_from_clr_and_py():
+ """Test setting and getting clr-accessible properties alternatingly from the clr and from python."""
+ t = ExampleClrClass()
+ assert t.GetType().GetProperty("X").GetValue(t) == 3
+ assert t.GetType().GetProperty("Y").GetValue(t) == 3 * 2
+ assert t.X == 3
+ assert t.Y == 3 * 2
+ t.GetType().GetProperty("X").SetValue(t, 4)
+ assert t.GetType().GetProperty("X").GetValue(t) == 4
+ assert t.GetType().GetProperty("Y").GetValue(t) == 4 * 2
+ assert t.X == 4
+ assert t.Y == 4 * 2
+ t.X = 5
+ assert t.GetType().GetProperty("X").GetValue(t) == 5
+ assert t.GetType().GetProperty("Y").GetValue(t) == 5 * 2
+ assert t.X == 5
+ assert t.Y == 5 * 2
+
+def test_method_invocation_from_py():
+ """Test calling a clr-accessible method from python."""
+ t = ExampleClrClass()
+ assert t.test(41) == 41*2
+
+def test_method_invocation_from_clr():
+ """Test calling a clr-accessible method from the clr."""
+ t = ExampleClrClass()
+ assert t.GetType().GetMethod("test").Invoke(t, [37]) == 37*2
diff --git a/src/tests/test_conversion.py b/src/tests/test_conversion.py
index 9152e30d0..53e5d8051 100644
--- a/src/tests/test_conversion.py
+++ b/src/tests/test_conversion.py
@@ -466,17 +466,6 @@ def test_double_conversion():
with pytest.raises(TypeError):
ConversionTest().DoubleField = None
- with pytest.raises(OverflowError):
- ConversionTest().DoubleField = 1.7976931348623159e308
-
- with pytest.raises(OverflowError):
- ConversionTest().DoubleField = -1.7976931348623159e308
-
- with pytest.raises(OverflowError):
- _ = System.Double(1.7976931348623159e308)
-
- with pytest.raises(OverflowError):
- _ = System.Double(-1.7976931348623159e308)
def test_decimal_conversion():
diff --git a/src/tests/test_subclass.py b/src/tests/test_subclass.py
index 8e862a56d..43d013c7c 100644
--- a/src/tests/test_subclass.py
+++ b/src/tests/test_subclass.py
@@ -15,12 +15,12 @@
from ._compat import range
-def interface_test_class_fixture():
+def interface_test_class_fixture(subnamespace):
"""Delay creation of class until test starts."""
class InterfaceTestClass(IInterfaceTest):
"""class that implements the test interface"""
- __namespace__ = "Python.Test"
+ __namespace__ = "Python.Test." + subnamespace
def foo(self):
return "InterfaceTestClass"
@@ -31,12 +31,12 @@ def bar(self, x, i):
return InterfaceTestClass
-def derived_class_fixture():
+def derived_class_fixture(subnamespace):
"""Delay creation of class until test starts."""
class DerivedClass(SubClassTest):
"""class that derives from a class deriving from IInterfaceTest"""
- __namespace__ = "Python.Test"
+ __namespace__ = "Python.Test." + subnamespace
def foo(self):
return "DerivedClass"
@@ -60,12 +60,12 @@ def return_list(self):
return DerivedClass
-def derived_event_test_class_fixture():
+def derived_event_test_class_fixture(subnamespace):
"""Delay creation of class until test starts."""
class DerivedEventTest(IInterfaceTest):
"""class that implements IInterfaceTest.TestEvent"""
- __namespace__ = "Python.Test"
+ __namespace__ = "Python.Test." + subnamespace
def __init__(self):
self.event_handlers = []
@@ -85,7 +85,6 @@ def OnTestEvent(self, value):
return DerivedEventTest
-@pytest.mark.skip(reason="FIXME: test randomly pass/fails")
def test_base_class():
"""Test base class managed type"""
ob = SubClassTest()
@@ -98,10 +97,9 @@ def test_base_class():
assert list(SubClassTest.test_list(ob)) == ["a", "b", "c"]
-@pytest.mark.skip(reason="FIXME: test randomly pass/fails")
def test_interface():
"""Test python classes can derive from C# interfaces"""
- InterfaceTestClass = interface_test_class_fixture()
+ InterfaceTestClass = interface_test_class_fixture(test_interface.__name__)
ob = InterfaceTestClass()
assert ob.foo() == "InterfaceTestClass"
assert FunctionsTest.test_foo(ob) == "InterfaceTestClass"
@@ -112,10 +110,9 @@ def test_interface():
assert id(x) == id(ob)
-@pytest.mark.skip(reason="FIXME: test randomly pass/fails")
def test_derived_class():
"""Test python class derived from managed type"""
- DerivedClass = derived_class_fixture()
+ DerivedClass = derived_class_fixture(test_derived_class.__name__)
ob = DerivedClass()
assert ob.foo() == "DerivedClass"
assert ob.base_foo() == "foo"
@@ -131,10 +128,9 @@ def test_derived_class():
assert id(x) == id(ob)
-@pytest.mark.skip(reason="FIXME: test randomly pass/fails")
def test_create_instance():
"""Test derived instances can be created from managed code"""
- DerivedClass = derived_class_fixture()
+ DerivedClass = derived_class_fixture(test_create_instance.__name__)
ob = FunctionsTest.create_instance(DerivedClass)
assert ob.foo() == "DerivedClass"
assert FunctionsTest.test_foo(ob) == "DerivedClass"
@@ -145,7 +141,7 @@ def test_create_instance():
x = FunctionsTest.pass_through(ob)
assert id(x) == id(ob)
- InterfaceTestClass = interface_test_class_fixture()
+ InterfaceTestClass = interface_test_class_fixture(test_create_instance.__name__)
ob2 = FunctionsTest.create_instance(InterfaceTestClass)
assert ob2.foo() == "InterfaceTestClass"
assert FunctionsTest.test_foo(ob2) == "InterfaceTestClass"
@@ -156,7 +152,6 @@ def test_create_instance():
assert id(y) == id(ob2)
-@pytest.mark.skip(reason="FIXME: test randomly pass/fails")
def test_events():
class EventHandler(object):
def handler(self, x, args):
@@ -169,12 +164,12 @@ def handler(self, x, args):
assert FunctionsTest.test_event(x, 1) == 1
assert event_handler.value == 1
- InterfaceTestClass = interface_test_class_fixture()
+ InterfaceTestClass = interface_test_class_fixture(test_events.__name__)
i = InterfaceTestClass()
with pytest.raises(System.NotImplementedException):
FunctionsTest.test_event(i, 2)
- DerivedEventTest = derived_event_test_class_fixture()
+ DerivedEventTest = derived_event_test_class_fixture(test_events.__name__)
d = DerivedEventTest()
d.add_TestEvent(event_handler.handler)
assert FunctionsTest.test_event(d, 3) == 3
@@ -193,3 +188,59 @@ def test_isinstance_check():
for x in b:
assert isinstance(x, System.Object)
assert isinstance(x, System.String)
+
+def test_namespace_and_init():
+ calls = []
+ class TestX(System.Object):
+ __namespace__ = "test_clr_subclass_with_init_args"
+ def __init__(self, *args, **kwargs):
+ calls.append((args, kwargs))
+ t = TestX(1,2,3,foo="bar")
+ assert len(calls) == 1
+ assert calls[0][0] == (1,2,3)
+ assert calls[0][1] == {"foo":"bar"}
+
+def test_namespace_and_argless_init():
+ calls = []
+ class TestX(System.Object):
+ __namespace__ = "test_clr_subclass_without_init_args"
+ def __init__(self):
+ calls.append(True)
+ t = TestX()
+ assert len(calls) == 1
+ assert calls[0] == True
+
+
+def test_namespace_and_no_init():
+ class TestX(System.Object):
+ __namespace__ = "test_clr_subclass_without_init"
+ q = 1
+ t = TestX()
+ assert t.q == 1
+
+def test_construction_from_clr():
+ import clr
+ calls = []
+ class TestX(System.Object):
+ __namespace__ = "test_clr_subclass_init_from_clr"
+ @clr.clrmethod(None, [int, str])
+ def __init__(self, i, s):
+ calls.append((i, s))
+
+ # Construct a TestX from Python
+ t = TestX(1, "foo")
+ assert len(calls) == 1
+ assert calls[0][0] == 1
+ assert calls[0][1] == "foo"
+
+ # Reset calls and construct a TestX from CLR
+ calls = []
+ tp = t.GetType()
+ t2 = tp.GetConstructors()[0].Invoke(None)
+ assert len(calls) == 0
+
+ # The object has only been constructed, now it needs to be initialized as well
+ tp.GetMethod("__init__").Invoke(t2, [1, "foo"])
+ assert len(calls) == 1
+ assert calls[0][0] == 1
+ assert calls[0][1] == "foo"