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

Commitf8becef

Browse files
committed
Introduced PyIterable, PyObject no longer implements IEnumerable<PyObject>
1 parent2f3562a commitf8becef

File tree

9 files changed

+59
-54
lines changed

9 files changed

+59
-54
lines changed

‎CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ See [Mixins/collections.py](src/runtime/Mixins/collections.py).
2222
- .NET arrays implement Python buffer protocol
2323
- Python.NET will correctly resolve .NET methods, that accept`PyList`,`PyInt`,
2424
and other`PyObject` derived types when called from Python.
25+
-`PyIterable` type, that wraps any iterable object in Python
2526

2627

2728
###Changed
@@ -67,6 +68,8 @@ See [Mixins/collections.py](src/runtime/Mixins/collections.py).
6768
- BREAKING: When trying to convert Python`int` to`System.Object`, result will
6869
be of type`PyInt` instead of`System.Int32` due to possible loss of information.
6970
Python`float` will continue to be converted to`System.Double`.
71+
- BREAKING:`PyObject` no longer implements`IEnumerable<PyObject>`.
72+
Instead,`PyIterable` does that.
7073

7174
###Fixed
7275

‎src/embed_tests/Codecs.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ static void TupleConversionsGeneric<T, TTuple>()
4545
[Test]
4646
publicvoidTupleConversionsObject()
4747
{
48-
TupleConversionsObject<ValueTuple<int,string,object>,ValueTuple>();
48+
TupleConversionsObject<ValueTuple<double,string,object>,ValueTuple>();
4949
}
5050
staticvoidTupleConversionsObject<T,TTuple>()
5151
{
5252
TupleCodec<TTuple>.Register();
53-
vartuple=Activator.CreateInstance(typeof(T),42,"42",newobject());
53+
vartuple=Activator.CreateInstance(typeof(T),42.0,"42",newobject());
5454
Trestored=default;
5555
using(varscope=Py.CreateScope())
5656
{
@@ -66,11 +66,11 @@ static void TupleConversionsObject<T, TTuple>()
6666
[Test]
6767
publicvoidTupleRoundtripObject()
6868
{
69-
TupleRoundtripObject<ValueTuple<int,string,object>,ValueTuple>();
69+
TupleRoundtripObject<ValueTuple<double,string,object>,ValueTuple>();
7070
}
7171
staticvoidTupleRoundtripObject<T,TTuple>()
7272
{
73-
vartuple=Activator.CreateInstance(typeof(T),42,"42",newobject());
73+
vartuple=Activator.CreateInstance(typeof(T),42.0,"42",newobject());
7474
varpyTuple=TupleCodec<TTuple>.Instance.TryEncode(tuple);
7575
Assert.IsTrue(TupleCodec<TTuple>.Instance.TryDecode(pyTuple,outobjectrestored));
7676
Assert.AreEqual(expected:tuple,actual:restored);
@@ -231,7 +231,7 @@ public void IterableDecoderTest()
231231
//ensure a PyList can be converted to a plain IEnumerable
232232
System.Collections.IEnumerableplainEnumerable1=null;
233233
Assert.DoesNotThrow(()=>{codec.TryDecode(pyList,outplainEnumerable1);});
234-
CollectionAssert.AreEqual(plainEnumerable1,newList<object>{1,2,3});
234+
CollectionAssert.AreEqual(plainEnumerable1.Cast<PyInt>().Select(i=>i.ToInt32()),newList<object>{1,2,3});
235235

236236
//can convert to any generic ienumerable. If the type is not assignable from the python element
237237
//it will lead to an empty iterable when decoding. TODO - should it throw?
@@ -271,7 +271,7 @@ public void IterableDecoderTest()
271271
varfooType=foo.GetPythonType();
272272
System.Collections.IEnumerableplainEnumerable2=null;
273273
Assert.DoesNotThrow(()=>{codec.TryDecode(pyList,outplainEnumerable2);});
274-
CollectionAssert.AreEqual(plainEnumerable2,newList<object>{1,2,3});
274+
CollectionAssert.AreEqual(plainEnumerable2.Cast<PyInt>().Select(i=>i.ToInt32()),newList<object>{1,2,3});
275275

276276
//can convert to any generic ienumerable. If the type is not assignable from the python element
277277
//it will be an exception during TryDecode

‎src/runtime/Util.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#nullable enable
22
usingSystem;
3+
usingSystem.Collections.Generic;
34
usingSystem.IO;
45
usingSystem.Runtime.InteropServices;
56

@@ -68,5 +69,7 @@ internal static string ReadStringResource(this System.Reflection.Assembly assemb
6869
usingvarreader=newStreamReader(stream);
6970
returnreader.ReadToEnd();
7071
}
72+
73+
publicstaticIEnumerator<T>GetEnumerator<T>(thisIEnumerator<T>enumerator)=>enumerator;
7174
}
7275
}

‎src/runtime/classderived.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ internal static Type CreateDerivedType(string name,
174174
{
175175
Runtime.XIncref(py_dict);
176176
using(vardict=newPyDict(py_dict))
177-
using(PyObjectkeys=dict.Keys())
177+
using(PyIterablekeys=dict.Keys())
178178
{
179179
foreach(PyObjectpyKeyinkeys)
180180
{
@@ -223,7 +223,7 @@ internal static Type CreateDerivedType(string name,
223223
{
224224
Runtime.XIncref(py_dict);
225225
using(vardict=newPyDict(py_dict))
226-
using(PyObjectkeys=dict.Keys())
226+
using(PyIterablekeys=dict.Keys())
227227
{
228228
foreach(PyObjectpyKeyinkeys)
229229
{
@@ -439,19 +439,14 @@ private static void AddPythonMethod(string methodName, PyObject func, TypeBuilde
439439
}
440440

441441
using(PyObjectpyReturnType=func.GetAttr("_clr_return_type_"))
442-
using(PyObjectpyArgTypes=func.GetAttr("_clr_arg_types_"))
442+
using(varpyArgTypes=PyIter.GetIter(func.GetAttr("_clr_arg_types_")))
443443
{
444444
varreturnType=pyReturnType.AsManagedObject(typeof(Type))asType;
445445
if(returnType==null)
446446
{
447447
returnType=typeof(void);
448448
}
449449

450-
if(!pyArgTypes.IsIterable())
451-
{
452-
thrownewArgumentException("_clr_arg_types_ must be a list or tuple of CLR types");
453-
}
454-
455450
varargTypes=newList<Type>();
456451
foreach(PyObjectpyArgTypeinpyArgTypes)
457452
{

‎src/runtime/pydict.cs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Python.Runtime
88
/// PY3: https://docs.python.org/3/c-api/dict.html
99
/// for details.
1010
/// </summary>
11-
publicclassPyDict:PyObject
11+
publicclassPyDict:PyIterable
1212
{
1313
/// <summary>
1414
/// PyDict Constructor
@@ -102,14 +102,14 @@ public bool HasKey(string key)
102102
/// <remarks>
103103
/// Returns a sequence containing the keys of the dictionary.
104104
/// </remarks>
105-
publicPyObjectKeys()
105+
publicPyIterableKeys()
106106
{
107107
usingvaritems=Runtime.PyDict_Keys(Reference);
108108
if(items.IsNull())
109109
{
110110
throwPythonException.ThrowLastAsClrException();
111111
}
112-
returnitems.MoveToPyObject();
112+
returnnewPyIterable(items.Steal());
113113
}
114114

115115

@@ -119,14 +119,14 @@ public PyObject Keys()
119119
/// <remarks>
120120
/// Returns a sequence containing the values of the dictionary.
121121
/// </remarks>
122-
publicPyObjectValues()
122+
publicPyIterableValues()
123123
{
124124
IntPtritems=Runtime.PyDict_Values(obj);
125125
if(items==IntPtr.Zero)
126126
{
127127
throwPythonException.ThrowLastAsClrException();
128128
}
129-
returnnewPyObject(items);
129+
returnnewPyIterable(items);
130130
}
131131

132132

@@ -136,22 +136,14 @@ public PyObject Values()
136136
/// <remarks>
137137
/// Returns a sequence containing the items of the dictionary.
138138
/// </remarks>
139-
publicPyObjectItems()
139+
publicPyIterableItems()
140140
{
141-
varitems=Runtime.PyDict_Items(this.Reference);
142-
try
143-
{
144-
if(items.IsNull())
145-
{
146-
throwPythonException.ThrowLastAsClrException();
147-
}
148-
149-
returnitems.MoveToPyObject();
150-
}
151-
finally
141+
usingvaritems=Runtime.PyDict_Items(this.Reference);
142+
if(items.IsNull())
152143
{
153-
items.Dispose();
144+
throwPythonException.ThrowLastAsClrException();
154145
}
146+
returnnewPyIterable(items.Steal());
155147
}
156148

157149

‎src/runtime/pyiterable.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
usingSystem;
2+
usingSystem.Collections;
3+
usingSystem.Collections.Generic;
4+
5+
namespacePython.Runtime
6+
{
7+
publicclassPyIterable:PyObject,IEnumerable<PyObject>
8+
{
9+
internalPyIterable(IntPtrptr):base(ptr)
10+
{
11+
}
12+
13+
internalPyIterable(BorrowedReferencereference):base(reference){}
14+
internalPyIterable(inStolenReferencereference):base(reference){}
15+
16+
/// <summary>
17+
/// Return a new PyIter object for the object. This allows any iterable
18+
/// python object to be iterated over in C#. A PythonException will be
19+
/// raised if the object is not iterable.
20+
/// </summary>
21+
publicPyIterGetEnumerator()
22+
{
23+
returnPyIter.GetIter(this);
24+
}
25+
IEnumerator<PyObject>IEnumerable<PyObject>.GetEnumerator()=>this.GetEnumerator();
26+
IEnumeratorIEnumerable.GetEnumerator()=>this.GetEnumerator();
27+
}
28+
}

‎src/runtime/pyobject.cs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace Python.Runtime
1717
/// </summary>
1818
[Serializable]
1919
[DebuggerDisplay("{"+nameof(DebuggerDisplay)+",nq}")]
20-
publicpartialclassPyObject:DynamicObject,IEnumerable<PyObject>,IDisposable
20+
publicpartialclassPyObject:DynamicObject,IDisposable
2121
{
2222
#ifTRACE_ALLOC
2323
/// <summary>
@@ -80,7 +80,7 @@ internal PyObject(BorrowedReference reference)
8080
#endif
8181
}
8282

83-
internalPyObject(StolenReferencereference)
83+
internalPyObject(inStolenReferencereference)
8484
{
8585
if(reference==null)thrownewArgumentNullException(nameof(reference));
8686

@@ -703,21 +703,6 @@ public PyObject GetIterator()
703703
returnnewPyObject(r);
704704
}
705705

706-
/// <summary>
707-
/// GetEnumerator Method
708-
/// </summary>
709-
/// <remarks>
710-
/// Return a new PyIter object for the object. This allows any iterable
711-
/// python object to be iterated over in C#. A PythonException will be
712-
/// raised if the object is not iterable.
713-
/// </remarks>
714-
publicIEnumerator<PyObject>GetEnumerator()
715-
{
716-
returnPyIter.GetIter(this);
717-
}
718-
IEnumeratorIEnumerable.GetEnumerator()=>this.GetEnumerator();
719-
720-
721706
/// <summary>
722707
/// Invoke Method
723708
/// </summary>

‎src/runtime/pysequence.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
usingSystem;
2-
usingSystem.Collections;
32

43
namespacePython.Runtime
54
{
@@ -10,13 +9,14 @@ namespace Python.Runtime
109
/// PY3: https://docs.python.org/3/c-api/sequence.html
1110
/// for details.
1211
/// </summary>
13-
publicclassPySequence:PyObject,IEnumerable
12+
publicclassPySequence:PyIterable
1413
{
15-
protectedPySequence(IntPtrptr):base(ptr)
14+
protectedinternalPySequence(IntPtrptr):base(ptr)
1615
{
1716
}
1817

1918
internalPySequence(BorrowedReferencereference):base(reference){}
19+
internalPySequence(StolenReferencereference):base(reference){}
2020

2121

2222
/// <summary>
@@ -30,7 +30,6 @@ public static bool IsSequenceType(PyObject value)
3030
returnRuntime.PySequence_Check(value.obj);
3131
}
3232

33-
3433
/// <summary>
3534
/// GetSlice Method
3635
/// </summary>

‎src/runtime/pythonexception.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ public string Format()
387387
usingvartraceback=PyModule.Import("traceback");
388388
varbuffer=newStringBuilder();
389389
usingvarvalues=traceback.InvokeMethod("format_exception",copy.Type,copy.Value,copy.Traceback);
390-
foreach(PyObjectvalinvalues)
390+
foreach(PyObjectvalinPyIter.GetIter(values))
391391
{
392392
buffer.Append(val);
393393
val.Dispose();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp