rubypython 0.2.11 → 0.3.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.
Files changed (72) hide show
  1. data.tar.gz.sig +0 -0
  2. data/{History.txt → History.markdown} +34 -28
  3. data/Manifest.txt +26 -40
  4. data/PostInstall.txt +2 -1
  5. data/README.markdown +103 -0
  6. data/Rakefile +19 -3
  7. data/lib/rubypython.rb +118 -114
  8. data/lib/rubypython/blankobject.rb +21 -0
  9. data/lib/rubypython/conversion.rb +198 -0
  10. data/lib/rubypython/core_ext/string.rb +7 -0
  11. data/lib/rubypython/legacy.rb +15 -0
  12. data/lib/rubypython/macros.rb +47 -0
  13. data/lib/rubypython/operators.rb +111 -0
  14. data/lib/rubypython/pymainclass.rb +51 -0
  15. data/lib/rubypython/pyobject.rb +203 -0
  16. data/lib/rubypython/python.rb +111 -0
  17. data/lib/rubypython/pythonerror.rb +78 -0
  18. data/lib/rubypython/rubypyproxy.rb +214 -0
  19. data/lib/rubypython/version.rb +4 -3
  20. data/spec/conversion_spec.rb +66 -0
  21. data/spec/legacy_spec.rb +22 -0
  22. data/spec/pymainclass_spec.rb +26 -0
  23. data/spec/pyobject_spec.rb +264 -0
  24. data/spec/python_helpers/objects.py +41 -0
  25. data/spec/pythonerror_spec.rb +43 -0
  26. data/spec/refcnt_spec.rb +68 -0
  27. data/spec/rubypyclass_spec.rb +13 -0
  28. data/spec/rubypyproxy_spec.rb +249 -0
  29. data/spec/rubypython_spec.rb +62 -0
  30. data/spec/spec.opts +2 -0
  31. data/spec/spec_helper.rb +51 -0
  32. metadata +79 -73
  33. metadata.gz.sig +0 -0
  34. data/README.txt +0 -60
  35. data/ext/rubypython_bridge/cbridge.c +0 -150
  36. data/ext/rubypython_bridge/cbridge.h +0 -15
  37. data/ext/rubypython_bridge/config.h +0 -14
  38. data/ext/rubypython_bridge/extconf.rb +0 -43
  39. data/ext/rubypython_bridge/ptor.c +0 -242
  40. data/ext/rubypython_bridge/ptor.h +0 -15
  41. data/ext/rubypython_bridge/rp_blankobject.c +0 -42
  42. data/ext/rubypython_bridge/rp_blankobject.h +0 -11
  43. data/ext/rubypython_bridge/rp_class.c +0 -56
  44. data/ext/rubypython_bridge/rp_class.h +0 -7
  45. data/ext/rubypython_bridge/rp_error.c +0 -34
  46. data/ext/rubypython_bridge/rp_error.h +0 -11
  47. data/ext/rubypython_bridge/rp_function.c +0 -31
  48. data/ext/rubypython_bridge/rp_function.h +0 -7
  49. data/ext/rubypython_bridge/rp_instance.c +0 -164
  50. data/ext/rubypython_bridge/rp_instance.h +0 -7
  51. data/ext/rubypython_bridge/rp_module.c +0 -160
  52. data/ext/rubypython_bridge/rp_module.h +0 -8
  53. data/ext/rubypython_bridge/rp_object.c +0 -194
  54. data/ext/rubypython_bridge/rp_object.h +0 -23
  55. data/ext/rubypython_bridge/rp_util.c +0 -63
  56. data/ext/rubypython_bridge/rp_util.h +0 -11
  57. data/ext/rubypython_bridge/rtop.c +0 -212
  58. data/ext/rubypython_bridge/rtop.h +0 -17
  59. data/ext/rubypython_bridge/rubypython_bridge.c +0 -125
  60. data/ext/rubypython_bridge/rubypython_bridge.h +0 -10
  61. data/lib/rubypython/session.rb +0 -4
  62. data/lib/rubypython/wrapper_extensions.rb +0 -83
  63. data/setup.rb +0 -1585
  64. data/tasks/environment.rake +0 -7
  65. data/tasks/extconf.rake +0 -13
  66. data/tasks/extconf/rubypython_bridge.rake +0 -49
  67. data/test/python_helpers/objects.py +0 -12
  68. data/test/test.wav +0 -0
  69. data/test/test_helper.rb +0 -2
  70. data/test/test_rubypython.rb +0 -215
  71. data/test/test_rubypython_bridge_extn.rb +0 -133
  72. data/test/test_session.rb +0 -6
@@ -1,8 +1,9 @@
1
1
  module RubyPython
2
- module VERSION #:nodoc:
2
+ #Just a simple way to keep track of the gem version.
3
+ module VERSION
3
4
  MAJOR = 0
4
- MINOR = 2
5
- TINY = 11
5
+ MINOR = 3
6
+ TINY = 0
6
7
 
7
8
  STRING = [MAJOR, MINOR, TINY].join('.')
8
9
  end
@@ -0,0 +1,66 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include TestConstants
4
+ describe RubyPython::Conversion do
5
+ include RubyPythonStartStop
6
+
7
+ subject { RubyPython::Conversion }
8
+
9
+ before do
10
+ sys = RubyPython.import 'sys'
11
+ sys.path.append './spec/python_helpers'
12
+ @objects = RubyPython.import 'objects'
13
+ end
14
+
15
+ context "when converting from Python to Ruby" do
16
+ [
17
+ ["an int", "an int", AnInt],
18
+ ["a float", "a float", AFloat],
19
+ ["a string", "a string", AString],
20
+ ["a list", "an array", AnArray],
21
+ ["a tuple", "an array", AnArray],
22
+ ["a dict", "a hash", AConvertedHash],
23
+ ["python True", "true", true],
24
+ ["python False", "false", false],
25
+ ["python None", "nil", nil]
26
+ ].each do |py_type, rb_type, output|
27
+ it "should convert #{py_type} to #{rb_type}" do
28
+ py_object_ptr = @objects.__send__(py_type.sub(' ', '_')).pObject.pointer
29
+ subject.ptorObject(py_object_ptr).should == output
30
+ end
31
+ end
32
+
33
+ it "should return an FFI::Pointer when it cannot convert" do
34
+ unconvertable = @objects.RubyPythonMockObject.pObject.pointer
35
+ subject.ptorObject(unconvertable).should be_a_kind_of(FFI::Pointer)
36
+ end
37
+ end
38
+
39
+
40
+ context "when converting Ruby to Python" do
41
+ [
42
+ ["an int", "an int", AnInt],
43
+ ["a float", "a float", AFloat],
44
+ ["a string", "a string", AString],
45
+ ["a string", "a symbol", ASym],
46
+ ["a list", "an array", AnArray],
47
+ ["a dict", "a hash", AConvertedHash],
48
+ ["python True", "true", true],
49
+ ["python False", "false", false],
50
+ ["python None", "nil", nil]
51
+ ].each do |py_type, rb_type, input|
52
+
53
+ it "should convert #{rb_type} to #{py_type}" do
54
+ py_object_ptr = subject.rtopObject(input)
55
+ output = @objects.__send__(rb_type.sub(' ', '_')).pObject.pointer
56
+ RubyPython::Python.PyObject_Compare(py_object_ptr, output).should == 0
57
+ end
58
+ end
59
+
60
+ it "should raise an exception when it cannot convert" do
61
+ lambda { subject.rtopObject(Class) }.should raise_exception(subject::UnsupportedConversion)
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include TestConstants
4
+
5
+ describe 'RubyPython Legacy Mode Module' do
6
+ include RubyPythonStartStop
7
+
8
+ before :all do
9
+ require 'rubypython/legacy'
10
+ end
11
+
12
+ after :all do
13
+ RubyPython::LegacyMode.teardown_legacy
14
+ end
15
+
16
+ describe "when required" do
17
+ it "should enable legacy mode" do
18
+ RubyPython.legacy_mode.should == true
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe RubyPython::PyMainClass do
4
+ include TestConstants
5
+ include RubyPythonStartStop
6
+
7
+ subject { RubyPython::PyMain }
8
+
9
+ it "should delegate to builtins" do
10
+ subject.float(AnInt).rubify.should == AnInt.to_f
11
+ end
12
+
13
+ it "should handle block syntax" do
14
+ subject.float(AnInt) {|f| f.rubify*2}.should == (AnInt.to_f * 2)
15
+ end
16
+
17
+ it "should allow attribute access" do
18
+ subject.main.__name__.rubify.should == '__main__'
19
+ end
20
+
21
+ it "should allow global variable setting" do
22
+ subject.x = 2
23
+ subject.x.rubify.should == 2
24
+ end
25
+
26
+ end
@@ -0,0 +1,264 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe RubyPython::PyObject do
4
+ include RubyPythonStartStop
5
+ include TestConstants
6
+
7
+ before do
8
+ @string = RubyPython.import('string').pObject
9
+ @urllib2 = RubyPython.import('urllib2').pObject
10
+ @builtin = RubyPython.import("__builtin__")
11
+ sys = RubyPython.import 'sys'
12
+ sys.path.append './spec/python_helpers/'
13
+ @objects = RubyPython.import('objects')
14
+ end
15
+
16
+ describe ".new" do
17
+ [
18
+ ["a string", AString],
19
+ ["an int", AnInt],
20
+ ["a float", AFloat],
21
+ ["an array", AnArray],
22
+ ["a symbol", ASym],
23
+ ["a hash", AHash]
24
+ ].each do |title, obj|
25
+
26
+ it "should wrap #{title}" do
27
+ lambda { described_class.new(obj) }.should_not raise_exception
28
+ end
29
+ end
30
+
31
+ [
32
+ "a string",
33
+ "an int",
34
+ "a list",
35
+ "a dict",
36
+ "a tuple"
37
+ ].each do |title|
38
+ it "should take #{title} from a Python pointer" do
39
+ lambda do
40
+ py_obj = @objects.__send__(title.gsub(' ','_')).pObject.pointer
41
+ described_class.new(py_obj)
42
+ end.should_not raise_exception
43
+ end
44
+ end
45
+
46
+
47
+ end #new
48
+
49
+ describe "#rubify" do
50
+
51
+ [
52
+ ["a string", AString],
53
+ ["an int", AnInt],
54
+ ["a float", AFloat],
55
+ ["an array", AnArray],
56
+ ["a symbol", ASym, ASym.to_s],
57
+ ["a hash", AHash, AConvertedHash]
58
+ ].each do |arr|
59
+ type, input, output = arr
60
+ output ||= input
61
+
62
+ it "should faithfully unwrap #{type}" do
63
+ described_class.new(input).rubify.should == output
64
+ end
65
+
66
+ end
67
+
68
+ end #rubify
69
+
70
+ describe "#hasAttr" do
71
+ it "should return true when object has the requested attribute" do
72
+ @string.hasAttr("ascii_letters").should be_true
73
+ end
74
+
75
+ it "should return false when object does not have the requested attribute" do
76
+ @string.hasAttr("nonExistentThing").should be_false
77
+ end
78
+ end
79
+
80
+ describe "#getAttr" do
81
+ it "should fetch requested object attribute" do
82
+ ascii_letters = @string.getAttr "ascii_letters"
83
+ ascii_letters.rubify.should == "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
84
+ end
85
+
86
+ it "should return a PyObject instance" do
87
+ ascii_letters = @string.getAttr "ascii_letters"
88
+ ascii_letters.should be_kind_of(described_class)
89
+ end
90
+ end
91
+
92
+ describe "#setAttr" do
93
+ it "should modify the specified attribute of the object" do
94
+ pyNewLetters = described_class.new "RbPy"
95
+ @string.setAttr "ascii_letters", pyNewLetters
96
+ @string.getAttr("ascii_letters").rubify.should == pyNewLetters.rubify
97
+ end
98
+
99
+ it "should create the requested attribute if it doesn't exist" do
100
+ pyNewString = described_class.new "python"
101
+ @string.setAttr "ruby", pyNewString
102
+ @string.getAttr("ruby").rubify.should == pyNewString.rubify
103
+ end
104
+ end
105
+
106
+ describe "#cmp" do
107
+
108
+ before do
109
+ @less = described_class.new 5
110
+ @greater = described_class.new 10
111
+ @less_dup = described_class.new 5
112
+ end
113
+
114
+ it "should return 0 when objects are equal" do
115
+ @less.cmp(@less_dup).should == 0
116
+ end
117
+
118
+ it "should change sign under interchange of arguments" do
119
+ @less.cmp(@greater).should == -@greater.cmp(@less)
120
+ end
121
+
122
+ it "should return -1 when first object is less than the second" do
123
+ @less.cmp(@greater).should == -1
124
+ end
125
+
126
+ it "should return 1 when first object is greater than the second" do
127
+ @greater.cmp(@less).should == 1
128
+ end
129
+ end
130
+
131
+ describe "#makeTuple" do
132
+ it "should wrap single arguments in a tuple" do
133
+ arg = described_class.new AString
134
+ described_class.makeTuple(arg).rubify.should == [AString]
135
+ end
136
+
137
+ it "should turn a Python list into a tuple" do
138
+ arg = @objects.a_list.pObject
139
+ converted = described_class.makeTuple(arg)
140
+ converted.rubify.should == AnArray
141
+ end
142
+
143
+ it "should return the given argument if it is a tuple" do
144
+ arg = @objects.a_tuple.pObject
145
+ converted = described_class.makeTuple(arg)
146
+ converted.pointer.address.should == arg.pointer.address
147
+ end
148
+
149
+ end
150
+
151
+ describe "#callObject" do
152
+ #Expand coverage types
153
+ it "should execute wrapped object with supplied arguments" do
154
+ arg = described_class.new AnInt
155
+ argt = described_class.buildArgTuple arg
156
+
157
+ builtin = @builtin.pObject
158
+ stringClass = builtin.getAttr "str"
159
+ stringClass.callObject(argt).rubify.should == AnInt.to_s
160
+ end
161
+ end
162
+
163
+ describe "#newList" do
164
+ it "should wrap supplied args in a Python list" do
165
+ args = AnArray.map do |obj|
166
+ described_class.new obj
167
+ end
168
+ described_class.newList(*args).rubify.should == AnArray
169
+ end
170
+ end
171
+
172
+ describe "#function_or_method?" do
173
+
174
+ it "should be true for a method" do
175
+ mockObjClass = @objects.RubyPythonMockObject.pObject
176
+ mockObjClass.getAttr('square_elements').should be_a_function_or_method
177
+ end
178
+
179
+ it "should be true for a function" do
180
+ @objects.pObject.getAttr('identity').should be_a_function_or_method
181
+ end
182
+
183
+ xit "should return true for a builtin function" do
184
+ any = @builtin.pObject.getAttr('any')
185
+ any.should be_a_function_or_method
186
+ end
187
+
188
+ it "should return false for a class" do
189
+ @objects.RubyPythonMockObject.pObject.should_not be_a_function_or_method
190
+ end
191
+
192
+ end
193
+
194
+ describe "#class?" do
195
+
196
+ it "should return true if wrapped object is an old style class" do
197
+ @objects.RubyPythonMockObject.pObject.should be_a_class
198
+ end
199
+
200
+ it "should return true if wrapped object is an new style class" do
201
+ @objects.NewStyleClass.pObject.should be_a_class
202
+ end
203
+
204
+ it "should return true if wrapped object is a builtin class" do
205
+ strClass = @builtin.pObject.getAttr('str')
206
+ strClass.should be_a_class
207
+ end
208
+
209
+ it "should return false for an object instance" do
210
+ @objects.RubyPythonMockObject.new.pObject.should_not be_a_class
211
+ end
212
+
213
+ end
214
+
215
+ describe "#callable?" do
216
+
217
+ it "should be true for a method" do
218
+ mockObjClass = @objects.RubyPythonMockObject.pObject
219
+ mockObjClass.getAttr('square_elements').should be_callable
220
+ end
221
+
222
+ it "should be true for a function" do
223
+ @objects.pObject.getAttr('identity').should be_callable
224
+ end
225
+
226
+ it "should return true for a builtin function" do
227
+ any = @builtin.pObject.getAttr('any')
228
+ any.should be_callable
229
+ end
230
+
231
+ it "should return true for a class" do
232
+ @objects.RubyPythonMockObject.pObject.should be_callable
233
+ end
234
+
235
+ it "should return false for a non-callable instance" do
236
+ @objects.RubyPythonMockObject.new.pObject.should_not be_callable
237
+ end
238
+
239
+ specify { described_class.new(6).should_not be_callable }
240
+
241
+ end
242
+
243
+ describe ".convert" do
244
+
245
+ it "should not modify PyObjects passed to it" do
246
+ args = AnArray.map { |x| described_class.new(x) }
247
+ described_class.convert(*args).should == args
248
+ end
249
+
250
+ it "should pull PyObjects out of RubyPyProxy instances" do
251
+ args = @objects.an_array.to_a
252
+ described_class.convert(*args).should == args.map {|x| x.pObject}
253
+ end
254
+
255
+ it "should create new PyObject instances of simple Ruby types" do
256
+ described_class.convert(*AnArray).each do |x|
257
+ x.should be_a_kind_of described_class
258
+ end
259
+ end
260
+
261
+ end
262
+
263
+ end
264
+
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env python
2
+
3
+ def identity(object):
4
+ return object
5
+
6
+ class RubyPythonMockObject:
7
+ STRING = "STRING"
8
+ STRING_LIST = ["STRING1", "STRING2"]
9
+ INT = 1
10
+ INT_LIST = [1,1]
11
+ FLOAT = 1.0
12
+ FLOAT_LIST = [1.0,1.0]
13
+
14
+ def square_elements(self, aList):
15
+ return [x**2 for x in aList]
16
+
17
+ def sum_elements(self, aList):
18
+ return sum(aList)
19
+
20
+ def __eq__(self, other):
21
+ if type(self) == type(other):
22
+ return True
23
+ else:
24
+ return False
25
+
26
+ class NewStyleClass(object):
27
+ def a_method(self):
28
+ pass
29
+
30
+ an_int = 1
31
+ a_char = 'a'
32
+ a_float = 1.0
33
+ a_symbol = 'sym'
34
+ a_string = "STRING"
35
+ an_array = a_list = [an_int, a_char, a_float, a_string]
36
+ a_hash = a_dict = { an_int: an_int, a_char: a_char, a_symbol: a_float, a_string:
37
+ a_string}
38
+ true = python_True = True
39
+ false = python_False = False
40
+ nil = python_None = None
41
+ a_tuple = tuple(a_list)
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe RubyPython::PythonError do
4
+ include RubyPythonStartStop
5
+
6
+ def cause_error
7
+ RubyPython::Python.PyImport_ImportModule("wat")
8
+ end
9
+
10
+ describe "#error?" do
11
+ it "should return false when no error has occured" do
12
+ described_class.error?.should be_false
13
+ end
14
+
15
+ it "should return true when an error has occured" do
16
+ cause_error
17
+ described_class.error?.should be_true
18
+ end
19
+ end
20
+
21
+ describe "#clear" do
22
+ it "should reset the Python error flag" do
23
+ cause_error
24
+ described_class.clear
25
+ described_class.error?.should be_false
26
+ end
27
+
28
+ it "should not barf when there is no error" do
29
+ lambda {described_class.clear}.should_not raise_exception
30
+ end
31
+ end
32
+
33
+
34
+ describe "#fetch" do
35
+ it "should make availible Python error type" do
36
+ cause_error
37
+ rbType, rbValue, rbTraceback = described_class.fetch
38
+ rbType.getAttr("__name__").rubify.should == "ImportError"
39
+ end
40
+ end
41
+
42
+ end
43
+