8000 respond to comments · pythonnet/pythonnet@fd0aaa9 · GitHub
[go: up one dir, main page]

Skip to content

Commit fd0aaa9

Browse files
committed
respond to comments
1 parent 0e37fbc commit fd0aaa9

File tree

3 files changed

+48
-15
lines changed

3 files changed

+48
-15
lines changed

src/runtime/CollectionWrappers/IterableWrapper.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,47 @@ namespace Python.Runtime.CollectionWrappers
66
{
77
internal class IterableWrapper<T> : IEnumerable<T>
88
{
9-
protected PyObject pyObject;
9+
protected readonly PyObject pyObject;
1010

1111
public IterableWrapper(PyObject pyObj)
1212
{
13+
if (pyObj == null)
14+
throw new PythonException();
1315
pyObject = pyObj;
1416
}
1517

1618
private void propagateIterationException()
1719
{
1820
var err = Runtime.PyErr_Occurred();
19-
if (err != null && err != Exceptions.StopIteration)
21+
if (err == null) return;
22+
23+
//remove StopIteration exceptions
24+
if (0 != Runtime.PyErr_ExceptionMatches(Exceptions.StopIteration))
2025
{
21-
Runtime.CheckExceptionOccurred();
26+
Runtime.PyErr_Clear();
27+
return;
2228
}
29+
30+
Runtime.CheckExceptionOccurred();
2331
}
2432

2533
IEnumerator IEnumerable.GetEnumerator()
2634
{
27-
if (pyObject == null) yield break;
28-
PyObject iterObject = new PyObject(Runtime.PyObject_GetIter(pyObject.Handle));
29-
IntPtr item;
35+
PyObject iterObject = null;
36+
using (Py.GIL())
37+
{
38+
iterObject = new PyObject(Runtime.PyObject_GetIter(pyObject.Handle));
39+
}
3040

31-
while ((item = Runtime.PyIter_Next(iterObject.Handle)) != IntPtr.Zero)
41+
while (true)
3242
{
43+
IntPtr item = IntPtr.Zero;
44+
using (Py.GIL())
45+
{
46+
item = Runtime.PyIter_Next(iterObject.Handle);
47+
}
48+
if (item == IntPtr.Zero) break;
49+
3350
object obj = null;
3451
if (!Converter.ToManaged(item, typeof(object), out obj, true))
3552
{
@@ -46,7 +63,6 @@ IEnumerator IEnumerable.GetEnumerator()
4663

4764
public IEnumerator<T> GetEnumerator()
4865
{
49-
if (pyObject == null) yield break;
5066
PyObject iterObject = null;
5167
using (Py.GIL())
5268
{

src/runtime/CollectionWrappers/ListWrapper.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@ public T this[int index]
2626
{
2727
IntPtr pyItem = Converter.ToPython(value, typeof(T));
2828
if (pyItem == IntPtr.Zero)
29-
throw new Exception("failed to set item");
29+
{
30+
throw new InvalidCastException(
31+
"cannot cast " + value.ToString() + "to type: " + typeof(T).ToString(),
32+
new PythonException());
33+
}
3034

3135
var result = Runtime.PyList_SetItem(pyObject.Handle, index, pyItem);
32-
Runtime.XDecref(pyItem);
3336
if (result == -1)
3437
Runtime.CheckExceptionOccurred();
3538
}
@@ -47,7 +50,7 @@ public void Insert(int index, T item)
4750

4851
IntPtr pyItem = Converter.ToPython(item, typeof(T));
4952
if (pyItem == IntPtr.Zero)
50-
throw new Exception("failed to insert item");
53+
throw new PythonException();
5154

5255
var result = Runtime.PyList_Insert(pyObject.Reference, index, pyItem);
5356
Runtime.XDecref(pyItem);
@@ -57,7 +60,12 @@ public void Insert(int index, T item)
5760

5861
public void RemoveAt(int index)
5962
{
60-
removeAt(index);
63+
var result = removeAt(index);
64+
65+
//PySequence_DelItem will set an error if it fails. throw it here
66+
//since RemoveAt does not have a bool return value.
67+
if (result == false)
68+
Runtime.CheckExceptionOccurred();
6169
}
6270
}
6371
}

src/runtime/CollectionWrappers/SequenceWrapper.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,11 @@ private T getItem(int index)
7272

7373
public void CopyTo(T[] array, int arrayIndex)
7474
{
75-
for (int index = 0; index < Count; index++)
75+
var index = 0;
76+
foreach (var item in this)
7677
{
77-
array[index + arrayIndex] = getItem(index);
78+
array[index + arrayIndex] = item;
79+
index++;
7880
}
7981
}
8082

@@ -102,7 +104,14 @@ protected int indexOf(T item)
102104

103105
public bool Remove(T item)
104106
{
105-
return removeAt(indexOf(item));
107+
var result = removeAt(indexOf(item));
108+
109+
//clear the python exception from PySequence_DelItem
110+
//it is idiomatic in C# to return a bool rather than
111+
//throw for a failed Remove in ICollection
112+
if (result == false)
113+
Runtime.PyErr_Clear();
114+
return result;
106115
}
107116
}
108117
}

0 commit comments

Comments
 (0)
0