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 PythonException() { IntPtr gs = PythonEngine.AcquireLock(); Runtime.PyErr_Fetch(ref _pyType, ref _pyValue, ref _pyTB); if (_pyType != IntPtr.Zero && _pyValue != IntPtr.Zero) { string type; string message; Runtime.XIncref(_pyType); using (var pyType = new PyObject(_pyType)) using (PyObject pyTypeName = pyType.GetAttr("__name__")) { type = pyTypeName.ToString(); } _pythonTypeName = type; Runtime.XIncref(_pyValue); using (var pyValue = new PyObject(_pyValue)) { message = pyValue.ToString(); } _message = type + " : " + message; } if (_pyTB != IntPtr.Zero) { using (PyObject tb_module = PythonEngine.ImportModule("traceback")) { Runtime.XIncref(_pyTB); using (var pyTB = new PyObject(_pyTB)) { _tb = tb_module.InvokeMethod("format_tb", pyTB).ToString(); } } } PythonEngine.ReleaseLock(gs); }