8000 Merge remote-tracking branch 'remotes/upstream/master' into soft-shut… · pythonnet/pythonnet@5387b05 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5387b05

Browse files
committed
Merge remote-tracking branch 'remotes/upstream/master' into soft-shutdown
2 parents 2b7bcac + 61d1b7c commit 5387b05

36 files changed

+938
-393
lines changed

AUTHORS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
- Alexandre Catarino([@AlexCatarino](https://github.com/AlexCatarino))
2121
- Andrey Sant'Anna ([@andreydani](https://github.com/andreydani))
2222
- Arvid JB ([@ArvidJB](https://github.com/ArvidJB))
23+
- Avinash Maddikonda ([@SFM61319](https://github.com/SFM61319))
2324
- Benoît Hudson ([@benoithudson](https://github.com/benoithudson))
2425
- Bradley Friedman ([@leith-bartrich](https://github.com/leith-bartrich))
2526
- Callum Noble ([@callumnoble](https://github.com/callumnoble))
@@ -73,7 +74,7 @@
7374
- ([@OneBlue](https://github.com/OneBlue))
7475
- ([@rico-chet](https://github.com/rico-chet))
7576
- ([@rmadsen-ks](https://github.com/rmadsen-ks))
77+
- ([@SnGmng](https://github.com/SnGmng))
7678
- ([@stonebig](https://github.com/stonebig))
7779
- ([@testrunner123](https://github.com/testrunner123))
7880
- ([@DanBarzilian](https://github.com/DanBarzilian))
79-

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
1111

1212
### F438 Changed
1313
- Drop support for Python 2
14+
- `clr.AddReference` may now throw errors besides `FileNotFoundException`, that provide more
15+
details about the cause of the failure
16+
- `clr.AddReference` no longer adds ".dll" implicitly
1417

1518
### Fixed
1619

@@ -35,6 +38,7 @@ This version improves performance on benchmarks significantly compared to 2.3.
3538
- Support for Python 3.8
3639
- Codecs as the designated way to handle automatic conversions between
3740
.NET and Python types
41+
- Added Python 3 buffer api support and PyBuffer interface for fast byte and numpy array read/write ([#980][p980])
3842

3943
### Changed
4044

README.rst

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ provides a powerful application scripting tool for .NET developers. It
1414
allows Python code to interact with the CLR, and may also be used to
1515
embed Python into a .NET application.
1616

17+
.. note::
18+
The master branch of this repository tracks the ongoing development of version 3.0.
19+
Backports of patches to 2.5 are tracked in the
20+
`backports-2.5 branch <https://github.com/pythonnet/pythonnet/tree/backports-2.5>`_.
21+
1722
Calling .NET code from Python
1823
-----------------------------
1924

2025
Python.NET allows CLR namespaces to be treated essentially as Python packages.
2126

22-
.. code-block::
27+
.. code-block:: python
2328
2429
import clr
2530
from System import String
@@ -28,7 +33,7 @@ Python.NET allows CLR namespaces to be treated essentially as Python packages.
2833
To load an assembly, use the ``AddReference`` function in the ``clr``
2934
module:
3035

31-
.. code-block::
36+
.. code-block:: python
3237
3338
import clr
3439
clr.AddReference("System.Windows.Forms")
@@ -80,7 +85,7 @@ Example
8085
8186
Output:
8287

83-
.. code::
88+
.. code:: csharp
8489
8590
1.0
8691
-0.958924274663

appveyor.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ init:
4242
install:
4343
- python -m pip install -U pip
4444
- pip install --upgrade -r requirements.txt --quiet
45+
- pip install pycparser --quiet
4546

4647
# Install OpenCover. Can't put on `packages.config`, not Mono compatible
4748
- .\tools\nuget\nuget.exe install OpenCover -OutputDirectory packages -Verbosity quiet
@@ -53,7 +54,7 @@ build_script:
5354
- coverage run setup.py bdist_wheel %BUILD_OPTS%
5455

5556
test_script:
56-
- pip install --find-links=.\dist\ pythonnet
57+
- pip install --no-index --find-links=.\dist\ pythonnet
5758
- ps: .\ci\appveyor_run_tests.ps1
5859

5960
on_finish:

src/embed_tests/Python.EmbeddingTest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
<Compile Include="TestFinalizer.cs" />
9898
<Compile Include="TestInstanceWrapping.cs" />
9999
<Compile Include="TestPyAnsiString.cs" />
100+
<Compile Include="TestPyBuffer.cs" />
100101
<Compile Include="Tes EED3 tPyFloat.cs" />
101102
<Compile Include="TestPyInt.cs" />
102103
<Compile Include="TestPyList.cs" />

src/embed_tests/TestConverter.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
4+
35
using NUnit.Framework;
6+
47
using Python.Runtime;
58

9+
using PyRuntime = Python.Runtime.Runtime;
10+
611
namespace Python.EmbeddingTest
712
{
813
public class TestConverter
914
{
15+
static readonly Type[] _numTypes = new Type[]
16+
{
17+
typeof(short),
18+
typeof(ushort),
19+
typeof(int),
20+
typeof(uint),
21+
typeof(long),
22+
typeof(ulong)
23+
};
24+
1025
[OneTimeSetUp]
1126
public void SetUp()
1227
{
@@ -47,6 +62,60 @@ public void TestConvertDoubleToManaged(
4762
Assert.IsTrue(((double) convertedValue).Equals(testValue));
4863
}
4964

65+
[Test]
66+
public void CovertTypeError()
67+
{
68+
Type[] floatTypes = new Type[]
69+
{
70+
typeof(float),
71+
typeof(double)
72+
};
73+
using (var s = new PyString("abc"))
74+
{
75+
foreach (var type in _numTypes.Union(floatTypes))
76+
{
77+
object value;
78+
try
79+
{
80+
bool res = Converter.ToManaged(s.Handle, type, out value, true);
81+
Assert.IsFalse(res);
82+
var bo = Exceptions.ExceptionMatches(Exceptions.TypeError);
83+
Assert.IsTrue(Exceptions.ExceptionMatches(Exceptions.TypeError)
84+
|| Exceptions.ExceptionMatches(Exceptions.ValueError));
85+
}
86+
finally
87+
{
88+
Exceptions.Clear();
89+
}
90+
}
91+
}
92+
}
93+
94+
[Test]
95+
public void ConvertOverflow()
96+
{
97+
using (var num = new PyLong(ulong.MaxValue))
98+
{
99+
IntPtr largeNum = PyRuntime.PyNumber_Add(num.Handle, num.Handle);
100+
try
101+
{
102+
object value;
103+
foreach (var type in _numTypes)
104+
{
105+
bool res = Converter.ToManaged(largeNum, type, out value, true);
106+
Assert.IsFalse(res);
107+
Assert.IsTrue(Exceptions.ExceptionMatches(Exceptions.OverflowError));
108+
Exceptions.Clear();
109+
}
110+
}
111+
finally
112+
{
113+
Exceptions.Clear();
114+
PyRuntime.XDecref(largeNum);
115+
}
116+
}
117+
}
118+
50119
[Test]
51120
public void RawListProxy()
52121
{

src/embed_tests/TestPyBuffer.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System.Text;
2+
using NUnit.Framework;
3+
using Python.Runtime;
4+
5+
namespace Python.EmbeddingTest {
6+
class TestPyBuffer
7+
{
8+
[OneTimeSetUp]
9+
public void SetUp()
10+
{
11+
PythonEngine.Initialize();
12+
}
13+
14+
[OneTimeTearDown]
15+
public void Dispose()
16+
{
17+
PythonEngine.Shutdown();
18+
}
19+
20+
[Test]
21+
public void TestBufferWrite()
22+
{
23+
string bufferTestString = "hello world! !$%&/()=?";
24+
25+
using (Py.GIL())
26+
{
27+
using (var scope = Py.CreateScope())
28+
{
29+
scope.Exec($"arr = bytearray({bufferTestString.Length})");
30+
PyObject pythonArray = scope.Get("arr");
31+
byte[] managedArray = new UTF8Encoding().GetBytes(bufferTestString);
32+
33+
using (PyBuffer buf = pythonArray.GetBuffer())
34+
{
35+
buf.Write(managedArray, 0, managedArray.Length);
36+
}
37+
38+
string result = scope.Eval("arr.decode('utf-8')").ToString();
39+
Assert.IsTrue(result == bufferTestString);
40+
}
41+
}
42+
}
43+
44+
[Test]
45+
public void TestBufferRead()
46+
{
47+
string bufferTestString = "hello world! !$%&/()=?";
48+
49+
using (Py.GIL())
50+
{
51+
using (var scope = Py.CreateScope())
52+
{
53+
scope.Exec($"arr = b'{bufferTestString}'");
54+
PyObject pythonArray = scope.Get("arr");
55+
byte[] managedArray = new byte[bufferTestString.Length];
56+
57+
using (PyBuffer buf = pythonArray.GetBuffer())
58+
{
59+
buf.Read(managedArray, 0, managedArray.Length);
60+
}
61+
62+
string result = new UTF8Encoding().GetString(managedArray);
63+
Assert.IsTrue(result == bufferTestString);
64+
}
65+
}
66+
}
67+
}
68+
}

src/embed_tests/pyimport.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ public void SetUp()
3838
string testPath = Path.Combine(TestContext.CurrentContext.TestDirectory, s);
3939

4040
IntPtr str = Runtime.Runtime.PyString_FromString(testPath);
41-
IntPtr path = Runtime.Runtime.PySys_GetObject("path");
42-
Runtime.Runtime.PyList_Append(new BorrowedReference(path), str);
41+
BorrowedReference path = Runtime.Runtime.PySys_GetObject("path");
42+
Runtime.Runtime.PyList_Append(path, str);
4343
Runtime.Runtime.XDecref(str);
4444
}
4545

@@ -84,5 +84,28 @@ public void TestCastGlobalVar()
8484
Assert.AreEqual("2", foo.FOO.ToString());
8585
Assert.AreEqual("2", foo.test_foo().ToString());
8686
}
87+
88+
[Test]
89+
public void BadAssembly()
90+
{
91+
string path;
92+
if (Python.Runtime.Runtime.IsWindows)
93+
{
94+
path = @"C:\Windows\System32\kernel32.dll";
95+
}
96+
else
97+
{
98+
Assert.Pass("TODO: add bad assembly location for other platforms");
99+
return;
100+
}
101+
102+
string code = $@"
103+
import clr
104+
clr.AddReference('{path}')
105+
";
106+
107+
var error = Assert.Throws<PythonException>(() => PythonEngine.Exec(code));
108+
Assert.AreEqual(nameof(FileLoadException), error.PythonTypeName);
109+
}
87110
}
88111
}

src/runtime/BorrowedReference.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ readonly ref struct BorrowedReference
1111
public bool IsNull => this.pointer == IntPtr.Zero;
1212

1313
/// <summary>Gets a raw pointer to the Python object</summary>
14-
public IntPtr DangerousGetAddress()
15-
=> this.IsNull ? throw new NullReferenceException() : this.pointer;
14+
public IntPtr DangerousGetAddress() => this.pointer;
1615

1716
/// <summary>
1817
/// Creates new instance of <see cref="BorrowedReference"/> from raw pointer. Unsafe.

src/runtime/NewReference.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@ public PyObject MoveToPyObject()
2727
this.pointer = IntPtr.Zero;
2828
return result;
2929
}
30+
3031
/// <summary>
3132
/// Removes this reference to a Python object, and sets it to <c>null</c>.
3233
/// </summary>
3334
public void Dispose()
3435
{
35-
if (!this.IsNull())
36-
Runtime.XDecref(this.pointer);
37-
this.pointer = IntPtr.Zero;
36+
if (this.IsNull())
37+
{
38+
return;
39+
}
40+
Runtime.XDecref(pointer);
41+
pointer = IntPtr.Zero;
3842
}
3943

4044
/// <summary>

src/runtime/Python.Runtime.15.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
<DefineConstants Condition="'$(CustomDefineConstants)' == ''">$(DefineConstants);PYTHON2;$(Python2Version);$(PythonWinDefineConstants);FINALIZER_CHECK;TRACE;DEBUG</DefineConstants>
9191
</PropertyGroup>
9292
<PropertyGroup Condition=" '$(Configuration)' == 'DebugWinPY3'">
93-
<DefineConstants Condition="'$(CustomDefineConstants)' == ''">$(DefineConstants);PYTHON3;$(Python3Version);$(PythonWinDefineConstants);FINALIZER_CHECK;TRACE;DEBUG</DefineConstants>
93+
<DefineConstants Condition="'$(CustomDefineConstants)' == ''">TRACE;DEBUG;XPLAT;;PYTHON3;PYTHON38;UCS2;FINALIZER_CHECK;WINDOWS</DefineConstants>
9494
</PropertyGroup>
9595

9696
<ItemGroup Condition=" '$(PythonInteropFile)' != '' ">

src/runtime/Python.Runtime.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
<Compile Include="arrayobject.cs" />
9090
<Compile Include="assemblymanager.cs" />
9191
<Compile Include="BorrowedReference.cs" />
92+
<Compile Include="bufferinterface.cs" />
9293
<Compile Include="classderived.cs" />
9394
<Compile Include="classbase.cs" />
9495
<Compile Include="classmanager.cs" />
@@ -130,6 +131,7 @@
130131
<Compile Include="overload.cs" />
131132
<Compile Include="propertyobject.cs" />
132133
<Compile Include="pyansistring.cs" />
134+
<Compile Include="pybuffer.cs" />
133135
<Compile Include="pydict.cs" />
134136
<Compile Include="PyExportAttribute.cs" />
135137
<Compile Include="pyfloat.cs" />

0 commit comments

Comments
 (0)
0