public static void PyCheck_Iter_PyObject_IsIterable_ThreadingLock_Test() { Runtime.Runtime.Py_Initialize(); Runtime.Native.ABI.Initialize(Runtime.Runtime.PyVersion); try { // Create an instance of threading.Lock, which is one of the very few types that does not have the // TypeFlags.HaveIter set in Python 2. This tests a different code path in PyObject_IsIterable and PyIter_Check. using var threading = Runtime.Runtime.PyImport_ImportModule("threading"); Exceptions.ErrorCheck(threading); var threadingDict = Runtime.Runtime.PyModule_GetDict(threading); Exceptions.ErrorCheck(threadingDict); var lockType = Runtime.Runtime.PyDict_GetItemString(threadingDict, "Lock"); if (lockType.IsNull) { throw PythonException.ThrowLastAsClrException(); } using var args = NewReference.DangerousFromPointer(Runtime.Runtime.PyTuple_New(0)); using var lockInstance = Runtime.Runtime.PyObject_CallObject(lockType, args); Exceptions.ErrorCheck(lockInstance); Assert.IsFalse(Runtime.Runtime.PyObject_IsIterable(lockInstance)); Assert.IsFalse(Runtime.Runtime.PyIter_Check(lockInstance)); } finally { Runtime.Runtime.Py_Finalize(); } }
public static NewReference CreateObjectType() { using var globals = Runtime.PyDict_New(); if (Runtime.PyDict_SetItemString(globals.Borrow(), "__builtins__", Runtime.PyEval_GetBuiltins()) != 0) { globals.Dispose(); throw PythonException.ThrowLastAsClrException(); } const string code = "class A(object): pass"; using var resRef = Runtime.PyRun_String(code, RunFlagType.File, globals.Borrow(), globals.Borrow()); if (resRef.IsNull()) { globals.Dispose(); throw PythonException.ThrowLastAsClrException(); } resRef.Dispose(); BorrowedReference A = Runtime.PyDict_GetItemString(globals.Borrow(), "A"); return(new NewReference(A)); }
public static IntPtr CreateObjectType() { using var globals = NewReference.DangerousFromPointer(Runtime.PyDict_New()); if (Runtime.PyDict_SetItemString(globals, "__builtins__", Runtime.PyEval_GetBuiltins()) != 0) { globals.Dispose(); throw PythonException.ThrowLastAsClrException(); } const string code = "class A(object): pass"; using var resRef = Runtime.PyRun_String(code, RunFlagType.File, globals, globals); if (resRef.IsNull()) { globals.Dispose(); throw PythonException.ThrowLastAsClrException(); } resRef.Dispose(); BorrowedReference A = Runtime.PyDict_GetItemString(globals, "A"); Debug.Assert(!A.IsNull); return(new NewReference(A).DangerousMoveToPointer()); }
private object?TrueDispatch(object?[] args) { MethodInfo method = dtype.GetMethod("Invoke"); ParameterInfo[] pi = method.GetParameters(); Type rtype = method.ReturnType; NewReference callResult; using (var pyargs = Runtime.PyTuple_New(pi.Length)) { 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. using var arg = Converter.ToPython(args[i], pi[i].ParameterType); int res = Runtime.PyTuple_SetItem(pyargs.Borrow(), i, arg.StealOrThrow()); if (res != 0) { throw PythonException.ThrowLastAsClrException(); } } callResult = Runtime.PyObject_Call(target, pyargs.Borrow(), null); } if (callResult.IsNull()) { throw PythonException.ThrowLastAsClrException(); } using (callResult) { BorrowedReference op = callResult.Borrow(); int byRefCount = pi.Count(parameterInfo => parameterInfo.ParameterType.IsByRef); if (byRefCount > 0) { // By symmetry with MethodBinder.Invoke, when there are out // parameters we expect to receive a tuple containing // the result, if any, followed by the out parameters. If there is only // one out parameter and the return type of the method is void, // we instead receive the out parameter as the result from Python. bool isVoid = rtype == typeof(void); int tupleSize = byRefCount + (isVoid ? 0 : 1); if (isVoid && byRefCount == 1) { // The return type is void and there is a single out parameter. for (int i = 0; i < pi.Length; i++) { Type t = pi[i].ParameterType; if (t.IsByRef) { if (!Converter.ToManaged(op, t, out args[i], true)) { Exceptions.RaiseTypeError($"The Python function did not return {t.GetElementType()} (the out parameter type)"); throw PythonException.ThrowLastAsClrException(); } break; } } return(null); } else if (Runtime.PyTuple_Check(op) && Runtime.PyTuple_Size(op) == tupleSize) { int index = isVoid ? 0 : 1; for (int i = 0; i < pi.Length; i++) { Type t = pi[i].ParameterType; if (t.IsByRef) { BorrowedReference item = Runtime.PyTuple_GetItem(op, index++); if (!Converter.ToManaged(item, t, out args[i], true)) { Exceptions.RaiseTypeError($"The Python function returned a tuple where element {i} was not {t.GetElementType()} (the out parameter type)"); throw PythonException.ThrowLastAsClrException(); } } } if (isVoid) { return(null); } BorrowedReference item0 = Runtime.PyTuple_GetItem(op, 0); if (!Converter.ToManaged(item0, rtype, out object?result0, true)) { Exceptions.RaiseTypeError($"The Python function returned a tuple where element 0 was not {rtype} (the return type)"); throw PythonException.ThrowLastAsClrException(); } return(result0); } else { string tpName = Runtime.PyObject_GetTypeName(op); if (Runtime.PyTuple_Check(op)) { tpName += $" of size {Runtime.PyTuple_Size(op)}"; } var sb = new StringBuilder(); if (!isVoid) { sb.Append(rtype.FullName); } for (int i = 0; i < pi.Length; i++) { Type t = pi[i].ParameterType; if (t.IsByRef) { if (sb.Length > 0) { sb.Append(","); } sb.Append(t.GetElementType().FullName); } } string returnValueString = isVoid ? "" : "the return value and "; Exceptions.RaiseTypeError($"Expected a tuple ({sb}) of {returnValueString}the values for out and ref parameters, got {tpName}."); throw PythonException.ThrowLastAsClrException(); } } if (rtype == typeof(void)) { return(null); } if (!Converter.ToManaged(op, rtype, out object?result, true)) { throw PythonException.ThrowLastAsClrException(); } return(result); } }