예제 #1
0
        public void RawPyObjectProxy()
        {
            var pyObject      = "hello world!".ToPython();
            var pyObjectProxy = PyObject.FromManagedObject(pyObject);
            var clrObject     = (CLRObject)ManagedType.GetManagedObject(pyObjectProxy.Handle);

            Assert.AreSame(pyObject, clrObject.inst);

            var proxiedHandle = pyObjectProxy.GetAttr("Handle").As <IntPtr>();

            Assert.AreEqual(pyObject.Handle, proxiedHandle);
        }
예제 #2
0
    /// <summary>
    /// Remove the given Python object event handler.
    /// </summary>
    internal bool RemoveEventHandler(BorrowedReference target, BorrowedReference handler)
    {
        object?obj = null;

        if (target != null)
        {
            var co = (CLRObject)ManagedType.GetManagedObject(target) !;
            obj = co.inst;
        }

        nint hash = Runtime.PyObject_Hash(handler);

        if (hash == -1 && Exceptions.ErrorOccurred())
        {
            return(false);
        }

        object key = obj ?? info.ReflectedType;

        if (!TryGetValue(key, out var list))
        {
            Exceptions.SetError(Exceptions.ValueError, "unknown event handler");
            return(false);
        }

        object?[]  args = { null };
        MethodInfo mi   = info.GetRemoveMethod(true);

        for (var i = 0; i < list.Count; i++)
        {
            var item = (Handler)list[i];
            if (item.hash != hash)
            {
                continue;
            }
            args[0] = item.del;
            try
            {
                mi.Invoke(obj, BindingFlags.Default, null, args, null);
            }
            catch
            {
                continue;
            }
            list.RemoveAt(i);
            return(true);
        }

        Exceptions.SetError(Exceptions.ValueError, "unknown event handler");
        return(false);
    }
예제 #3
0
        public void RawPyObjectProxy()
        {
            var pyObject      = "hello world!".ToPython();
            var pyObjectProxy = PyObject.FromManagedObject(pyObject);
            var clrObject     = (CLRObject)ManagedType.GetManagedObject(pyObjectProxy);

            Assert.AreSame(pyObject, clrObject.inst);

#pragma warning disable CS0612 // Type or member is obsolete
            const string handlePropertyName = nameof(PyObject.Handle);
#pragma warning restore CS0612 // Type or member is obsolete
            var proxiedHandle = pyObjectProxy.GetAttr(handlePropertyName).As <IntPtr>();
            Assert.AreEqual(pyObject.DangerousGetAddressOrNull(), proxiedHandle);
        }
예제 #4
0
        public void Encodes()
        {
            var encoder0 = new ObjectToEncoderInstanceEncoder <Tuple <int> >();
            var encoder1 = new ObjectToEncoderInstanceEncoder <Uri>();
            var encoder2 = new ObjectToEncoderInstanceEncoder <Uri>();
            var group    = new EncoderGroup {
                encoder0,
                encoder1,
                encoder2,
            };

            var uri       = group.TryEncode(new Uri("data:"));
            var clrObject = (CLRObject)ManagedType.GetManagedObject(uri.Handle);

            Assert.AreSame(encoder1, clrObject.inst);
            Assert.AreNotSame(encoder2, clrObject.inst);

            var tuple = group.TryEncode(Tuple.Create(1));

            clrObject = (CLRObject)ManagedType.GetManagedObject(tuple.Handle);
            Assert.AreSame(encoder0, clrObject.inst);
        }
예제 #5
0
        /// <summary>
        /// Implements __len__ for classes that implement ICollection
        /// (this includes any IList implementer or Array subclass)
        /// </summary>
        internal static nint impl(BorrowedReference ob)
        {
            var co = ManagedType.GetManagedObject(ob) as CLRObject;

            if (co == null)
            {
                Exceptions.RaiseTypeError("invalid object");
                return(-1);
            }

            // first look for ICollection implementation directly
            if (co.inst is ICollection c)
            {
                return(c.Count);
            }

            Type clrType = co.inst.GetType();

            // now look for things that implement ICollection<T> directly (non-explicitly)
            PropertyInfo p = clrType.GetProperty("Count");

            if (p != null && clrType.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection <>)))
            {
                return((int)p.GetValue(co.inst, null));
            }

            // finally look for things that implement the interface explicitly
            var iface = clrType.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection <>));

            if (iface != null)
            {
                p = iface.GetProperty(nameof(ICollection <int> .Count));
                return((int)p.GetValue(co.inst, null));
            }

            Exceptions.SetError(Exceptions.TypeError, $"object of type '{clrType.Name}' has no len()");
            return(-1);
        }
예제 #6
0
    /// <summary>
    /// Register a new Python object event handler with the event.
    /// </summary>
    internal bool AddEventHandler(BorrowedReference target, PyObject handler)
    {
        object?obj = null;

        if (target != null)
        {
            var co = (CLRObject)ManagedType.GetManagedObject(target) !;
            obj = co.inst;
        }

        // Create a true delegate instance of the appropriate type to
        // wrap the Python handler. Note that wrapper delegate creation
        // always succeeds, though calling the wrapper may fail.
        Type     type = info.EventHandlerType;
        Delegate d    = PythonEngine.DelegateManager.GetDelegate(type, handler);

        // Now register the handler in a mapping from instance to pairs
        // of (handler hash, delegate) so we can lookup to remove later.
        object key = obj ?? info.ReflectedType;

        if (!TryGetValue(key, out var list))
        {
            list      = new List <Handler>();
            this[key] = list;
        }
        list.Add(new Handler(Runtime.PyObject_Hash(handler), d));

        // Note that AddEventHandler helper only works for public events,
        // so we have to get the underlying add method explicitly.
        object[]   args = { d };
        MethodInfo mi   = info.GetAddMethod(true);

        mi.Invoke(obj, BindingFlags.Default, null, args, null);

        return(true);
    }