Esempio n. 1
0
        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();
            }
        }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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());
        }
Esempio n. 4
0
        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);
            }
        }