rubypython 0.3.2 → 0.5.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.
- data/.autotest +3 -0
- data/.gemtest +0 -0
- data/.gitignore +13 -0
- data/.hgignore +14 -0
- data/.hgtags +7 -0
- data/.rspec +1 -1
- data/Contributors.rdoc +9 -0
- data/History.rdoc +148 -0
- data/{License.txt → License.rdoc} +7 -1
- data/Manifest.txt +15 -10
- data/PostInstall.txt +11 -4
- data/README.rdoc +272 -0
- data/Rakefile +107 -22
- data/autotest/discover.rb +1 -0
- data/lib/rubypython.rb +214 -120
- data/lib/rubypython/blankobject.rb +16 -14
- data/lib/rubypython/conversion.rb +242 -173
- data/lib/rubypython/legacy.rb +30 -31
- data/lib/rubypython/macros.rb +43 -34
- data/lib/rubypython/operators.rb +103 -101
- data/lib/rubypython/options.rb +41 -44
- data/lib/rubypython/pygenerator.rb +61 -0
- data/lib/rubypython/pymainclass.rb +46 -29
- data/lib/rubypython/pyobject.rb +193 -177
- data/lib/rubypython/python.rb +189 -176
- data/lib/rubypython/pythonerror.rb +54 -63
- data/lib/rubypython/pythonexec.rb +123 -0
- data/lib/rubypython/rubypyproxy.rb +213 -137
- data/lib/rubypython/type.rb +20 -0
- data/spec/basic_spec.rb +50 -0
- data/spec/callback_spec.rb +7 -17
- data/spec/conversion_spec.rb +7 -21
- data/spec/legacy_spec.rb +1 -16
- data/spec/pymainclass_spec.rb +6 -15
- data/spec/pyobject_spec.rb +39 -64
- data/spec/python_helpers/basics.py +20 -0
- data/spec/python_helpers/objects.py +24 -20
- data/spec/pythonerror_spec.rb +5 -17
- data/spec/refcnt_spec.rb +4 -10
- data/spec/rubypyclass_spec.rb +1 -11
- data/spec/rubypyproxy_spec.rb +45 -54
- data/spec/rubypython_spec.rb +45 -57
- data/spec/spec_helper.rb +49 -33
- metadata +87 -63
- data.tar.gz.sig +0 -0
- data/History.markdown +0 -97
- data/README.markdown +0 -105
- data/lib/rubypython/core_ext/string.rb +0 -7
- data/lib/rubypython/version.rb +0 -9
- data/spec/python_helpers/objects.pyc +0 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
def iterate_list():
|
4
|
+
for item in [ 1, 2, 3 ]:
|
5
|
+
yield item
|
6
|
+
|
7
|
+
def identity(object):
|
8
|
+
return object
|
9
|
+
|
10
|
+
def simple_callback(callback, value):
|
11
|
+
return callback(value)
|
12
|
+
|
13
|
+
def simple_generator(callback):
|
14
|
+
output = []
|
15
|
+
for i in callback():
|
16
|
+
output.append(i)
|
17
|
+
return output
|
18
|
+
|
19
|
+
def named_args(arg1, arg2):
|
20
|
+
return [arg1, arg2]
|
@@ -1,43 +1,47 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
|
3
3
|
def identity(object):
|
4
|
-
|
4
|
+
return object
|
5
5
|
|
6
6
|
def apply_callback(callback, args):
|
7
7
|
return callback(*args)
|
8
8
|
|
9
|
+
def named_args(arg1, arg2):
|
10
|
+
return [arg2*2, arg1*2]
|
11
|
+
|
9
12
|
class RubyPythonMockObject:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
STRING = "STRING"
|
14
|
+
STRING_LIST = ["STRING1", "STRING2"]
|
15
|
+
INT = 1
|
16
|
+
INT_LIST = [1,1]
|
17
|
+
FLOAT = 1.0
|
18
|
+
FLOAT_LIST = [1.0,1.0]
|
16
19
|
|
17
|
-
|
18
|
-
|
20
|
+
def square_elements(self, aList):
|
21
|
+
return [x**2 for x in aList]
|
19
22
|
|
20
|
-
|
21
|
-
|
23
|
+
def sum_elements(self, aList):
|
24
|
+
return sum(aList)
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
def __eq__(self, other):
|
27
|
+
if type(self) == type(other):
|
28
|
+
return True
|
29
|
+
else:
|
30
|
+
return False
|
28
31
|
|
29
32
|
class NewStyleClass(object):
|
30
|
-
|
31
|
-
|
33
|
+
def a_method(self):
|
34
|
+
pass
|
32
35
|
|
33
36
|
an_int = 1
|
34
37
|
a_char = 'a'
|
35
38
|
a_float = 1.0
|
36
39
|
a_symbol = 'sym'
|
37
40
|
a_string = "STRING"
|
41
|
+
a_string_with_nulls = "STRING\0WITH\0NULLS"
|
38
42
|
an_array = a_list = [an_int, a_char, a_float, a_string]
|
39
|
-
a_hash = a_dict = { an_int: an_int, a_char: a_char, a_symbol: a_float,
|
40
|
-
|
43
|
+
a_hash = a_dict = { an_int: an_int, a_char: a_char, a_symbol: a_float,
|
44
|
+
a_string: a_string }
|
41
45
|
true = python_True = True
|
42
46
|
false = python_False = False
|
43
47
|
nil = python_None = None
|
data/spec/pythonerror_spec.rb
CHANGED
@@ -1,50 +1,38 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
2
|
|
3
3
|
describe RubyPython::PythonError do
|
4
|
-
|
5
|
-
before do
|
6
|
-
RubyPython.start
|
7
|
-
end
|
8
|
-
|
9
|
-
after do
|
10
|
-
RubyPython.start
|
11
|
-
end
|
12
|
-
|
13
4
|
def cause_error
|
14
5
|
RubyPython::Python.PyImport_ImportModule("wat")
|
15
6
|
end
|
16
7
|
|
17
8
|
describe "#error?" do
|
18
|
-
it "
|
9
|
+
it "should return false when no error has occured" do
|
19
10
|
described_class.error?.should be_false
|
20
11
|
end
|
21
12
|
|
22
|
-
it "
|
13
|
+
it "should return true when an error has occured" do
|
23
14
|
cause_error
|
24
15
|
described_class.error?.should be_true
|
25
16
|
end
|
26
17
|
end
|
27
18
|
|
28
19
|
describe "#clear" do
|
29
|
-
it "
|
20
|
+
it "should reset the Python error flag" do
|
30
21
|
cause_error
|
31
22
|
described_class.clear
|
32
23
|
described_class.error?.should be_false
|
33
24
|
end
|
34
25
|
|
35
|
-
it "
|
26
|
+
it "should not barf when there is no error" do
|
36
27
|
lambda {described_class.clear}.should_not raise_exception
|
37
28
|
end
|
38
29
|
end
|
39
30
|
|
40
|
-
|
41
31
|
describe "#fetch" do
|
42
|
-
it "
|
32
|
+
it "should make availible Python error type" do
|
43
33
|
cause_error
|
44
34
|
rbType, rbValue, rbTraceback = described_class.fetch
|
45
35
|
rbType.getAttr("__name__").rubify.should == "ImportError"
|
46
36
|
end
|
47
37
|
end
|
48
|
-
|
49
38
|
end
|
50
|
-
|
data/spec/refcnt_spec.rb
CHANGED
@@ -15,7 +15,6 @@ end
|
|
15
15
|
include TestConstants
|
16
16
|
|
17
17
|
describe 'Reference Counting' do
|
18
|
-
|
19
18
|
before :all do
|
20
19
|
RubyPython.start
|
21
20
|
@sys = RubyPython.import 'sys'
|
@@ -27,12 +26,12 @@ describe 'Reference Counting' do
|
|
27
26
|
RubyPython.stop
|
28
27
|
end
|
29
28
|
|
30
|
-
it "
|
29
|
+
it "should be one given a new object" do
|
31
30
|
pyObj = @objects.RubyPythonMockObject.new
|
32
31
|
get_refcnt(pyObj).should == 1
|
33
32
|
end
|
34
33
|
|
35
|
-
it "
|
34
|
+
it "should increase when a new reference is passed into Ruby" do
|
36
35
|
pyObj = @objects.RubyPythonMockObject
|
37
36
|
refcnt = get_refcnt(pyObj)
|
38
37
|
pyObj2 = @objects.RubyPythonMockObject
|
@@ -40,9 +39,8 @@ describe 'Reference Counting' do
|
|
40
39
|
end
|
41
40
|
|
42
41
|
describe RubyPython::PyObject do
|
43
|
-
|
44
42
|
describe "#xIncref" do
|
45
|
-
it "
|
43
|
+
it "should increase the reference count" do
|
46
44
|
pyObj = @objects.RubyPythonMockObject.new
|
47
45
|
refcnt = get_refcnt(pyObj)
|
48
46
|
pyObj.pObject.xIncref
|
@@ -51,7 +49,7 @@ describe 'Reference Counting' do
|
|
51
49
|
end
|
52
50
|
|
53
51
|
describe "#xDecref" do
|
54
|
-
it "
|
52
|
+
it "should decrease the reference count" do
|
55
53
|
pyObj = @objects.RubyPythonMockObject.new
|
56
54
|
pyObj.pObject.xIncref
|
57
55
|
refcnt = get_refcnt(pyObj)
|
@@ -60,9 +58,5 @@ describe 'Reference Counting' do
|
|
60
58
|
get_refcnt(pointer).should == refcnt - 1
|
61
59
|
end
|
62
60
|
end
|
63
|
-
|
64
61
|
end
|
65
|
-
|
66
|
-
|
67
62
|
end
|
68
|
-
|
data/spec/rubypyclass_spec.rb
CHANGED
@@ -1,20 +1,10 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
2
|
|
3
3
|
describe RubyPython::RubyPyClass do
|
4
|
-
|
5
|
-
before do
|
6
|
-
RubyPython.start
|
7
|
-
end
|
8
|
-
|
9
|
-
after do
|
10
|
-
RubyPython.start
|
11
|
-
end
|
12
|
-
|
13
4
|
describe "#new" do
|
14
|
-
it "
|
5
|
+
it "should return a RubyPyInstance" do
|
15
6
|
urllib2 = RubyPython.import 'urllib2'
|
16
7
|
urllib2.Request.new('google.com').should be_a(RubyPython::RubyPyInstance)
|
17
8
|
end
|
18
9
|
end
|
19
|
-
|
20
10
|
end
|
data/spec/rubypyproxy_spec.rb
CHANGED
@@ -1,17 +1,7 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
2
|
|
3
|
-
|
4
3
|
include TestConstants
|
5
4
|
describe RubyPython::RubyPyProxy do
|
6
|
-
|
7
|
-
before do
|
8
|
-
RubyPython.start
|
9
|
-
end
|
10
|
-
|
11
|
-
after do
|
12
|
-
RubyPython.start
|
13
|
-
end
|
14
|
-
|
15
5
|
before do
|
16
6
|
@a = RubyPython::PyObject.new "a"
|
17
7
|
@b = RubyPython::PyObject.new "b"
|
@@ -27,12 +17,11 @@ describe RubyPython::RubyPyProxy do
|
|
27
17
|
end
|
28
18
|
|
29
19
|
describe "#new" do
|
30
|
-
it "
|
20
|
+
it "should accept a PyObject instance" do
|
31
21
|
rbPyObject = RubyPython::PyObject.new AString
|
32
22
|
lambda {described_class.new rbPyObject}.should_not raise_exception
|
33
23
|
end
|
34
24
|
|
35
|
-
|
36
25
|
[
|
37
26
|
["a string", AString],
|
38
27
|
["an int", AnInt],
|
@@ -44,10 +33,9 @@ describe RubyPython::RubyPyProxy do
|
|
44
33
|
type, input, output = arr
|
45
34
|
output ||= input
|
46
35
|
|
47
|
-
it "
|
36
|
+
it "should convert #{type} to wrapped pObject" do
|
48
37
|
described_class.new(input).pObject.rubify.should == output
|
49
38
|
end
|
50
|
-
|
51
39
|
end
|
52
40
|
end
|
53
41
|
|
@@ -60,7 +48,7 @@ describe RubyPython::RubyPyProxy do
|
|
60
48
|
["a symbol", ASym],
|
61
49
|
["a hash", AHash]
|
62
50
|
].each do |title, obj|
|
63
|
-
it "faithfully
|
51
|
+
it "should faithfully unwrap #{title}" do
|
64
52
|
pyObject = RubyPython::PyObject.new obj
|
65
53
|
proxy = described_class.new pyObject
|
66
54
|
proxy.rubify.should == pyObject.rubify
|
@@ -69,27 +57,25 @@ describe RubyPython::RubyPyProxy do
|
|
69
57
|
end
|
70
58
|
|
71
59
|
describe "#inspect" do
|
72
|
-
|
73
|
-
it "returns 'repr' of wrapped object" do
|
60
|
+
it "should return 'repr' of wrapped object" do
|
74
61
|
@six.inspect.should == '6'
|
75
62
|
end
|
76
63
|
|
77
|
-
it "gracefully
|
64
|
+
it "should gracefully handle lack of defined __repr__" do
|
78
65
|
lambda { @objects.RubyPythonMockObject.inspect }.should_not raise_exception
|
79
66
|
end
|
80
67
|
|
81
68
|
it "always tries the 'repr' function if __repr__ produces an error" do
|
82
69
|
RubyPython::PyMain.list.inspect.should == run_python_command('print repr(list)').chomp
|
83
70
|
end
|
84
|
-
|
85
71
|
end
|
86
72
|
|
87
73
|
describe "#to_s" do
|
88
|
-
it "
|
74
|
+
it "should return 'str' of wrapped object" do
|
89
75
|
@six.to_s.should == '6'
|
90
76
|
end
|
91
77
|
|
92
|
-
it "gracefully
|
78
|
+
it "should gracefully handle lack of defined __str__" do
|
93
79
|
lambda { @objects.RubyPythonMockObject.to_s }.should_not raise_exception
|
94
80
|
end
|
95
81
|
|
@@ -99,97 +85,105 @@ describe RubyPython::RubyPyProxy do
|
|
99
85
|
end
|
100
86
|
|
101
87
|
describe "#to_a" do
|
102
|
-
it "
|
88
|
+
it "should convert a list to an array of its entries" do
|
103
89
|
list = @objects.a_list
|
104
90
|
list.to_a.should == AnArray.map { |x| described_class.new(x) }
|
105
91
|
end
|
106
92
|
|
107
|
-
it "
|
93
|
+
it "should convert a tuple to an array of its entries" do
|
108
94
|
tuple = @objects.a_tuple
|
109
95
|
tuple.to_a.should == AnArray.map { |x| described_class.new(x) }
|
110
96
|
end
|
111
97
|
|
112
|
-
it "
|
98
|
+
it "should convert a dict to an array of keys" do
|
113
99
|
dict = @objects.a_dict
|
114
100
|
dict.to_a.sort.should == AConvertedHash.keys.map {|x| described_class.new(x)}.sort
|
115
101
|
end
|
116
102
|
end
|
117
103
|
|
118
104
|
describe "#respond_to?" do
|
119
|
-
it "
|
105
|
+
it "should return true given getters" do
|
120
106
|
@objects.should respond_to(:RubyPythonMockObject)
|
121
107
|
end
|
122
108
|
|
123
|
-
it "
|
109
|
+
it "should return false given undefined methods" do
|
124
110
|
@objects.should_not respond_to(:undefined_attr)
|
125
111
|
end
|
126
112
|
|
127
|
-
it "
|
113
|
+
it "should return true given any setter" do
|
128
114
|
@objects.should respond_to(:any_variable=)
|
129
115
|
end
|
130
116
|
|
131
|
-
it "
|
117
|
+
it "should return true given methods on RubyPyProxy instance" do
|
132
118
|
@objects.should respond_to(:inspect)
|
133
119
|
end
|
134
|
-
|
135
120
|
end
|
136
121
|
|
137
122
|
describe "method delegation" do
|
138
|
-
|
139
|
-
it "refers method calls to wrapped object" do
|
123
|
+
it "should refer method calls to wrapped object" do
|
140
124
|
aProxy = described_class.new(@a)
|
141
125
|
bProxy = described_class.new(@b)
|
142
126
|
aProxy.__add__(bProxy).rubify.should == (@a.rubify + @b.rubify)
|
143
127
|
end
|
144
128
|
|
145
|
-
it "
|
129
|
+
it "should raise NoMethodError when method is undefined" do
|
146
130
|
aProxy = described_class.new @a
|
147
131
|
lambda {aProxy.wat}.should raise_exception(NoMethodError)
|
148
132
|
end
|
149
133
|
|
150
|
-
it "raises NoMethodError when boolean method is
|
134
|
+
it "raises NoMethodError when boolean method is undefined" do
|
151
135
|
aProxy = described_class.new @a
|
152
136
|
lambda { aProxy.wat? }.should raise_exception(NoMethodError)
|
153
137
|
end
|
154
138
|
|
155
|
-
it "
|
139
|
+
it "should allow methods to be called with no arguments" do
|
156
140
|
builtinProxy = described_class.new @builtin
|
157
141
|
rbStrClass = builtinProxy.str
|
158
142
|
rbStrClass.new.rubify.should == String.new
|
159
143
|
end
|
160
144
|
|
161
|
-
it "
|
145
|
+
it "should fetch attributes when method name is an attribute" do
|
162
146
|
pyLetters = @string.getAttr "ascii_letters"
|
163
147
|
stringProxy = described_class.new @string
|
164
148
|
stringProxy.ascii_letters.rubify.should == pyLetters.rubify
|
165
149
|
end
|
166
150
|
|
167
|
-
it "
|
151
|
+
it "should set attribute if method call is a setter" do
|
168
152
|
stringProxy = described_class.new @string
|
169
153
|
stringProxy.letters = AString
|
170
154
|
stringProxy.letters.rubify.should == AString
|
171
155
|
end
|
172
156
|
|
173
|
-
it "
|
157
|
+
it "should create nonexistent attirubte if method call is a setter" do
|
174
158
|
stringProxy = described_class.new @string
|
175
159
|
stringProxy.nonExistent = 1
|
176
160
|
stringProxy.nonExistent.rubify.should == 1
|
177
161
|
end
|
178
162
|
|
179
|
-
it "
|
163
|
+
it "should return a class as a RubyPyClass" do
|
180
164
|
urllib2 = RubyPython.import('urllib2')
|
181
165
|
urllib2.Request.should be_a(RubyPython::RubyPyClass)
|
182
166
|
end
|
183
167
|
|
168
|
+
it "should pass named args via bang method" do
|
169
|
+
@objects.named_args!(:arg2 => 2, :arg1 => 1).rubify.should == [4,2]
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should pass through keyword arguments via bang method" do
|
173
|
+
builtinProxy = described_class.new @builtin
|
174
|
+
builtinProxy.dict!({'dict'=>'val'}, :keyword=>true).rubify.should == {
|
175
|
+
'dict' => 'val',
|
176
|
+
'keyword' => true
|
177
|
+
}
|
178
|
+
end
|
184
179
|
end
|
185
180
|
|
186
181
|
describe "when used with an operator" do
|
187
|
-
|
188
182
|
[
|
189
183
|
'+', '-', '/', '*', '&', '^', '%', '**',
|
190
184
|
'>>', '<<', '<=>', '|'
|
191
185
|
].each do |op|
|
192
|
-
it "
|
186
|
+
it "should delegate #{op}" do
|
193
187
|
@six.__send__(op, @two).rubify.should == 6.__send__(op, 2)
|
194
188
|
end
|
195
189
|
end
|
@@ -197,49 +191,48 @@ describe RubyPython::RubyPyProxy do
|
|
197
191
|
[
|
198
192
|
'~', '-@', '+@'
|
199
193
|
].each do |op|
|
200
|
-
it "
|
194
|
+
it "should delegate #{op}" do
|
201
195
|
@six.__send__(op).rubify.should == 6.__send__(op)
|
202
196
|
end
|
203
197
|
end
|
204
198
|
|
205
199
|
['==', '<', '>', '<=', '>='].each do |op|
|
206
|
-
it "
|
200
|
+
it "should delegate #{op}" do
|
207
201
|
@six.__send__(op, @two).should == 6.__send__(op, 2)
|
208
202
|
end
|
209
203
|
end
|
210
204
|
|
211
205
|
describe "#equal?" do
|
212
|
-
it "
|
206
|
+
it "be true given proxies representing the same object" do
|
213
207
|
obj1 = @objects.RubyPythonMockObject
|
214
208
|
obj2 = @objects.RubyPythonMockObject
|
215
209
|
obj1.should equal(obj2)
|
216
210
|
end
|
217
211
|
|
218
|
-
it "
|
212
|
+
it "should be false given objects which are different" do
|
219
213
|
@two.should_not equal(@six)
|
220
214
|
end
|
221
|
-
|
222
215
|
end
|
223
216
|
|
224
|
-
it "
|
217
|
+
it "should allow list indexing" do
|
225
218
|
array = described_class.new(AnArray)
|
226
219
|
array[1].rubify.should == AnArray[1]
|
227
220
|
end
|
228
221
|
|
229
|
-
it "
|
222
|
+
it "should allow dict access" do
|
230
223
|
dict = described_class.new(AHash)
|
231
224
|
key = AConvertedHash.keys[0]
|
232
225
|
dict[key].rubify.should == AConvertedHash[key]
|
233
226
|
end
|
234
227
|
|
235
|
-
it "
|
228
|
+
it "should allow list index assignment" do
|
236
229
|
array = described_class.new(AnArray)
|
237
230
|
val = AString*2
|
238
231
|
array[1] = val
|
239
232
|
array[1].rubify.should == val
|
240
233
|
end
|
241
234
|
|
242
|
-
it "
|
235
|
+
it "should allow dict value modification" do
|
243
236
|
dict = described_class.new(AHash)
|
244
237
|
key = AConvertedHash.keys[0]
|
245
238
|
val = AString*2
|
@@ -247,24 +240,22 @@ describe RubyPython::RubyPyProxy do
|
|
247
240
|
dict[key].rubify.should == val
|
248
241
|
end
|
249
242
|
|
250
|
-
it "
|
243
|
+
it "should allow creation of new dict key-val pair" do
|
251
244
|
dict = described_class.new(AHash)
|
252
245
|
key = AString*2
|
253
246
|
dict[key] = AString
|
254
247
|
dict[key].rubify.should == AString
|
255
248
|
end
|
256
249
|
|
257
|
-
it "
|
250
|
+
it "should allow membership tests with include?" do
|
258
251
|
list = described_class.new(AnArray)
|
259
252
|
list.include?(AnArray[0]).should be_true
|
260
253
|
end
|
261
254
|
end
|
262
255
|
|
263
|
-
|
264
|
-
it "delegates object equality" do
|
256
|
+
it "should delegate object equality" do
|
265
257
|
urllib_a = RubyPython.import('urllib')
|
266
258
|
urllib_b = RubyPython.import('urllib')
|
267
259
|
urllib_a.should == urllib_b
|
268
260
|
end
|
269
|
-
|
270
261
|
end
|