public static void With(PyObject obj, Action <dynamic> Body) { // Behavior described here: // https://docs.python.org/2/reference/datamodel.html#with-statement-context-managers IntPtr type = Runtime.PyNone; IntPtr val = Runtime.PyNone; IntPtr traceBack = Runtime.PyNone; PythonException ex = null; try { PyObject enterResult = obj.InvokeMethod("__enter__"); Body(enterResult); } catch (PythonException e) { ex = e; type = ex.PyType; val = ex.PyValue; traceBack = ex.PyTB; } var exitResult = obj.InvokeMethod("__exit__", new PyObject(type), new PyObject(val), new PyObject(traceBack)); if (ex != null && !exitResult.IsTrue()) { throw ex; } }
public object TrueDispatch(ArrayList args) { MethodInfo method = dtype.GetMethod("Invoke"); ParameterInfo[] pi = method.GetParameters(); IntPtr pyargs = Runtime.PyTuple_New(pi.Length); Type rtype = method.ReturnType; for (var i = 0; i < pi.Length; i++) { // Here we own the reference to the Python value, and we // give the ownership to the arg tuple. IntPtr arg = Converter.ToPython(args[i], pi[i].ParameterType); Runtime.PyTuple_SetItem(pyargs, i, arg); } IntPtr op = Runtime.PyObject_Call(target, pyargs, IntPtr.Zero); Runtime.XDecref(pyargs); if (op == IntPtr.Zero) { var e = new PythonException(); throw e; } if (rtype == typeof(void)) { return(null); } object result = null; if (!Converter.ToManaged(op, rtype, out result, false)) { Runtime.XDecref(op); throw new ConversionException($"could not convert Python result to {rtype}"); } Runtime.XDecref(op); return(result); }