File tree Expand file tree Collapse file tree 6 files changed +76
-0
lines changed Expand file tree Collapse file tree 6 files changed +76
-0
lines changed Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ module PyCall
5
5
require 'pycall/pyobject_wrapper'
6
6
require 'pycall/pytypeobject_wrapper'
7
7
require 'pycall/pymodule_wrapper'
8
+ require 'pycall/iterable_wrapper'
8
9
require 'pycall/init'
9
10
10
11
module_function
@@ -73,6 +74,10 @@ def import_module(name)
73
74
LibPython ::Helpers . import_module ( name )
74
75
end
75
76
77
+ def iterable ( obj )
78
+ IterableWrapper . new ( obj )
79
+ end
80
+
76
81
def len ( obj )
77
82
case obj
78
83
when PyObjectWrapper
Original file line number Diff line number Diff line change
1
+ module PyCall
2
+ class IterableWrapper
3
+ include Enumerable
4
+
5
+ def initialize ( obj )
6
+ @obj = check_iterable ( obj )
7
+ end
8
+
9
+ private def check_iterable ( obj )
10
+ unless PyCall . hasattr? ( obj , :__iter__ )
11
+ raise ArgumentError , "%p object is not iterable" % obj
12
+ end
13
+ obj
14
+ end
15
+
16
+ def each
17
+ return enum_for ( __method__ ) unless block_given?
18
+ iter = @obj . __iter__ ( )
19
+ while true
20
+ begin
21
+ yield iter . __next__ ( )
22
+ rescue PyCall ::PyError => err
23
+ if err . type == PyCall . builtins . StopIteration
24
+ break
25
+ else
26
+ raise err
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
Original file line number Diff line number Diff line change 1
1
require "pycall"
2
+ require "pathname"
2
3
require "test-unit"
4
+
5
+ test_dir = Pathname . new ( __dir__ )
6
+ python_dir = test_dir + "python"
7
+
8
+ PyCall . sys . path . append ( python_dir . to_s )
Original file line number Diff line number Diff line change
1
+ class IntGenerator (object ):
2
+ def __init__ (self , start , stop ):
3
+ self .start = start
4
+ self .stop = stop
5
+ self .current = None
6
+
7
+ def __iter__ (self ):
8
+ self .current = self .start
9
+ return self
10
+
11
+ def __next__ (self ):
12
+ if self .current == self .stop :
13
+ raise StopIteration ()
14
+ value = self .current
15
+ self .current += 1
16
+ return value
17
+
18
+ if __name__ == "__main__" :
19
+ print (list (IntGenerator (105 , 115 )))
Original file line number Diff line number Diff line change @@ -2,4 +2,18 @@ class PyCallTest < Test::Unit::TestCase
2
2
def test_VERSION
3
3
assert_not_nil ( PyCall ::VERSION )
4
4
end
5
+
6
+ def test_iterable
7
+ simple_iterable = PyCall . import_module ( "pycall.simple_iterable" )
8
+ int_gen = simple_iterable . IntGenerator . new ( 10 , 25 )
9
+ iterable = PyCall . iterable ( int_gen )
10
+ assert_equal ( {
11
+ enumerable_p : true ,
12
+ each_to_a : ( 10 .. 24 ) . to_a ,
13
+ } ,
14
+ {
15
+ enumerable_p : iterable . is_a? ( Enumerable ) ,
16
+ each_to_a : iterable . each . to_a
17
+ } )
18
+ end
5
19
end
You can’t perform that action at this time.
0 commit comments