Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

implement list codec#1084

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
lostmsu merged 25 commits intopythonnet:masterfromkoubaa:list-codec
Feb 18, 2021
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
25 commits
Select commitHold shift + click to select a range
b500aa1
begin to implement list codec
koubaaMar 10, 2020
f80ae87
add a test
koubaaMar 10, 2020
765b6a2
improve CanDecode
koubaaMar 11, 2020
98ce49c
improve list codec
koubaaMar 11, 2020
b827f5a
full set of list codecs
koubaaMar 11, 2020
224df0e
abandon rank and use three codecs
koubaaMar 22, 2020
1600fdc
update
koubaaMar 25, 2020
c43446e
respond to PR comments
koubaaMar 29, 2020
32fa32d
make decoders public
koubaaMar 31, 2020
dfc814b
Make reset public
koubaaApr 1, 2020
f025cd1
add codec tests
koubaaApr 1, 2020
24d78c3
respond to comments
koubaaApr 6, 2020
ebcfa30
fix brace
koubaaAug 30, 2020
5cc575d
use unix line endings to avoid large diff
koubaaAug 30, 2020
17c47a7
fix compiler error
koubaaAug 30, 2020
e8cc3d8
don't rethrow exception
koubaaSep 13, 2020
080dbc3
cleanup
koubaaSep 17, 2020
059ab08
fixes
koubaaSep 18, 2020
432c09e
clean up sequence wrapper
koubaaSep 18, 2020
3043201
respond to comments
koubaaOct 10, 2020
57d7779
fix potential double free
koubaaOct 20, 2020
7fb5915
fix exception
koubaaFeb 17, 2021
085c665
fix all exceptions
koubaaFeb 17, 2021
bf2d038
respond to PR feedback
koubaaFeb 18, 2021
07ee9fb
use hasattr("__iter__")
koubaaFeb 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
improve CanDecode
  • Loading branch information
@koubaa
koubaa committedFeb 16, 2021
commit765b6a221bf6414d147e96c0310c8b1b0045d26d
13 changes: 13 additions & 0 deletionssrc/embed_tests/Codecs.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,6 +133,19 @@ raise StopIteration
System.Collections.IEnumerable plainEnumerable2 = null;
Assert.DoesNotThrow(() => { codec.TryDecode<System.Collections.IEnumerable>(x, out plainEnumerable2); });
checkPlainEnumerable(plainEnumerable2);

//can convert to any generic ienumerable. If the type is not assignable from the python element
//it will be an exception during TryDecode
Assert.IsTrue(codec.CanDecode(foo, typeof(IEnumerable<int>)));
Assert.IsTrue(codec.CanDecode(foo, typeof(IEnumerable<double>)));
Assert.IsTrue(codec.CanDecode(foo, typeof(IEnumerable<string>)));

//cannot convert to ICollection or IList of any type since the python type is only iterable
Assert.IsFalse(codec.CanDecode(foo, typeof(ICollection<string>)));
Assert.IsFalse(codec.CanDecode(foo, typeof(ICollection<int>)));
Assert.IsFalse(codec.CanDecode(foo, typeof(IList<int>)));


}
}

Expand Down
94 changes: 73 additions & 21 deletionssrc/runtime/Codecs/ListCodec.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,43 +8,95 @@ namespace Python.Runtime.Codecs
{
class ListCodec : IPyObjectDecoder
{
public bool CanDecode(PyObject objectType, Type targetType)
private enum CollectionRank
{
//order matters, this is in increasing order of specialization
None,
Iterable,
Sequence,
List
}

private CollectionRank GetRank(PyObject objectType)
{
var handle = objectType.Handle;
//first check if the PyObject is iterable.
IntPtr IterObject = Runtime.PyObject_GetIter(objectType.Handle);
IntPtr IterObject = Runtime.PyObject_GetIter(handle);
if (IterObject == IntPtr.Zero)
returnfalse;
returnCollectionRank.None;

//if it is a plain IEnumerable, we can decode it using sequence protocol.
if (targetType == typeof(System.Collections.IEnumerable))
return true;
//now check if its a sequence
if (Runtime.PySequence_Check(handle))
{
//last check if its a list
if (Runtime.PyList_Check(handle))
return CollectionRank.List;
return CollectionRank.Sequence;
}

//if its not a plain IEnumerable it must be a generic type
if (!targetType.IsGenericType) return false;
return CollectionRank.Iterable;
}

Predicate<Type> IsCLRSequence = (Type type) => {
return (type.GetGenericTypeDefinition() == typeof(IEnumerable<>) ||
type.GetGenericTypeDefinition() == typeof(ICollection<>) ||
type.GetGenericTypeDefinition() == typeof(IList<>));
private CollectionRank GetRank(Type targetType)
{
//if it is a plain IEnumerable, we can decode it using sequence protocol.
if (targetType == typeof(System.Collections.IEnumerable))
return CollectionRank.Iterable;

Func<Type, CollectionRank> getRankOfType = (Type type) => {
if (type.GetGenericTypeDefinition() == typeof(IList<>))
return CollectionRank.List;
if (type.GetGenericTypeDefinition() == typeof(ICollection<>))
return CollectionRank.Sequence;
if (type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
return CollectionRank.Iterable;
return CollectionRank.None;
};

if (IsCLRSequence(targetType))
return true;
if (targetType.IsGenericType)
{
var thisRank = getRankOfType(targetType);
if (thisRank != CollectionRank.None)
return thisRank;
}

var maxRank = CollectionRank.None;
//if it implements any of the standard C# collection interfaces, we can decode it.
foreach (Type itf in targetType.GetInterfaces())
{
if (IsCLRSequence(itf))
return true;
if (!itf.IsGenericType) continue;

var thisRank = getRankOfType(itf);

//this is the most specialized type. return early
if (thisRank == CollectionRank.List) return thisRank;

//if it is more specialized, assign to max rank
if ((int)thisRank > (int)maxRank)
maxRank = thisRank;
}

//TODO objectType should implement the Sequence protocol to be convertible to ICollection
// and the list protocol to be convertible to IList. We should check for list first,
// then collection, then enumerable
return maxRank;
}


//if we get here we cannot decode it.
return false;
public bool CanDecode(PyObject objectType, Type targetType)
{
//get the python object rank
var pyRank = GetRank(objectType);
if (pyRank == CollectionRank.None)
return false;

//get the clr object rank
var clrRank = GetRank(targetType);
if (clrRank == CollectionRank.None)
return false;

//if it is a plain IEnumerable, we can decode it using sequence protocol.
if (targetType == typeof(System.Collections.IEnumerable))
return true;

return (int)pyRank >= (int)clrRank;
}

private class PyEnumerable : System.Collections.IEnumerable
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp