-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathArgs.cs
53 lines (47 loc) · 1.95 KB
/
Args.cs
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
using System;
using System.Collections;
using System.Reactive.Linq;
using Pythonnet = Python.Runtime;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Reflection;
namespace Bonsai.Scripting.Python
{
/// <summary>
/// Represents an operator that takes a sequence of python objects and converts them to a type of PyTuple to pass as arguments to a function.
/// </summary>
[Combinator]
[WorkflowElementCategory(ElementCategory.Transform)]
public class Args
{
public IObservable<Pythonnet.PyTuple> Process(IObservable<object> source)
{
return source.Select(obj =>
{
using (Pythonnet.Py.GIL())
{
if (!(obj is ITuple || obj is IList || obj is Array))
{
if (obj is Pythonnet.PyObject pyObj)
{
return new Pythonnet.PyTuple(new Pythonnet.PyObject[] {pyObj});
}
return new Pythonnet.PyTuple(new Pythonnet.PyObject[] {Pythonnet.PyObject.FromManagedObject(obj)});
}
PropertyInfo[] properties = obj.GetType().GetProperties();
Pythonnet.PyObject[] pyObjects = new Pythonnet.PyObject[properties.Length];
for (int i = 0; i < properties.Length; i++)
{
object value = properties[i].GetValue(obj, null);
if (!(value is Pythonnet.PyObject))
{
throw new ArgumentException($"All elements of the tuple must be of type PyObject. Instead, found {value.GetType()} for Item{i+1}.");
}
pyObjects[i] = (Pythonnet.PyObject)value;
}
return new Pythonnet.PyTuple(pyObjects);
}
});
}
}
}