File tree Expand file tree Collapse file tree 5 files changed +58
-22
lines changed Expand file tree Collapse file tree 5 files changed +58
-22
lines changed Original file line number Diff line number Diff line change @@ -26,6 +26,7 @@ details about the cause of the failure
26
26
- BREAKING: Parameters marked with ` ParameterAttributes.Out ` are no longer returned in addition
27
27
to the regular method return value (unless they are passed with ` ref ` or ` out ` keyword).
28
28
- BREAKING: Drop support for the long-deprecated CLR.* prefix.
29
+ - ` PyObject ` now implements ` IEnumerable<PyObject> ` in addition to ` IEnumerable `
29
30
30
31
### Fixed
31
32
@@ -40,6 +41,7 @@ details about the cause of the failure
40
41
- Fixed a bug where indexers could not be used if they were inherited
41
42
- Made it possible to use ` __len__ ` also on ` ICollection<> ` interface objects
42
43
- Made it possible to call ` ToString ` , ` GetHashCode ` , and ` GetType ` on inteface objects
44
+ - Fixed objects returned by enumerating ` PyObject ` being disposed too soon
43
45
44
46
### Removed
45
47
Original file line number Diff line number Diff line change
1
+ using System . Linq ;
2
+ using System . Text ;
3
+
4
+ using NUnit . Framework ;
5
+
6
+ using Python . Runtime ;
7
+
8
+ namespace Python . EmbeddingTest
9
+ {
10
+ class TestPyIter
11
+ {
12
+ [ OneTimeSetUp ]
13
+ public void SetUp ( )
14
+ {
15
+ PythonEngine . Initialize ( ) ;
16
+ }
17
+
18
+ [ OneTimeTearDown ]
19
+ public void Dispose ( )
20
+ {
21
+ PythonEngine . Shutdown ( ) ;
22
+ }
23
+
24
+ [ Test ]
25
+ public void KeepOldObjects ( )
26
+ {
27
+ using ( Py . GIL ( ) )
28
+ using ( var testString = new PyString ( "hello world! !$%&/()=?" ) )
29
+ {
30
+ PyObject [ ] chars = testString . ToArray ( ) ;
31
+ Assert . IsTrue ( chars . Length > 1 ) ;
32
+ string reconstructed = string . Concat ( chars . Select ( c => c . As < string > ( ) ) ) ;
33
+ Assert . AreEqual ( testString . As < string > ( ) , reconstructed ) ;
34
+ }
35
+ }
36
+ }
37
+ }
Original file line number Diff line number Diff line change @@ -9,7 +9,7 @@ namespace Python.Runtime
9
9
/// PY3: https://docs.python.org/3/c-api/iterator.html
10
10
/// for details.
11
11
/// </summary>
12
- public class PyIter : PyObject , IEnumerator < object >
12
+ public class PyIter : PyObject , IEnumerator < PyObject >
13
13
{
14
14
private PyObject _current ;
15
15
@@ -46,41 +46,35 @@ public static PyIter GetIter(PyObject iterable)
46
46
47
47
protected override void Dispose ( bool disposing )
48
48
{
49
- if ( null != _current )
50
- {
51
- _current . Dispose ( ) ;
52
- _current = null ;
53
- }
49
+ _current = null ;
54
50
base . Dispose ( disposing ) ;
55
51
}
56
52
57
53
public bool MoveNext ( )
58
54
{
59
- // dispose of the previous object, if there was one
60
- if ( null != _current )
55
+ NewReference next = Runtime . PyIter_Next ( Reference ) ;
56
+ if ( next . IsNull ( ) )
61
57
{
62
- _current . Dispose ( ) ;
63
- _current = null ;
64
- }
58
+ if ( Exceptions . ErrorOccurred ( ) )
59
+ {
60
+ throw new PythonException ( ) ;
61
+ }
65
62
66
- IntPtr next = Runtime . PyIter_Next ( obj ) ;
67
- if ( next == IntPtr . Zero )
68
- {
63
+ // stop holding the previous object, if there was one
64
+ _current = null ;
69
65
return false ;
70
66
}
71
67
72
- _current = new PyObject ( next ) ;
68
+ _current = next . MoveToPyObject ( ) ;
73
69
return true ;
74
70
}
75
71
76
72
public void Reset ( )
77
73
{
78
- //Not supported in python.
74
+ throw new NotSupportedException ( ) ;
79
75
}
80
76
81
- public object Current
82
- {
83
- get { return _current ; }
84
- }
77
+ public PyObject Current => _current ;
78
+ object System . Collections . IEnumerator . Current => _current ;
85
79
}
86
80
}
Original file line number Diff line number Diff line change @@ -16,7 +16,7 @@ namespace Python.Runtime
16
16
/// for details.
17
17
/// </summary>
18
18
[ Serializable ]
19
- public partial class PyObject : DynamicObject , IEnumerable , IDisposable
19
+ public partial class PyObject : DynamicObject , IEnumerable < PyObject > , IDisposable
20
20
{
21
21
#if TRACE_ALLOC
22
22
/// <summary>
@@ -705,10 +705,11 @@ public PyObject GetIterator()
705
705
/// python object to be iterated over in C#. A PythonException will be
706
706
/// raised if the object is not iterable.
707
707
/// </remarks>
708
- public IEnumerator GetEnumerator ( )
708
+ public IEnumerator < PyObject > GetEnumerator ( )
709
709
{
710
710
return PyIter . GetIter ( this ) ;
711
711
}
712
+ IEnumerator IEnumerable . GetEnumerator ( ) => this . GetEnumerator ( ) ;
712
713
713
714
714
715
/// <summary>
Original file line number Diff line number Diff line change @@ -1854,6 +1854,8 @@ internal static bool PyIter_Check(IntPtr pointer)
1854
1854
1855
1855
[ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl) ]
1856
1856
internal static extern IntPtr PyIter_Next( IntPtr pointer) ;
1857
+ [ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl) ]
1858
+ internal static extern NewReference PyIter_Next( BorrowedReference pointer) ;
1857
1859
1858
1860
1859
1861
//====================================================================
You can’t perform that action at this time.
0 commit comments