lokeshh_rubypython 0.7

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 (48) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +3 -0
  3. data/.gitignore +18 -0
  4. data/.hgignore +20 -0
  5. data/.hgtags +12 -0
  6. data/.rspec +2 -0
  7. data/Contributors.rdoc +11 -0
  8. data/History.rdoc +214 -0
  9. data/License.rdoc +26 -0
  10. data/Manifest.txt +46 -0
  11. data/PostInstall.txt +16 -0
  12. data/README.rdoc +272 -0
  13. data/Rakefile +118 -0
  14. data/autotest/discover.rb +1 -0
  15. data/lib/rubypython/blankobject.rb +23 -0
  16. data/lib/rubypython/conversion.rb +332 -0
  17. data/lib/rubypython/interpreter.rb +262 -0
  18. data/lib/rubypython/macros.rb +56 -0
  19. data/lib/rubypython/operators.rb +120 -0
  20. data/lib/rubypython/pygenerator.rb +61 -0
  21. data/lib/rubypython/pymainclass.rb +80 -0
  22. data/lib/rubypython/pyobject.rb +189 -0
  23. data/lib/rubypython/python.rb +199 -0
  24. data/lib/rubypython/pythonerror.rb +80 -0
  25. data/lib/rubypython/rubypyproxy.rb +328 -0
  26. data/lib/rubypython/tuple.rb +10 -0
  27. data/lib/rubypython/type.rb +20 -0
  28. data/lib/rubypython.rb +229 -0
  29. data/spec/basic_spec.rb +50 -0
  30. data/spec/callback_spec.rb +53 -0
  31. data/spec/conversion_spec.rb +68 -0
  32. data/spec/pymainclass_spec.rb +24 -0
  33. data/spec/pyobject_spec.rb +202 -0
  34. data/spec/python_helpers/basics.py +23 -0
  35. data/spec/python_helpers/errors.py +2 -0
  36. data/spec/python_helpers/objects.py +48 -0
  37. data/spec/pythonerror_spec.rb +52 -0
  38. data/spec/refcnt_spec.rb +98 -0
  39. data/spec/rubypyclass_spec.rb +10 -0
  40. data/spec/rubypyproxy_spec.rb +261 -0
  41. data/spec/rubypython_spec.rb +59 -0
  42. data/spec/spec_helper.rb +71 -0
  43. data/website/index.rhtml +36 -0
  44. data/website/robots.txt +5 -0
  45. data/website/stylesheets/960.css +549 -0
  46. data/website/stylesheets/border-radius.htc +143 -0
  47. data/website/stylesheets/screen.css +132 -0
  48. metadata +297 -0
@@ -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,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,202 @@
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
+
124
+ describe "#callObject" do
125
+ #Expand coverage types
126
+ it "should execute wrapped object with supplied arguments" do
127
+ arg = described_class.new AnInt
128
+ argt = described_class.buildArgTuple arg
129
+
130
+ builtin = @builtin.pObject
131
+ stringClass = builtin.getAttr "str"
132
+ stringClass.callObject(argt).rubify.should == AnInt.to_s
133
+ end
134
+ end
135
+
136
+ describe "#function_or_method?" do
137
+ it "should be true given a method" do
138
+ mockObjClass = @objects.RubyPythonMockObject.pObject
139
+ mockObjClass.getAttr('square_elements').should be_a_function_or_method
140
+ end
141
+
142
+ it "should be true given a function" do
143
+ @objects.pObject.getAttr('identity').should be_a_function_or_method
144
+ end
145
+
146
+ it "should return true given a builtin function" do
147
+ any = @builtin.pObject.getAttr('any')
148
+ any.should be_a_function_or_method
149
+ end
150
+
151
+ it "should return false given a class" do
152
+ @objects.RubyPythonMockObject.pObject.should_not be_a_function_or_method
153
+ end
154
+ end
155
+
156
+ describe "#class?" do
157
+ it "should return true if wrapped object is an old style class" do
158
+ @objects.RubyPythonMockObject.pObject.should be_a_class
159
+ end
160
+
161
+ it "should return true if wrapped object is an new style class" do
162
+ @objects.NewStyleClass.pObject.should be_a_class
163
+ end
164
+
165
+ it "should return true if wrapped object is a builtin class" do
166
+ strClass = @builtin.pObject.getAttr('str')
167
+ strClass.should be_a_class
168
+ end
169
+
170
+ it "should return false given an object instance" do
171
+ @objects.RubyPythonMockObject.new.pObject.should_not be_a_class
172
+ end
173
+ end
174
+
175
+ describe "#callable?" do
176
+ it "should be true given a method" do
177
+ mockObjClass = @objects.RubyPythonMockObject.pObject
178
+ mockObjClass.getAttr('square_elements').should be_callable
179
+ end
180
+
181
+ it "should be true given a function" do
182
+ @objects.pObject.getAttr('identity').should be_callable
183
+ end
184
+
185
+ it "should return true given a builtin function" do
186
+ any = @builtin.pObject.getAttr('any')
187
+ any.should be_callable
188
+ end
189
+
190
+ it "should return true given a class" do
191
+ @objects.RubyPythonMockObject.pObject.should be_callable
192
+ end
193
+
194
+ it "should return false given a non-callable instance" do
195
+ @objects.RubyPythonMockObject.new.pObject.should_not be_callable
196
+ end
197
+
198
+ specify { described_class.new(6).should_not be_callable }
199
+
200
+ end
201
+
202
+ end
@@ -0,0 +1,23 @@
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]
21
+
22
+ def expects_tuple(tvalue):
23
+ return isinstance(tvalue, tuple)
@@ -0,0 +1,2 @@
1
+ def nested_error():
2
+ return 1 / 0
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env python
2
+
3
+ def identity(object):
4
+ return object
5
+
6
+ def apply_callback(callback, args):
7
+ return callback(*args)
8
+
9
+ def named_args(arg1, arg2):
10
+ return [arg2*2, arg1*2]
11
+
12
+ class RubyPythonMockObject:
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]
19
+
20
+ def square_elements(self, aList):
21
+ return [x**2 for x in aList]
22
+
23
+ def sum_elements(self, aList):
24
+ return sum(aList)
25
+
26
+ def __eq__(self, other):
27
+ if type(self) == type(other):
28
+ return True
29
+ else:
30
+ return False
31
+
32
+ class NewStyleClass(object):
33
+ def a_method(self):
34
+ pass
35
+
36
+ an_int = 1
37
+ a_char = 'a'
38
+ a_float = 1.0
39
+ a_symbol = 'sym'
40
+ a_string = "STRING"
41
+ a_string_with_nulls = "STRING\0WITH\0NULLS"
42
+ an_array = a_list = [an_int, a_char, a_float, a_string]
43
+ a_hash = a_dict = { an_int: an_int, a_char: a_char, a_symbol: a_float,
44
+ a_string: a_string }
45
+ true = python_True = True
46
+ false = python_False = False
47
+ nil = python_None = None
48
+ a_tuple = tuple(a_list)
@@ -0,0 +1,52 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe RubyPython::PythonError do
4
+ def cause_error
5
+ RubyPython::Python.PyImport_ImportModule("wat")
6
+ end
7
+
8
+ describe "#error?" do
9
+ it "should return false when no error has occured" do
10
+ described_class.error?.should be_false
11
+ end
12
+
13
+ it "should return true when an error has occured" do
14
+ cause_error
15
+ described_class.error?.should be_true
16
+ end
17
+ end
18
+
19
+ describe "#clear" do
20
+ it "should reset the Python error flag" do
21
+ cause_error
22
+ described_class.clear
23
+ described_class.error?.should be_false
24
+ end
25
+
26
+ it "should not barf when there is no error" do
27
+ lambda {described_class.clear}.should_not raise_exception
28
+ end
29
+ end
30
+
31
+ describe "#fetch" do
32
+ it "should make availible Python error type" do
33
+ cause_error
34
+ rbType, rbValue, rbTraceback = described_class.fetch
35
+ rbType.getAttr("__name__").rubify.should == "ImportError"
36
+ end
37
+ end
38
+
39
+ describe ".last_traceback" do
40
+ it "should make availble the Python traceback of the last error" do
41
+ traceback = RubyPython.import 'traceback'
42
+ errors = RubyPython.import 'errors'
43
+ begin
44
+ errors.nested_error
45
+ rescue RubyPython::PythonError => exc
46
+ tb = exc.traceback
47
+ list = traceback.format_tb(tb)
48
+ list.rubify[0].should =~ /1 \/ 0/
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,98 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ def get_refcnt(pobject)
4
+ raise 'Cannot work with a nil object' if pobject.nil?
5
+
6
+ if pobject.kind_of? RubyPython::RubyPyProxy
7
+ pobject = pobject.pObject.pointer
8
+ elsif pobject.kind_of? RubyPython::PyObject
9
+ pobject = pobject.pointer
10
+ end
11
+ RubyPython::Macros.Py_REFCNT pobject
12
+ end
13
+
14
+ include TestConstants
15
+
16
+ describe 'Reference Counting' do
17
+ before :all do
18
+ RubyPython.start
19
+ @sys = RubyPython.import 'sys'
20
+ @sys.path.append './spec/python_helpers'
21
+ @objects = RubyPython.import 'objects'
22
+ end
23
+
24
+ after :all do
25
+ RubyPython.stop
26
+ end
27
+
28
+ it "should be one given a new object" do
29
+ pyObj = @objects.RubyPythonMockObject.new
30
+ get_refcnt(pyObj).should == 1
31
+ end
32
+
33
+ it "should increase when a new reference is passed into Ruby" do
34
+ pyObj = @objects.RubyPythonMockObject
35
+ refcnt = get_refcnt(pyObj)
36
+ pyObj2 = @objects.RubyPythonMockObject
37
+ get_refcnt(pyObj).should == (refcnt + 1)
38
+ end
39
+
40
+ describe RubyPython::PyObject do
41
+ describe "#xIncref" do
42
+ it "should increase the reference count" do
43
+ pyObj = @objects.RubyPythonMockObject.new
44
+ refcnt = get_refcnt(pyObj)
45
+ pyObj.pObject.xIncref
46
+ get_refcnt(pyObj).should == refcnt + 1
47
+ end
48
+ end
49
+
50
+ describe "#xDecref" do
51
+ it "should decrease the reference count" do
52
+ pyObj = @objects.RubyPythonMockObject.new
53
+ pyObj.pObject.xIncref
54
+ refcnt = get_refcnt(pyObj)
55
+ pointer = pyObj.pObject.pointer
56
+ pyObj.pObject.xDecref
57
+ get_refcnt(pointer).should == refcnt - 1
58
+ end
59
+ end
60
+ end
61
+
62
+ describe RubyPython::Conversion do
63
+ describe ".rtopArrayToList" do
64
+ it "should incref any wrapped objects in the array" do
65
+ int = RubyPython::PyObject.new AnInt
66
+ refcnt = get_refcnt(int)
67
+ arr = [int]
68
+ pyArr = subject.rtopArrayToList(arr)
69
+ get_refcnt(int).should == refcnt + 1
70
+ end
71
+
72
+ end
73
+
74
+ describe ".rtopObject" do
75
+ [
76
+ ["string", AString],
77
+ ["float", AFloat],
78
+ ["array", AnArray],
79
+ #["symbol", ASym],
80
+ ["hash", AHash]
81
+ ].each do |arr|
82
+ type, input = arr
83
+
84
+ it "should return a refcnt of 1 for newly created #{type}" do
85
+ pyObj = subject.rtopObject(input)
86
+ get_refcnt(pyObj).should == 1
87
+ end
88
+
89
+ it "should increment the refcnt each time the same #{type} is passed in" do
90
+ pyObj = RubyPython::PyObject.new subject.rtopObject(input)
91
+ refcnt = get_refcnt(pyObj)
92
+ pyObj2 = subject.rtopObject(pyObj)
93
+ get_refcnt(pyObj2).should == refcnt + 1
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe RubyPython::RubyPyClass do
4
+ describe "#new" do
5
+ it "should return a RubyPyInstance" do
6
+ urllib2 = RubyPython.import 'urllib2'
7
+ urllib2.Request.new('google.com').should be_a(RubyPython::RubyPyInstance)
8
+ end
9
+ end
10
+ end