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

Commitcebc515

Browse files
committed
PyIter: do not force dispose previous object upon moving to the next one
also added exception handling for PyIter_NextPyObject now implements `IEnumerable<PyObject>`
1 parent9307bb3 commitcebc515

File tree

5 files changed

+58
-22
lines changed

5 files changed

+58
-22
lines changed

‎CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ details about the cause of the failure
2626
- BREAKING: Parameters marked with`ParameterAttributes.Out` are no longer returned in addition
2727
to the regular method return value (unless they are passed with`ref` or`out` keyword).
2828
- BREAKING: Drop support for the long-deprecated CLR.* prefix.
29+
-`PyObject` now implements`IEnumerable<PyObject>` in addition to`IEnumerable`
2930

3031
###Fixed
3132

@@ -40,6 +41,7 @@ details about the cause of the failure
4041
- Fixed a bug where indexers could not be used if they were inherited
4142
- Made it possible to use`__len__` also on`ICollection<>` interface objects
4243
- Made it possible to call`ToString`,`GetHashCode`, and`GetType` on inteface objects
44+
- Fixed objects returned by enumerating`PyObject` being disposed too soon
4345

4446
###Removed
4547

‎src/embed_tests/TestPyIter.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
usingSystem.Linq;
2+
usingSystem.Text;
3+
4+
usingNUnit.Framework;
5+
6+
usingPython.Runtime;
7+
8+
namespacePython.EmbeddingTest
9+
{
10+
classTestPyIter
11+
{
12+
[OneTimeSetUp]
13+
publicvoidSetUp()
14+
{
15+
PythonEngine.Initialize();
16+
}
17+
18+
[OneTimeTearDown]
19+
publicvoidDispose()
20+
{
21+
PythonEngine.Shutdown();
22+
}
23+
24+
[Test]
25+
publicvoidKeepOldObjects()
26+
{
27+
using(Py.GIL())
28+
using(vartestString=newPyString("hello world! !$%&/()=?"))
29+
{
30+
PyObject[]chars=testString.ToArray();
31+
Assert.IsTrue(chars.Length>1);
32+
stringreconstructed=string.Concat(chars.Select(c=>c.As<string>()));
33+
Assert.AreEqual(testString.As<string>(),reconstructed);
34+
}
35+
}
36+
}
37+
}

‎src/runtime/pyiter.cs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Python.Runtime
99
/// PY3: https://docs.python.org/3/c-api/iterator.html
1010
/// for details.
1111
/// </summary>
12-
publicclassPyIter:PyObject,IEnumerator<object>
12+
publicclassPyIter:PyObject,IEnumerator<PyObject>
1313
{
1414
privatePyObject_current;
1515

@@ -46,41 +46,35 @@ public static PyIter GetIter(PyObject iterable)
4646

4747
protectedoverridevoidDispose(booldisposing)
4848
{
49-
if(null!=_current)
50-
{
51-
_current.Dispose();
52-
_current=null;
53-
}
49+
_current=null;
5450
base.Dispose(disposing);
5551
}
5652

5753
publicboolMoveNext()
5854
{
59-
// dispose of the previous object, if there was one
60-
if(null!=_current)
55+
NewReferencenext=Runtime.PyIter_Next(Reference);
56+
if(next.IsNull())
6157
{
62-
_current.Dispose();
63-
_current=null;
64-
}
58+
if(Exceptions.ErrorOccurred())
59+
{
60+
thrownewPythonException();
61+
}
6562

66-
IntPtrnext=Runtime.PyIter_Next(obj);
67-
if(next==IntPtr.Zero)
68-
{
63+
// stop holding the previous object, if there was one
64+
_current=null;
6965
returnfalse;
7066
}
7167

72-
_current=newPyObject(next);
68+
_current=next.MoveToPyObject();
7369
returntrue;
7470
}
7571

7672
publicvoidReset()
7773
{
78-
//Not supported in python.
74+
thrownewNotSupportedException();
7975
}
8076

81-
publicobjectCurrent
82-
{
83-
get{return_current;}
84-
}
77+
publicPyObjectCurrent=>_current;
78+
objectSystem.Collections.IEnumerator.Current=>_current;
8579
}
8680
}

‎src/runtime/pyobject.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace Python.Runtime
1616
/// for details.
1717
/// </summary>
1818
[Serializable]
19-
publicpartialclassPyObject:DynamicObject,IEnumerable,IDisposable
19+
publicpartialclassPyObject:DynamicObject,IEnumerable<PyObject>,IDisposable
2020
{
2121
#ifTRACE_ALLOC
2222
/// <summary>
@@ -705,10 +705,11 @@ public PyObject GetIterator()
705705
/// python object to be iterated over in C#. A PythonException will be
706706
/// raised if the object is not iterable.
707707
/// </remarks>
708-
publicIEnumeratorGetEnumerator()
708+
publicIEnumerator<PyObject>GetEnumerator()
709709
{
710710
returnPyIter.GetIter(this);
711711
}
712+
IEnumeratorIEnumerable.GetEnumerator()=>this.GetEnumerator();
712713

713714

714715
/// <summary>

‎src/runtime/runtime.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,6 +1854,8 @@ internal static bool PyIter_Check(IntPtr pointer)
18541854

18551855
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
18561856
internalstaticextern IntPtr PyIter_Next(IntPtr pointer);
1857+
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
1858+
internalstaticextern NewReference PyIter_Next(BorrowedReference pointer);
18571859

18581860

18591861
//====================================================================

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp