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.
Files changed (51) hide show
  1. data/.autotest +3 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +13 -0
  4. data/.hgignore +14 -0
  5. data/.hgtags +7 -0
  6. data/.rspec +1 -1
  7. data/Contributors.rdoc +9 -0
  8. data/History.rdoc +148 -0
  9. data/{License.txt → License.rdoc} +7 -1
  10. data/Manifest.txt +15 -10
  11. data/PostInstall.txt +11 -4
  12. data/README.rdoc +272 -0
  13. data/Rakefile +107 -22
  14. data/autotest/discover.rb +1 -0
  15. data/lib/rubypython.rb +214 -120
  16. data/lib/rubypython/blankobject.rb +16 -14
  17. data/lib/rubypython/conversion.rb +242 -173
  18. data/lib/rubypython/legacy.rb +30 -31
  19. data/lib/rubypython/macros.rb +43 -34
  20. data/lib/rubypython/operators.rb +103 -101
  21. data/lib/rubypython/options.rb +41 -44
  22. data/lib/rubypython/pygenerator.rb +61 -0
  23. data/lib/rubypython/pymainclass.rb +46 -29
  24. data/lib/rubypython/pyobject.rb +193 -177
  25. data/lib/rubypython/python.rb +189 -176
  26. data/lib/rubypython/pythonerror.rb +54 -63
  27. data/lib/rubypython/pythonexec.rb +123 -0
  28. data/lib/rubypython/rubypyproxy.rb +213 -137
  29. data/lib/rubypython/type.rb +20 -0
  30. data/spec/basic_spec.rb +50 -0
  31. data/spec/callback_spec.rb +7 -17
  32. data/spec/conversion_spec.rb +7 -21
  33. data/spec/legacy_spec.rb +1 -16
  34. data/spec/pymainclass_spec.rb +6 -15
  35. data/spec/pyobject_spec.rb +39 -64
  36. data/spec/python_helpers/basics.py +20 -0
  37. data/spec/python_helpers/objects.py +24 -20
  38. data/spec/pythonerror_spec.rb +5 -17
  39. data/spec/refcnt_spec.rb +4 -10
  40. data/spec/rubypyclass_spec.rb +1 -11
  41. data/spec/rubypyproxy_spec.rb +45 -54
  42. data/spec/rubypython_spec.rb +45 -57
  43. data/spec/spec_helper.rb +49 -33
  44. metadata +87 -63
  45. data.tar.gz.sig +0 -0
  46. data/History.markdown +0 -97
  47. data/README.markdown +0 -105
  48. data/lib/rubypython/core_ext/string.rb +0 -7
  49. data/lib/rubypython/version.rb +0 -9
  50. data/spec/python_helpers/objects.pyc +0 -0
  51. 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
- return object
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
- STRING = "STRING"
11
- STRING_LIST = ["STRING1", "STRING2"]
12
- INT = 1
13
- INT_LIST = [1,1]
14
- FLOAT = 1.0
15
- FLOAT_LIST = [1.0,1.0]
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
- def square_elements(self, aList):
18
- return [x**2 for x in aList]
20
+ def square_elements(self, aList):
21
+ return [x**2 for x in aList]
19
22
 
20
- def sum_elements(self, aList):
21
- return sum(aList)
23
+ def sum_elements(self, aList):
24
+ return sum(aList)
22
25
 
23
- def __eq__(self, other):
24
- if type(self) == type(other):
25
- return True
26
- else:
27
- return False
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
- def a_method(self):
31
- pass
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, a_string:
40
- a_string}
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
@@ -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 "is false when no error has occured" do
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 "is true when an error has occured" do
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 "resets the Python error flag" do
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 "doesn't barf when there is no error" do
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 "makes availible Python error type" do
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 "is one for a new object" do
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 "increases when a new reference is passed into Ruby" do
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 "increases the reference count" do
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 "decreases the reference count" do
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
-
@@ -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 "returns a RubyPyInstance" do
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
@@ -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 "accepts a PyObject instance" do
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 "converts #{type} to wrapped pObject" do
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 unwraps #{title}" do
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 handles lack of defined __repr__" do
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 "returns 'str' of wrapped object" do
74
+ it "should return 'str' of wrapped object" do
89
75
  @six.to_s.should == '6'
90
76
  end
91
77
 
92
- it "gracefully handles lack of defined __str__" do
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 "converts a list to an array of its entries" do
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 "converts a tuple to an array of its entries" do
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 "converts a dict to an array of keys" do
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 "is true for getters" do
105
+ it "should return true given getters" do
120
106
  @objects.should respond_to(:RubyPythonMockObject)
121
107
  end
122
108
 
123
- it "is false for undefined methods" do
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 "is true for any setter" do
113
+ it "should return true given any setter" do
128
114
  @objects.should respond_to(:any_variable=)
129
115
  end
130
116
 
131
- it "is true for methods on RubyPyProxy instance" do
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 "raises NoMethodError when method is undefined" do
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 undefine" do
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 "allows methods to be called with no arguments" do
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 "fetchs attributes when method name is an attribute" do
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 "sets attribute if method call is a setter" do
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 "creates nonexistent attirubte if method call is a setter" do
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 "returns a class as a RubyPyClass" do
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 "delegates #{op}" do
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 "delegates #{op}" do
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 "delegates #{op}" do
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 "is true for proxies representing the same object" do
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 "is false for objects which are different" do
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 "allows list indexing" do
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 "allows dict access" do
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 "allows list index assignment" do
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 "allows dict value modification" do
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 "allows creation of new dict key-val pair" do
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 "allows membership tests with include?" do
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