forked from pythonnet/pythonnet
-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathPyIter.cs
More file actions
112 lines (96 loc) · 3.52 KB
/
PyIter.cs
File metadata and controls
112 lines (96 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Python.Runtime
{
/// <summary>
/// Represents a standard Python iterator object. See the documentation at
/// PY2: https://docs.python.org/2/c-api/iterator.html
/// PY3: https://docs.python.org/3/c-api/iterator.html
/// for details.
/// </summary>
public class PyIter : PyObject, IEnumerator<PyObject>
{
private PyObject? _current;
/// <summary>
/// PyIter Constructor
/// </summary>
/// <remarks>
/// Creates a new PyIter from an existing iterator reference. Note
/// that the instance assumes ownership of the object reference.
/// The object reference is not checked for type-correctness.
/// </remarks>
internal PyIter(in StolenReference reference) : base(reference)
{
}
/// <summary>
/// Creates new <see cref="PyIter"/> from an untyped reference to Python object.
/// The object must support iterator protocol.
/// </summary>
public PyIter(PyObject pyObject) : base(FromPyObject(pyObject)) { }
static BorrowedReference FromPyObject(PyObject pyObject) {
if (pyObject is null) throw new ArgumentNullException(nameof(pyObject));
if (!Runtime.PyIter_Check(pyObject.Reference))
throw new ArgumentException("Object does not support iterator protocol");
return pyObject.Reference;
}
internal PyIter(BorrowedReference reference) : base(reference) { }
/// <summary>
/// Create a new <see cref="PyIter"/> from a given iterable.
///
/// Like doing "iter(<paramref name="iterable"/>)" in Python.
/// </summary>
public static PyIter GetIter(PyObject iterable)
{
if (iterable == null)
{
throw new ArgumentNullException();
}
var val = Runtime.PyObject_GetIter(iterable.Reference);
PythonException.ThrowIfIsNull(val);
return new PyIter(val.Steal());
}
protected override void Dispose(bool disposing)
{
_current = null;
base.Dispose(disposing);
}
public bool MoveNext()
{
NewReference next = Runtime.PyIter_Next(Reference);
if (next.IsNull())
{
if (Exceptions.ErrorOccurred())
{
throw PythonException.ThrowLastAsClrException();
}
// stop holding the previous object, if there was one
_current = null;
return false;
}
_current = next.MoveToPyObject();
return true;
}
public void Reset()
{
throw new NotSupportedException();
}
public PyObject Current => _current ?? throw new InvalidOperationException();
object System.Collections.IEnumerator.Current => Current;
protected PyIter(SerializationInfo info, StreamingContext context)
: base(info, context)
{
_current = (PyObject?)info.GetValue("c", typeof(PyObject));
}
protected override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("c"
3539
;, _current);
}
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
}
}