rubypython 0.3.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|