Skip to content

Commit 4dd91c1

Browse files
committed
Add more checks and tests
1 parent 48bb33a commit 4dd91c1

2 files changed

Lines changed: 57 additions & 5 deletions

File tree

‎src/embed_tests/TestPyBuffer.cs‎

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
using System.Runtime.CompilerServices;
33
using System.Text;
44
using System.Threading;
5+
56
using NUnit.Framework;
7+
68
using Python.Runtime;
79
using Python.Runtime.Codecs;
810

9-
namespace Python.EmbeddingTest {
11+
namespace Python.EmbeddingTest
12+
{
1013
class TestPyBuffer
1114
{
1215
[OneTimeSetUp]
@@ -70,16 +73,38 @@ public void GetPointer()
7073

7174
using PyBuffer buf = ndArray.GetBuffer(PyBUF.STRIDES);
7275

73-
// this throws System.ExecutionEngineException
7476
var ptr = buf.GetPointer([0, 0, 0]);
7577

7678
Assert.That(ptr, Is.Not.EqualTo(IntPtr.Zero));
79+
80+
var ptrEnd = buf.GetPointer([9, 9, 9]);
81+
Assert.That(ptrEnd, Is.Not.EqualTo(IntPtr.Zero));
82+
Assert.That(ptrEnd, Is.Not.EqualTo(ptr));
83+
84+
Assert.Throws<ArgumentNullException>(() => buf.GetPointer(null!));
85+
86+
Assert.Throws<ArgumentOutOfRangeException>(() => buf.GetPointer([0, 0]));
87+
Assert.Throws<ArgumentOutOfRangeException>(() => buf.GetPointer([0, 0, 0, 0]));
88+
89+
Assert.Throws<ArgumentOutOfRangeException>(() => buf.GetPointer([-1, 0, 0]));
90+
Assert.Throws<ArgumentOutOfRangeException>(() => buf.GetPointer([0, -1, 0]));
91+
Assert.Throws<ArgumentOutOfRangeException>(() => buf.GetPointer([0, 0, -1]));
92+
93+
Assert.Throws<ArgumentOutOfRangeException>(() => buf.GetPointer([10, 0, 0]));
94+
Assert.Throws<ArgumentOutOfRangeException>(() => buf.GetPointer([0, 10, 0]));
95+
Assert.Throws<ArgumentOutOfRangeException>(() => buf.GetPointer([0, 0, 10]));
96+
97+
using PyBuffer buf2 = ndArray.GetBuffer(PyBUF.ND);
98+
99+
Assert.Throws<InvalidOperationException>(
100+
() => buf2.GetPointer([0, 0, 0])
101+
);
77102
}
78103

79104
[Test]
80105
public void ArrayHasBuffer()
81106
{
82-
var array = new[,] {{1, 2}, {3,4}};
107+
var array = new[,] { { 1, 2 }, { 3, 4 } };
83108
var memoryView = PythonEngine.Eval("memoryview");
84109
var mem = memoryView.Invoke(array.ToPython());
85110
Assert.That(mem[(0, 0).ToPython()].As<int>(), Is.EqualTo(1));
@@ -128,7 +153,7 @@ public void Finalization()
128153
[Test]
129154
public void MultidimensionalNumPyArray()
130155
{
131-
var ndarray = np.arange(24).reshape(1,2,3,4).T;
156+
var ndarray = np.arange(24).reshape(1, 2, 3, 4).T;
132157
PyObject ndim = ndarray.ndim;
133158
PyObject shape = ndarray.shape;
134159
PyObject strides = ndarray.strides;

‎src/runtime/PythonTypes/PyBuffer.cs‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,37 @@ public bool IsContiguous(BufferOrderStyle order)
110110
/// </summary>
111111
public IntPtr GetPointer(long[] indices)
112112
{
113-
if (indices is null) throw new ArgumentNullException(nameof(indices));
113+
if (indices is null)
114+
throw new ArgumentNullException(nameof(indices));
115+
116+
if (Strides is null)
117+
throw new InvalidOperationException($"{nameof(GetPointer)} requires {nameof(Strides)} to be filled");
118+
119+
if (indices.Length != Dimensions)
120+
throw new ArgumentOutOfRangeException($"{nameof(indices)} must be exactly {Dimensions} long");
121+
122+
if (Dimensions == 0 && Shape is null)
123+
throw new InvalidOperationException($"{nameof(GetPointer)} requires {nameof(Shape)} to be filled for dimensional buffers");
124+
114125
ThrowIfDisposed();
126+
115127
if (Runtime.PyVersion < new Version(3, 7))
116128
throw new NotSupportedException("GetPointer requires at least Python 3.7");
129+
130+
var indicesArr = new nint[Dimensions];
131+
132+
for (var i = 0; i < Dimensions; i++)
133+
{
134+
indicesArr[i] = checked((nint)indices[i]);
135+
136+
if (indicesArr[i] < 0 || indicesArr[i] >= Shape![i])
137+
{
138+
throw new ArgumentOutOfRangeException(
139+
$"Index {i} has a value of {indicesArr[i]} not in [0, {Shape![i]})"
140+
);
141+
}
142+
}
143+
117144
return Runtime.PyBuffer_GetPointer(ref _view, indices.Select(x => checked((nint)x)).ToArray());
118145
}
119146

0 commit comments

Comments
 (0)