rubypython-raspi 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ module RubyPython
2
+ # Creates a Ruby class that inherits from a proxied Python object.
3
+ def self.Type(name)
4
+ mod, match, klass = name.rpartition(".")
5
+ pymod = RubyPython.import(mod)
6
+ pyclass = pymod.pObject.getAttr(klass)
7
+ rclass = Class.new(RubyPyProxy) do
8
+ define_method(:initialize) do |*args|
9
+ args = PyObject.convert(*args)
10
+ pTuple = PyObject.buildArgTuple(*args)
11
+ pReturn = pyclass.callObject(pTuple)
12
+ if PythonError.error?
13
+ raise PythonError.handle_error
14
+ end
15
+ @pObject = pReturn
16
+ end
17
+ end
18
+ return rclass
19
+ end
20
+ end
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include TestConstants
4
+
5
+ describe "RubyPython" do
6
+ it "can import and use a native extension like cPickle" do
7
+ cPickle = RubyPython.import("cPickle")
8
+ string = cPickle.dumps("Testing RubyPython.")
9
+ string.should_not be_a_kind_of String
10
+ string.rubify.should be_a_kind_of String
11
+ string.rubify.should == "S'Testing RubyPython.'\np1\n."
12
+ end
13
+
14
+ it "can import and use a pure Python extension like pickle" do
15
+ pickle = RubyPython.import("pickle")
16
+ string = pickle.dumps("Testing RubyPython.")
17
+ string.should_not be_a_kind_of String
18
+ string.rubify.should be_a_kind_of String
19
+ string.rubify.should == "S'Testing RubyPython.'\np0\n."
20
+ end
21
+
22
+ it "can use iterators from Python" do
23
+ items = []
24
+ @basics.iterate_list.to_enum.each { |item| items << item }
25
+ items.should == [ 1, 2, 3 ]
26
+ end
27
+
28
+ it "can use Ruby procs as callbacks to Python code" do
29
+ @basics.simple_callback(lambda { |v| v * v }, 4).should == 16
30
+ end
31
+
32
+ it "can use Ruby methods as callbacks to Python code" do
33
+ def triple(v)
34
+ v * 3
35
+ end
36
+ @basics.simple_callback(method(:triple), 4).should == 12
37
+ end
38
+
39
+ it "can feed a Python generator in Ruby 1.9", :ruby_version => '1.9' do
40
+ output = @basics.simple_generator(RubyPython.generator do
41
+ (1..10).each { |i| RubyPython.yield i }
42
+ end)
43
+ output.should == [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
44
+ end
45
+
46
+ it "can use named parameters to functions" do
47
+ @basics.named_args(2, 1).should == [ 2, 1 ]
48
+ @basics.named_args!(:arg2 => 2, :arg1 => 1).should == [ 1, 2 ]
49
+ end
50
+ end
@@ -0,0 +1,53 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include TestConstants
4
+
5
+ describe 'Callbacks' do
6
+ {
7
+ 'procs' => AProc,
8
+ 'methods' => AMethod,
9
+ }.each do |rb_type, rb_object|
10
+ it "accepts #{rb_type} as functions" do
11
+ [
12
+ [2, 2],
13
+ ["a", "Word"],
14
+ [ [1, 2], [3, 4] ]
15
+ ].each do |args|
16
+ @objects.apply_callback(rb_object, args).should == rb_object.call(*args)
17
+ end
18
+ end
19
+ end
20
+
21
+ [
22
+ ["an int", AnInt],
23
+ ["a float", AFloat],
24
+ ["a string", AString],
25
+ ["a string with nulls", AStringWithNULLs],
26
+ ["an array", AnArray],
27
+ ["an array", AnArray],
28
+ ["a hash", AConvertedHash],
29
+ ["true", true],
30
+ ["false", false],
31
+ ["nil", nil]
32
+ ].each do |rb_type, rb_value|
33
+ it "is able to return #{rb_type}" do
34
+ callback = Proc.new do
35
+ rb_value
36
+ end
37
+
38
+ @objects.apply_callback(callback, []).should == rb_value
39
+ end
40
+ end
41
+
42
+ it "is able to be stored by python variables" do
43
+ mockObject = @objects.RubyPythonMockObject.new
44
+ mockObject.callback = AProc
45
+ end
46
+
47
+ it "is callable as a python instance variable" do
48
+ mockObject = @objects.RubyPythonMockObject.new
49
+ mockObject.callback = AProc
50
+ mockObject.callback(2, 2).rubify.should == 4
51
+ end
52
+
53
+ end
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include TestConstants
4
+
5
+ describe RubyPython::Conversion do
6
+ subject { RubyPython::Conversion }
7
+
8
+ context "when converting from Python to Ruby" do
9
+ [
10
+ ["an int", "an int", AnInt],
11
+ ["a float", "a float", AFloat],
12
+ ["a string", "a string", AString],
13
+ ["a string_with_nulls", "a string_with_nulls", AStringWithNULLs],
14
+ ["a list", "an array", AnArray],
15
+ ["a tuple", "a tuple", ATuple],
16
+ ["a dict", "a hash", AConvertedHash],
17
+ ["python True", "true", true],
18
+ ["python False", "false", false],
19
+ ["python None", "nil", nil]
20
+ ].each do |py_type, rb_type, output|
21
+ it "should convert #{py_type} to #{rb_type}" do
22
+ py_object_ptr = @objects.__send__(py_type.sub(' ', '_')).pObject.pointer
23
+ obj = subject.ptorObject(py_object_ptr)
24
+ obj.should == output
25
+ obj.class.should == output.class
26
+ end
27
+ end
28
+
29
+ it "should return an FFI::Pointer when it cannot convert" do
30
+ unconvertable = @objects.RubyPythonMockObject.pObject.pointer
31
+ subject.ptorObject(unconvertable).should be_a_kind_of(FFI::Pointer)
32
+ end
33
+ end
34
+
35
+ context "when converting Ruby to Python" do
36
+ [
37
+ ["an int", "an int", AnInt],
38
+ ["a float", "a float", AFloat],
39
+ ["a string", "a string", AString],
40
+ ["a string_with_nulls", "a string_with_nulls", AStringWithNULLs],
41
+ ["a string", "a symbol", ASym],
42
+ ["a list", "an array", AnArray],
43
+ ["a tuple", "a tuple", ATuple ],
44
+ ["a dict", "a hash", AConvertedHash],
45
+ ["python True", "true", true],
46
+ ["python False", "false", false],
47
+ ["python None", "nil", nil],
48
+ ["a function", "a proc", AProc, true]
49
+ ].each do |py_type, rb_type, input, no_compare|
50
+ it "should convert #{rb_type} to #{py_type}" do
51
+ py_object_ptr = subject.rtopObject(input)
52
+ unless no_compare
53
+ output = @objects.__send__(rb_type.sub(' ', '_')).pObject.pointer
54
+ RubyPython::Python.PyObject_Compare(py_object_ptr, output).should == 0
55
+ end
56
+ end
57
+ end
58
+
59
+ it "should raise an exception when it cannot convert" do
60
+ lambda { subject.rtopObject(Class) }.should raise_exception(subject::UnsupportedConversion)
61
+ end
62
+
63
+ it "should convert a tuple correctly" do
64
+ @basics.expects_tuple(AnArray).should == false
65
+ @basics.expects_tuple(RubyPython::Tuple.tuple(AnArray)).should == true
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include TestConstants
4
+
5
+ describe 'RubyPython Legacy Mode Module' do
6
+ before :all do
7
+ require 'rubypython/legacy'
8
+ end
9
+
10
+ after :all do
11
+ RubyPython::LegacyMode.teardown_legacy
12
+ end
13
+
14
+ describe "when required" do
15
+ it "should enable legacy mode" do
16
+ RubyPython.legacy_mode.should == true
17
+ end
18
+
19
+ [
20
+ ["an int", "an int", AnInt],
21
+ ["a float", "a float", AFloat],
22
+ ["a string", "a string", AString],
23
+ ["a list", "an array", AnArray],
24
+ ["a tuple", "an array", AnArray],
25
+ ["a dict", "a hash", AConvertedHash],
26
+ ["python True", "true", true],
27
+ ["python False", "false", false],
28
+ ["python None", "nil", nil]
29
+ ].each do |py_type, rb_type, output|
30
+ it "implicitly converts #{py_type} to #{rb_type}" do
31
+ @objects.__send__(py_type.sub(' ', '_')).should == output
32
+ end
33
+ end
34
+
35
+ [
36
+ ["proc", AProc],
37
+ ["method", AMethod]
38
+ ].each do |rb_type, rb_obj|
39
+ it "raises an exception if a #{rb_type} callback is supplied" do
40
+ lambda do
41
+ @objects.apply_callback(rb_obj, [1, 1])
42
+ end.should raise_exception(RubyPython::Conversion::UnsupportedConversion)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include TestConstants
4
+
5
+ describe RubyPython::PyMainClass do
6
+ subject { RubyPython::PyMain }
7
+
8
+ it "should delegate to builtins" do
9
+ subject.float(AnInt).rubify.should == AnInt.to_f
10
+ end
11
+
12
+ it "should handle block syntax" do
13
+ subject.float(AnInt) {|f| f.rubify*2}.should == (AnInt.to_f * 2)
14
+ end
15
+
16
+ it "should allow attribute access" do
17
+ subject.main.__name__.rubify.should == '__main__'
18
+ end
19
+
20
+ it "should allow global variable setting" do
21
+ subject.x = 2
22
+ subject.x.rubify.should == 2
23
+ end
24
+ end
@@ -0,0 +1,246 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include TestConstants
4
+
5
+ describe RubyPython::PyObject do
6
+ before do
7
+ @string = RubyPython.import('string').pObject
8
+ @urllib2 = RubyPython.import('urllib2').pObject
9
+ @builtin = RubyPython.import("__builtin__")
10
+ sys = RubyPython.import 'sys'
11
+ sys.path.append './spec/python_helpers/'
12
+ @objects = RubyPython.import('objects')
13
+ end
14
+
15
+ describe ".new" do
16
+ [
17
+ ["a string", AString],
18
+ ["an int", AnInt],
19
+ ["a float", AFloat],
20
+ ["an array", AnArray],
21
+ ["a symbol", ASym],
22
+ ["a hash", AHash]
23
+ ].each do |title, obj|
24
+ it "should wrap #{title}" do
25
+ lambda { described_class.new(obj) }.should_not raise_exception
26
+ end
27
+ end
28
+
29
+ [
30
+ "a string",
31
+ "an int",
32
+ "a list",
33
+ "a dict",
34
+ "a tuple"
35
+ ].each do |title|
36
+ it "should take #{title} from a Python pointer" do
37
+ lambda do
38
+ py_obj = @objects.__send__(title.gsub(' ','_')).pObject.pointer
39
+ described_class.new(py_obj)
40
+ end.should_not raise_exception
41
+ end
42
+ end
43
+ end #new
44
+
45
+ describe "#rubify" do
46
+ [
47
+ ["a string", AString],
48
+ ["an int", AnInt],
49
+ ["a float", AFloat],
50
+ ["an array", AnArray],
51
+ ["a symbol", ASym, ASym.to_s],
52
+ ["a hash", AHash, AConvertedHash]
53
+ ].each do |arr|
54
+ type, input, output = arr
55
+ output ||= input
56
+
57
+ it "should faithfully unwrap #{type}" do
58
+ described_class.new(input).rubify.should == output
59
+ end
60
+ end
61
+ end #rubify
62
+
63
+ describe "#hasAttr" do
64
+ it "should return true when object has the requested attribute" do
65
+ @string.hasAttr("ascii_letters").should be_true
66
+ end
67
+
68
+ it "should return false when object does not have the requested attribute" do
69
+ @string.hasAttr("nonExistentThing").should be_false
70
+ end
71
+ end
72
+
73
+ describe "#getAttr" do
74
+ it "should fetch requested object attribute" do
75
+ ascii_letters = @string.getAttr "ascii_letters"
76
+ ascii_letters.rubify.should == "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
77
+ end
78
+
79
+ it "should return a PyObject instance" do
80
+ ascii_letters = @string.getAttr "ascii_letters"
81
+ ascii_letters.should be_kind_of(described_class)
82
+ end
83
+ end
84
+
85
+ describe "#setAttr" do
86
+ it "should modify the specified attribute of the object" do
87
+ pyNewLetters = described_class.new "RbPy"
88
+ @string.setAttr "ascii_letters", pyNewLetters
89
+ @string.getAttr("ascii_letters").rubify.should == pyNewLetters.rubify
90
+ end
91
+
92
+ it "should create the requested attribute if it doesn't exist" do
93
+ pyNewString = described_class.new "python"
94
+ @string.setAttr "ruby", pyNewString
95
+ @string.getAttr("ruby").rubify.should == pyNewString.rubify
96
+ end
97
+ end
98
+
99
+ describe "#cmp" do
100
+ before do
101
+ @less = described_class.new 5
102
+ @greater = described_class.new 10
103
+ @less_dup = described_class.new 5
104
+ end
105
+
106
+ it "should return 0 when objects are equal" do
107
+ @less.cmp(@less_dup).should == 0
108
+ end
109
+
110
+ it "should change sign under interchange of arguments" do
111
+ @less.cmp(@greater).should == -@greater.cmp(@less)
112
+ end
113
+
114
+ it "should return -1 when first object is less than the second" do
115
+ @less.cmp(@greater).should == -1
116
+ end
117
+
118
+ it "should return 1 when first object is greater than the second" do
119
+ @greater.cmp(@less).should == 1
120
+ end
121
+ end
122
+
123
+ describe "#makeTuple" do
124
+ it "should wrap single arguments in a tuple" do
125
+ arg = described_class.new AString
126
+ described_class.makeTuple(arg).rubify.should == [AString]
127
+ end
128
+
129
+ it "should turn a Python list into a tuple" do
130
+ arg = @objects.a_list.pObject
131
+ converted = described_class.makeTuple(arg)
132
+ converted.rubify.should == AnArray
133
+ end
134
+
135
+ it "should return the given argument if it is a tuple" do
136
+ arg = @objects.a_tuple.pObject
137
+ converted = described_class.makeTuple(arg)
138
+ converted.pointer.address.should == arg.pointer.address
139
+ end
140
+ end
141
+
142
+ describe "#callObject" do
143
+ #Expand coverage types
144
+ it "should execute wrapped object with supplied arguments" do
145
+ arg = described_class.new AnInt
146
+ argt = described_class.buildArgTuple arg
147
+
148
+ builtin = @builtin.pObject
149
+ stringClass = builtin.getAttr "str"
150
+ stringClass.callObject(argt).rubify.should == AnInt.to_s
151
+ end
152
+ end
153
+
154
+ describe "#newList" do
155
+ it "should wrap supplied args in a Python list" do
156
+ args = AnArray.map do |obj|
157
+ described_class.new obj
158
+ end
159
+ described_class.newList(*args).rubify.should == AnArray
160
+ end
161
+ end
162
+
163
+ describe "#function_or_method?" do
164
+ it "should be true given a method" do
165
+ mockObjClass = @objects.RubyPythonMockObject.pObject
166
+ mockObjClass.getAttr('square_elements').should be_a_function_or_method
167
+ end
168
+
169
+ it "should be true given a function" do
170
+ @objects.pObject.getAttr('identity').should be_a_function_or_method
171
+ end
172
+
173
+ it "should return true given a builtin function" do
174
+ any = @builtin.pObject.getAttr('any')
175
+ any.should be_a_function_or_method
176
+ end
177
+
178
+ it "should return false given a class" do
179
+ @objects.RubyPythonMockObject.pObject.should_not be_a_function_or_method
180
+ end
181
+ end
182
+
183
+ describe "#class?" do
184
+ it "should return true if wrapped object is an old style class" do
185
+ @objects.RubyPythonMockObject.pObject.should be_a_class
186
+ end
187
+
188
+ it "should return true if wrapped object is an new style class" do
189
+ @objects.NewStyleClass.pObject.should be_a_class
190
+ end
191
+
192
+ it "should return true if wrapped object is a builtin class" do
193
+ strClass = @builtin.pObject.getAttr('str')
194
+ strClass.should be_a_class
195
+ end
196
+
197
+ it "should return false given an object instance" do
198
+ @objects.RubyPythonMockObject.new.pObject.should_not be_a_class
199
+ end
200
+ end
201
+
202
+ describe "#callable?" do
203
+ it "should be true given a method" do
204
+ mockObjClass = @objects.RubyPythonMockObject.pObject
205
+ mockObjClass.getAttr('square_elements').should be_callable
206
+ end
207
+
208
+ it "should be true given a function" do
209
+ @objects.pObject.getAttr('identity').should be_callable
210
+ end
211
+
212
+ it "should return true given a builtin function" do
213
+ any = @builtin.pObject.getAttr('any')
214
+ any.should be_callable
215
+ end
216
+
217
+ it "should return true given a class" do
218
+ @objects.RubyPythonMockObject.pObject.should be_callable
219
+ end
220
+
221
+ it "should return false given a non-callable instance" do
222
+ @objects.RubyPythonMockObject.new.pObject.should_not be_callable
223
+ end
224
+
225
+ specify { described_class.new(6).should_not be_callable }
226
+
227
+ end
228
+
229
+ describe ".convert" do
230
+ it "should not modify PyObjects passed to it" do
231
+ args = AnArray.map { |x| described_class.new(x) }
232
+ described_class.convert(*args).should == args
233
+ end
234
+
235
+ it "should pull PyObjects out of RubyPyProxy instances" do
236
+ args = @objects.an_array.to_a
237
+ described_class.convert(*args).should == args.map {|x| x.pObject}
238
+ end
239
+
240
+ it "should create new PyObject instances of simple Ruby types" do
241
+ described_class.convert(*AnArray).each do |x|
242
+ x.should be_a_kind_of described_class
243
+ end
244
+ end
245
+ end
246
+ end