From 3c53779840ee507342a0df2fc73a906d7c353afc Mon Sep 17 00:00:00 2001 From: Victor Nova Date: Fri, 1 Oct 2021 23:53:10 -0700 Subject: [PATCH] Changed signature of IPyObjectDecoder.CanDecode first parameter (objectType) type changed from PyObject to PyType --- CHANGELOG.md | 1 + src/embed_tests/Codecs.cs | 25 +++++++++++++------------ src/runtime/Codecs/DecoderGroup.cs | 4 ++-- src/runtime/Codecs/EnumPyIntCodec.cs | 2 +- src/runtime/Codecs/IterableDecoder.cs | 4 ++-- src/runtime/Codecs/ListDecoder.cs | 4 ++-- src/runtime/Codecs/SequenceDecoder.cs | 4 ++-- src/runtime/Codecs/TupleCodecs.cs | 2 +- src/runtime/converterextensions.cs | 7 +++++-- 9 files changed, 29 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 876bff07d..f8b0aed48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,7 @@ Python `float` will continue to be converted to `System.Double`. - BREAKING: `PyObject.GetAttr(name, default)` now only ignores `AttributeError` (previously ignored all exceptions). - BREAKING: `PyObject` no longer implements `IEnumerable`. Instead, `PyIterable` does that. +- BREAKING: `IPyObjectDecoder.CanDecode` `objectType` parameter type changed from `PyObject` to `PyType` ### Fixed diff --git a/src/embed_tests/Codecs.cs b/src/embed_tests/Codecs.cs index 1169bca34..1beddbec9 100644 --- a/src/embed_tests/Codecs.cs +++ b/src/embed_tests/Codecs.cs @@ -141,16 +141,17 @@ public void SequenceDecoderTest() //SequenceConverter can only convert to any ICollection var pyList = new PyList(items.ToArray()); + var listType = pyList.GetPythonType(); //it can convert a PyList, since PyList satisfies the python sequence protocol - Assert.IsFalse(codec.CanDecode(pyList, typeof(bool))); - Assert.IsFalse(codec.CanDecode(pyList, typeof(IList))); - Assert.IsFalse(codec.CanDecode(pyList, typeof(System.Collections.IEnumerable))); - Assert.IsFalse(codec.CanDecode(pyList, typeof(IEnumerable))); + Assert.IsFalse(codec.CanDecode(listType, typeof(bool))); + Assert.IsFalse(codec.CanDecode(listType, typeof(IList))); + Assert.IsFalse(codec.CanDecode(listType, typeof(System.Collections.IEnumerable))); + Assert.IsFalse(codec.CanDecode(listType, typeof(IEnumerable))); - Assert.IsTrue(codec.CanDecode(pyList, typeof(ICollection))); - Assert.IsTrue(codec.CanDecode(pyList, typeof(ICollection))); - Assert.IsTrue(codec.CanDecode(pyList, typeof(ICollection))); + Assert.IsTrue(codec.CanDecode(listType, typeof(ICollection))); + Assert.IsTrue(codec.CanDecode(listType, typeof(ICollection))); + Assert.IsTrue(codec.CanDecode(listType, typeof(ICollection))); //convert to collection of int ICollection intCollection = null; @@ -380,7 +381,7 @@ public void As_Object_AffectedByDecoders() public class EverythingElseToSelfDecoder : IPyObjectDecoder { - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) { return targetType.IsAssignableFrom(typeof(EverythingElseToSelfDecoder)); } @@ -399,7 +400,7 @@ public ValueErrorWrapper(string message) : base(message) { } class ValueErrorCodec : IPyObjectEncoder, IPyObjectDecoder { - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) => this.CanEncode(targetType) && PythonReferenceComparer.Instance.Equals(objectType, PythonEngine.Eval("ValueError")); @@ -424,7 +425,7 @@ class InstancelessExceptionDecoder : IPyObjectDecoder { readonly PyObject PyErr = Py.Import("clr.interop").GetAttr("PyErr"); - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) => PythonReferenceComparer.Instance.Equals(PyErr, objectType); public bool TryDecode(PyObject pyObj, out T value) @@ -466,7 +467,7 @@ public DecoderReturningPredefinedValue(PyObject objectType, TTarget decodeResult this.DecodeResult = decodeResult; } - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) => objectType.Handle == TheOnlySupportedSourceType.Handle && targetType == typeof(TTarget); public bool TryDecode(PyObject pyObj, out T value) @@ -485,7 +486,7 @@ public static void Setup() PyObjectConversions.RegisterDecoder(new DateTimeDecoder()); } - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) { return targetType == typeof(DateTime); } diff --git a/src/runtime/Codecs/DecoderGroup.cs b/src/runtime/Codecs/DecoderGroup.cs index cc511ed50..b72cd796c 100644 --- a/src/runtime/Codecs/DecoderGroup.cs +++ b/src/runtime/Codecs/DecoderGroup.cs @@ -27,7 +27,7 @@ public void Add(IPyObjectDecoder item) public void Clear() => this.decoders.Clear(); /// - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) => this.decoders.Any(decoder => decoder.CanDecode(objectType, targetType)); /// public bool TryDecode(PyObject pyObj, out T value) @@ -58,7 +58,7 @@ public static class DecoderGroupExtensions /// public static IPyObjectDecoder GetDecoder( this IPyObjectDecoder decoder, - PyObject objectType, Type targetType) + PyType objectType, Type targetType) { if (decoder is null) throw new ArgumentNullException(nameof(decoder)); diff --git a/src/runtime/Codecs/EnumPyIntCodec.cs b/src/runtime/Codecs/EnumPyIntCodec.cs index 5e6c4c7d3..8e68837f3 100644 --- a/src/runtime/Codecs/EnumPyIntCodec.cs +++ b/src/runtime/Codecs/EnumPyIntCodec.cs @@ -7,7 +7,7 @@ public sealed class EnumPyIntCodec : IPyObjectEncoder, IPyObjectDecoder { public static EnumPyIntCodec Instance { get; } = new EnumPyIntCodec(); - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) { return targetType.IsEnum && objectType.IsSubclass(new BorrowedReference(Runtime.PyLongType)); diff --git a/src/runtime/Codecs/IterableDecoder.cs b/src/runtime/Codecs/IterableDecoder.cs index 346057238..bcc2eca01 100644 --- a/src/runtime/Codecs/IterableDecoder.cs +++ b/src/runtime/Codecs/IterableDecoder.cs @@ -17,12 +17,12 @@ internal static bool IsIterable(Type targetType) return targetType.GetGenericTypeDefinition() == typeof(IEnumerable<>); } - internal static bool IsIterable(PyObject objectType) + internal static bool IsIterable(PyType objectType) { return objectType.HasAttr("__iter__"); } - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) { return IsIterable(objectType) && IsIterable(targetType); } diff --git a/src/runtime/Codecs/ListDecoder.cs b/src/runtime/Codecs/ListDecoder.cs index 013f3f3f9..439c87df8 100644 --- a/src/runtime/Codecs/ListDecoder.cs +++ b/src/runtime/Codecs/ListDecoder.cs @@ -13,7 +13,7 @@ private static bool IsList(Type targetType) return targetType.GetGenericTypeDefinition() == typeof(IList<>); } - private static bool IsList(PyObject objectType) + private static bool IsList(PyType objectType) { //TODO accept any python object that implements the sequence and list protocols //must implement sequence protocol to fully implement list protocol @@ -23,7 +23,7 @@ private static bool IsList(PyObject objectType) return objectType.Handle == Runtime.PyListType; } - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) { return IsList(objectType) && IsList(targetType); } diff --git a/src/runtime/Codecs/SequenceDecoder.cs b/src/runtime/Codecs/SequenceDecoder.cs index dce08fd99..a539297cd 100644 --- a/src/runtime/Codecs/SequenceDecoder.cs +++ b/src/runtime/Codecs/SequenceDecoder.cs @@ -13,7 +13,7 @@ internal static bool IsSequence(Type targetType) return targetType.GetGenericTypeDefinition() == typeof(ICollection<>); } - internal static bool IsSequence(PyObject objectType) + internal static bool IsSequence(PyType objectType) { //must implement iterable protocol to fully implement sequence protocol if (!IterableDecoder.IsIterable(objectType)) return false; @@ -25,7 +25,7 @@ internal static bool IsSequence(PyObject objectType) return objectType.HasAttr("__getitem__"); } - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) { return IsSequence(objectType) && IsSequence(targetType); } diff --git a/src/runtime/Codecs/TupleCodecs.cs b/src/runtime/Codecs/TupleCodecs.cs index 823c42489..cd4d519ba 100644 --- a/src/runtime/Codecs/TupleCodecs.cs +++ b/src/runtime/Codecs/TupleCodecs.cs @@ -41,7 +41,7 @@ public PyObject TryEncode(object value) return new PyTuple(StolenReference.DangerousFromPointer(tuple)); } - public bool CanDecode(PyObject objectType, Type targetType) + public bool CanDecode(PyType objectType, Type targetType) => objectType.Handle == Runtime.PyTupleType && this.CanEncode(targetType); public bool TryDecode(PyObject pyObj, out T value) diff --git a/src/runtime/converterextensions.cs b/src/runtime/converterextensions.cs index 5711b9f87..2396fb0bd 100644 --- a/src/runtime/converterextensions.cs +++ b/src/runtime/converterextensions.cs @@ -3,6 +3,7 @@ namespace Python.Runtime using System; using System.Collections.Concurrent; using System.Collections.Generic; + using System.Diagnostics; using System.Linq; using System.Reflection; using Python.Runtime.Codecs; @@ -15,7 +16,7 @@ public interface IPyObjectDecoder /// /// Checks if this decoder can decode from to /// - bool CanDecode(PyObject objectType, Type targetType); + bool CanDecode(PyType objectType, Type targetType); /// /// Attempts do decode into a variable of specified type /// @@ -124,7 +125,9 @@ internal static bool TryDecode(IntPtr pyHandle, IntPtr pyType, Type targetType, static Converter.TryConvertFromPythonDelegate GetDecoder(IntPtr sourceType, Type targetType) { IPyObjectDecoder decoder; - using (var pyType = new PyObject(Runtime.SelfIncRef(sourceType))) + var sourceTypeRef = new BorrowedReference(sourceType); + Debug.Assert(PyType.IsType(sourceTypeRef)); + using (var pyType = new PyType(sourceTypeRef, prevalidated: true)) { lock (decoders) { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy