forked from pythonnet/pythonnet
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPyTuple.cs
More file actions
123 lines (107 loc) · 4.08 KB
/
PyTuple.cs
File metadata and controls
123 lines (107 loc) · 4.08 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
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Linq;
using System.Runtime.Serialization;
namespace Python.Runtime
{
/// <summary>
/// Represents a Python tuple object. See the documentation at
/// PY2: https://docs.python.org/2/c-api/tupleObjects.html
/// PY3: https://docs.python.org/3/c-api/tupleObjects.html
/// for details.
/// </summary>
public class PyTuple : PySequence
{
internal PyTuple(in StolenReference reference) : base(reference) { }
/// <summary>
/// PyTuple Constructor
/// </summary>
/// <remarks>
/// Creates a new PyTuple from an existing object reference.
/// The object reference is not checked for type-correctness.
/// </remarks>
internal PyTuple(BorrowedReference reference) : base(reference) { }
protected PyTuple(SerializationInfo info, StreamingContext context) : base(info, context) { }
private static BorrowedReference FromObject(PyObject o)
{
if (o is null) throw new ArgumentNullException(nameof(o));
if (!IsTupleType(o))
{
throw new ArgumentException("object is not a tuple");
}
return o.Reference;
}
/// <summary>
/// PyTuple Constructor
/// </summary>
/// <remarks>
/// Copy constructor - obtain a PyTuple from a generic PyObject. An
/// ArgumentException will be thrown if the given object is not a
/// Python tuple object.
/// </remarks>
public PyTuple(PyObject o) : base(FromObject(o))
{
}
/// <summary>
/// PyTuple Constructor
/// </summary>
/// <remarks>
/// Creates a new empty PyTuple.
/// </remarks>
public PyTuple() : base(NewEmtpy()) { }
private static StolenReference NewEmtpy()
{
var ptr = Runtime.PyTuple_New(0);
return ptr.StealOrThrow();
}
private static StolenReference FromArray(PyObject[] items)
{
if (items is null) throw new ArgumentNullException(nameof(items));
if (items.Any(item => item is null))
throw new ArgumentException(message: Util.UseNone, paramName: nameof(items));
int count = items.Length;
using var val = Runtime.PyTuple_New(count);
for (var i = 0; i < count; i++)
{
int res = Runtime.PyTuple_SetItem(val.Borrow(), i, items[i]);
if (res != 0)
{
val.Dispose();
throw PythonException.ThrowLastAsClrException();
}
}
return val.Steal();
}
/// <summary>
/// PyTuple Constructor
/// </summary>
/// <remarks>
/// Creates a new PyTuple from an array of PyObject instances.
/// <para />
/// See caveats about PyTuple_SetItem:
/// https://www.coursehero.com/file/p4j2ogg/important-exceptions-to-this-rule-PyTupleSetItem-and-PyListSetItem-These/
/// </remarks>
public PyTuple(PyObject[] items) : base(FromArray(items))
{
}
/// <summary>
/// Returns <c>true</c> if the given object is a Python tuple.
/// </summary>
public static bool IsTupleType(PyObject value)
{
if (value is null) throw new ArgumentNullException(nameof(value));
return Runtime.PyTuple_Check(value.obj);
}
/// <summary>
/// Convert a Python object to a Python tuple if possible. This is
/// equivalent to the Python expression "tuple(<paramref name="value"/>)".
/// </summary>
/// <exception cref="PythonException">Raised if the object can not be converted to a tuple.</exception>
public static PyTuple AsTuple(PyObject value)
{
if (value is null) throw new ArgumentNullException(nameof(value));
NewReference op = Runtime.PySequence_Tuple(value.Reference);
PythonException.ThrowIfIsNull(op);
return new PyTuple(op.Steal());
}
}
}