rubypython 0.2.8 → 0.2.9
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/History.txt +4 -1
- data/Manifest.txt +16 -1
- data/PostInstall.txt +1 -1
- data/README.txt +7 -2
- data/config/hoe.rb +12 -12
- data/ext/rubypython_bridge/cbridge.c +92 -90
- data/ext/rubypython_bridge/cbridge.h +6 -16
- data/ext/rubypython_bridge/ptor.c +110 -56
- data/ext/rubypython_bridge/ptor.h +9 -25
- data/ext/rubypython_bridge/rp_blankobject.c +42 -0
- data/ext/rubypython_bridge/rp_blankobject.h +10 -0
- data/ext/rubypython_bridge/rp_class.c +56 -0
- data/ext/rubypython_bridge/rp_class.h +6 -0
- data/ext/rubypython_bridge/rp_error.c +14 -4
- data/ext/rubypython_bridge/rp_error.h +3 -1
- data/ext/rubypython_bridge/rp_function.c +31 -0
- data/ext/rubypython_bridge/rp_function.h +6 -0
- data/ext/rubypython_bridge/rp_instance.c +165 -0
- data/ext/rubypython_bridge/rp_instance.h +6 -0
- data/ext/rubypython_bridge/rp_module.c +159 -0
- data/ext/rubypython_bridge/rp_module.h +7 -0
- data/ext/rubypython_bridge/rp_object.c +93 -427
- data/ext/rubypython_bridge/rp_object.h +8 -54
- data/ext/rubypython_bridge/rp_util.c +61 -0
- data/ext/rubypython_bridge/rp_util.h +11 -0
- data/ext/rubypython_bridge/rtop.c +103 -54
- data/ext/rubypython_bridge/rtop.h +11 -16
- data/ext/rubypython_bridge/rubypython_bridge.c +48 -20
- data/ext/rubypython_bridge/rubypython_bridge.h +5 -6
- data/lib/rubypython.rb +2 -2
- data/lib/rubypython/session.rb +4 -0
- data/lib/rubypython/version.rb +1 -1
- data/test/python_helpers/objects.py +12 -0
- data/test/python_helpers/objects.pyc +0 -0
- data/test/test_rubypython.rb +123 -19
- data/test/test_rubypython_bridge_extn.rb +52 -19
- data/test/test_session.rb +1 -1
- data/website/index.html +25 -9
- data/website/index.txt +26 -3
- metadata +20 -5
- data/.autotest +0 -9
@@ -1,6 +1,18 @@
|
|
1
1
|
#include "rubypython_bridge.h"
|
2
2
|
|
3
|
+
#include "ptor.h" //PyObject* to VALUE conversion
|
4
|
+
#include "rtop.h" //VALUE to PyObject* conversion
|
5
|
+
#include "cbridge.h" //General interface functions
|
6
|
+
#include "rp_error.h" //Error propogation from Python to Ruby
|
7
|
+
#include "rp_object.h"
|
8
|
+
#include "rp_blankobject.h"
|
9
|
+
#include "rp_util.h"
|
10
|
+
#include "rp_module.h"
|
11
|
+
#include "rp_class.h"
|
12
|
+
#include "rp_function.h"
|
13
|
+
|
3
14
|
VALUE mRubyPythonBridge;
|
15
|
+
|
4
16
|
RUBY_EXTERN VALUE cRubyPyObject;
|
5
17
|
RUBY_EXTERN VALUE cRubyPyModule;
|
6
18
|
RUBY_EXTERN VALUE cRubyPyClass;
|
@@ -8,7 +20,8 @@ RUBY_EXTERN VALUE cBlankObject;
|
|
8
20
|
|
9
21
|
|
10
22
|
/*
|
11
|
-
call-seq: func(modname,funcname
|
23
|
+
call - seq: func(modname, funcname, *args)
|
24
|
+
|
12
25
|
Given a python module name _modname_ and a function name _funcname_ calls the given function
|
13
26
|
with the supplied arguments.
|
14
27
|
|
@@ -17,28 +30,43 @@ Use builtins as the module for a built in function.
|
|
17
30
|
*/
|
18
31
|
static VALUE func_with_module(VALUE self, VALUE args)
|
19
32
|
{
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
33
|
+
// Before doing anything we attempt to start the interpreter
|
34
|
+
// Started here will be 1 if the interpreter is started by this
|
35
|
+
// function and zero otherwise
|
36
|
+
int started_here = rpSafeStart();
|
37
|
+
|
38
|
+
VALUE module, func, return_val;
|
39
|
+
|
40
|
+
// If we hav less than two arguments we cannot proceed.
|
41
|
+
// Perhaps it would make more sense to throw an error here.
|
42
|
+
if(RARRAY_LEN(args) < 2) return Qfalse;
|
43
|
+
|
44
|
+
module = rb_ary_shift(args);
|
45
|
+
func = rb_ary_shift(args);
|
46
|
+
|
47
|
+
// rpCallWithModule is defined in cbridge.c
|
48
|
+
return_val = rpCallWithModule(module, func, args);
|
49
|
+
|
50
|
+
// If we started the interpreter, we now halt it.
|
51
|
+
rpSafeStop(started_here);
|
52
|
+
|
27
53
|
return return_val;
|
28
54
|
}
|
29
55
|
|
56
|
+
|
30
57
|
/*
|
31
|
-
* call-seq: import(modname)
|
58
|
+
* call - seq: import(modname)
|
32
59
|
*
|
33
60
|
* Imports the python module _modname_ using the interpreter and returns a ruby wrapper
|
34
61
|
*/
|
35
|
-
static VALUE rp_import(VALUE self,VALUE mname)
|
62
|
+
static VALUE rp_import(VALUE self, VALUE mname)
|
36
63
|
{
|
37
|
-
return rb_class_new_instance(1,&mname,cRubyPyModule);
|
64
|
+
return rb_class_new_instance(1,&mname, cRubyPyModule);
|
38
65
|
}
|
39
66
|
|
67
|
+
|
40
68
|
/*
|
41
|
-
* call-seq: start()
|
69
|
+
* call - seq: start()
|
42
70
|
*
|
43
71
|
* Starts the python interpreter
|
44
72
|
*/
|
@@ -51,11 +79,12 @@ VALUE rp_start(VALUE self)
|
|
51
79
|
return Qfalse;
|
52
80
|
}
|
53
81
|
Py_Initialize();
|
82
|
+
|
54
83
|
return Qtrue;
|
55
84
|
}
|
56
85
|
|
57
86
|
/*
|
58
|
-
* call-seq: stop()
|
87
|
+
* call - seq: stop()
|
59
88
|
*
|
60
89
|
* Stop the python interpreter
|
61
90
|
*/
|
@@ -77,14 +106,13 @@ VALUE rp_stop(VALUE self)
|
|
77
106
|
*
|
78
107
|
* Use RubyPython instead.
|
79
108
|
*/
|
80
|
-
|
81
109
|
void Init_rubypython_bridge()
|
82
110
|
{
|
83
|
-
mRubyPythonBridge=rb_define_module("RubyPythonBridge");
|
84
|
-
rb_define_module_function(mRubyPythonBridge,"func",func_with_module,-2);
|
85
|
-
rb_define_module_function(mRubyPythonBridge,"start",rp_start,0);
|
86
|
-
rb_define_module_function(mRubyPythonBridge,"stop",rp_stop,0);
|
87
|
-
rb_define_module_function(mRubyPythonBridge,"import",rp_import,1);
|
111
|
+
mRubyPythonBridge = rb_define_module("RubyPythonBridge");
|
112
|
+
rb_define_module_function(mRubyPythonBridge,"func", func_with_module,- 2);
|
113
|
+
rb_define_module_function(mRubyPythonBridge,"start", rp_start, 0);
|
114
|
+
rb_define_module_function(mRubyPythonBridge,"stop", rp_stop, 0);
|
115
|
+
rb_define_module_function(mRubyPythonBridge,"import", rp_import, 1);
|
88
116
|
Init_BlankObject();
|
89
117
|
Init_RubyPyObject();
|
90
118
|
Init_RubyPyModule();
|
@@ -93,4 +121,4 @@ void Init_rubypython_bridge()
|
|
93
121
|
Init_RubyPyError();
|
94
122
|
Init_RubyPyInstance();
|
95
123
|
|
96
|
-
}
|
124
|
+
}
|
@@ -1,11 +1,10 @@
|
|
1
|
+
#include "config.h"
|
2
|
+
|
1
3
|
#ifndef RUBY_19
|
4
|
+
|
5
|
+
#ifndef RARRAY_LEN
|
2
6
|
#define RARRAY_LEN(arr) (RARRAY(arr)->len)
|
3
7
|
#define RARRAY_PTR(arr) (RARRAY(arr)->ptr)
|
4
8
|
#endif
|
5
|
-
#include "config.h"
|
6
9
|
|
7
|
-
#
|
8
|
-
#include "rtop.h" //VALUE to PyObject conversion
|
9
|
-
#include "cbridge.h" //General interface functions
|
10
|
-
#include "rp_error.h"
|
11
|
-
#include "rp_object.h"
|
10
|
+
#endif
|
data/lib/rubypython.rb
CHANGED
@@ -80,7 +80,7 @@ module RubyPython
|
|
80
80
|
# RubyPython.stop
|
81
81
|
#
|
82
82
|
# Also see, _stop_
|
83
|
-
def self.start()
|
83
|
+
def self.start() #=> true||false
|
84
84
|
RubyPythonBridge.start
|
85
85
|
end
|
86
86
|
|
@@ -117,7 +117,7 @@ module RubyPython
|
|
117
117
|
# Simply starts the interpreter, runs the supplied block, and stops the interpreter.
|
118
118
|
def self.session(&block)
|
119
119
|
start
|
120
|
-
retval=block.call
|
120
|
+
retval = block.call
|
121
121
|
stop
|
122
122
|
return retval
|
123
123
|
end
|
data/lib/rubypython/version.rb
CHANGED
Binary file
|
data/test/test_rubypython.rb
CHANGED
@@ -16,86 +16,136 @@ class TestRubypython < Test::Unit::TestCase
|
|
16
16
|
def test_delegation
|
17
17
|
RubyPython.start
|
18
18
|
cPickle=RubyPython.import("cPickle")
|
19
|
-
|
20
|
-
|
19
|
+
|
20
|
+
assert_instance_of(RubyPythonBridge::RubyPyModule,
|
21
|
+
cPickle,
|
22
|
+
"Module object not returned by import.")
|
23
|
+
|
24
|
+
assert_equal({"a"=>"n", [1, "2"]=>4},
|
25
|
+
cPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns."),
|
26
|
+
"Python pickle load test returned incorrect objects.")
|
27
|
+
|
21
28
|
dumped_array=cPickle.dumps([1,2,3,4])
|
22
|
-
|
23
|
-
|
29
|
+
|
30
|
+
assert_equal([1,2,3,4],
|
31
|
+
cPickle.loads(dumped_array),
|
32
|
+
"Pickled information was not retrieved correctly.")
|
33
|
+
|
34
|
+
assert_raise(NoMethodError, "Rubypython failed to raise NoMethodError on call to nonexistent method") do
|
24
35
|
cPickle.splack
|
25
36
|
end
|
26
|
-
|
37
|
+
|
38
|
+
assert_instance_of(RubyPythonBridge::RubyPyClass,
|
39
|
+
cPickle.PicklingError,
|
40
|
+
"Wrapped Python class was not of type RubyPyClass.")
|
41
|
+
|
27
42
|
cPickle.free_pobj
|
43
|
+
|
28
44
|
ObjectSpace.each_object(RubyPythonBridge::RubyPyObject) do |o|
|
29
45
|
o.free_pobj
|
30
46
|
end
|
31
|
-
|
47
|
+
|
48
|
+
assert(RubyPython.stop,"Interpreter did not halt correctly.")
|
32
49
|
end
|
33
50
|
|
34
51
|
def test_two_imports
|
35
52
|
RubyPython.start
|
36
|
-
|
37
|
-
|
53
|
+
assert_nothing_raised("Error raised on imports") do
|
54
|
+
RubyPython.import "cPickle"
|
55
|
+
RubyPython.import "urllib"
|
56
|
+
end
|
38
57
|
RubyPython.stop
|
39
58
|
end
|
40
59
|
|
41
60
|
def test_propogate_python_error
|
42
61
|
RubyPython.start
|
43
|
-
|
62
|
+
|
63
|
+
assert_raise(PythonError,"rubypython failed to propogate python error.") do
|
44
64
|
RubyPython.import "slasdfj"
|
45
65
|
end
|
66
|
+
|
46
67
|
RubyPython.stop
|
47
68
|
end
|
48
69
|
|
49
70
|
def test_run_method
|
50
71
|
unpickled=nil
|
72
|
+
|
51
73
|
RubyPython.run do
|
52
74
|
cPickle=import "cPickle"
|
53
75
|
cPickle.inspect
|
54
76
|
unpickled=cPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns.")
|
55
77
|
end
|
56
|
-
|
57
|
-
|
78
|
+
|
79
|
+
assert_equal({"a"=>"n", [1, "2"]=>4},
|
80
|
+
unpickled,
|
81
|
+
"Incorrect object returned from cPickle.")
|
82
|
+
|
83
|
+
assert(!RubyPython.stop, "RubyPython did not seem to halt at the correct time.")
|
58
84
|
end
|
59
85
|
|
60
86
|
def test_instance_method_delegation
|
61
87
|
RubyPython.start
|
88
|
+
|
62
89
|
wave=RubyPython.import "wave"
|
63
90
|
w=wave.open("test/test.wav","rb")
|
64
|
-
assert_equal(9600,
|
91
|
+
assert_equal(9600,
|
92
|
+
w.getframerate,
|
93
|
+
"Wrapped wave library incorrectly passing framerate.")
|
65
94
|
w.close
|
95
|
+
|
66
96
|
RubyPython.stop
|
67
97
|
end
|
68
98
|
|
69
99
|
def test_pymain_delegation
|
70
100
|
RubyPython.start
|
71
|
-
|
101
|
+
|
102
|
+
assert_equal(42.to_f,
|
103
|
+
PyMain.float(42),
|
104
|
+
"Integer conversion problems in Python.")
|
105
|
+
|
72
106
|
RubyPython.stop
|
73
107
|
end
|
74
108
|
|
75
109
|
def test_block_syntax
|
76
110
|
returned=""
|
111
|
+
|
77
112
|
RubyPython.start
|
78
|
-
|
113
|
+
|
114
|
+
returned = PyMain.float(22) do |f|
|
79
115
|
f*2
|
80
116
|
end
|
81
|
-
|
117
|
+
|
118
|
+
assert_equal(44.0,
|
119
|
+
returned,
|
120
|
+
"Wrapped Python object failed to correctly utilize block syntax.")
|
121
|
+
|
82
122
|
RubyPython.stop
|
83
123
|
end
|
84
124
|
|
85
125
|
def test_session_function
|
86
126
|
RubyPython.session do
|
127
|
+
|
87
128
|
cPickle=RubyPython.import "cPickle"
|
129
|
+
|
88
130
|
cPickle.inspect
|
89
|
-
|
131
|
+
|
132
|
+
assert_equal({"a"=>"n", [1, "2"]=>4},
|
133
|
+
cPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns."),
|
134
|
+
"cPickle misbehaved in session block.")
|
90
135
|
end
|
91
136
|
end
|
92
137
|
|
93
138
|
|
94
139
|
def test_setter_ary
|
95
140
|
RubyPython.session do
|
141
|
+
|
96
142
|
sys=RubyPython.import 'sys'
|
97
|
-
|
98
|
-
|
143
|
+
|
144
|
+
sys.path=[".",".."]
|
145
|
+
|
146
|
+
assert_equal([".",".."],
|
147
|
+
sys.path,
|
148
|
+
"Ruby failed to modify Python object as expected.")
|
99
149
|
end
|
100
150
|
end
|
101
151
|
|
@@ -104,8 +154,62 @@ class TestRubypython < Test::Unit::TestCase
|
|
104
154
|
urllib2=RubyPython.import "urllib2"
|
105
155
|
req=urllib2.Request("google.com")
|
106
156
|
req.headers={:a=>"2","k"=>4}
|
107
|
-
assert_equal({"a"=>"2","k"=>4},
|
157
|
+
assert_equal({"a"=>"2","k"=>4},
|
158
|
+
req.headers,
|
159
|
+
"Python dictionary not set as expected.")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_set_twice
|
164
|
+
RubyPython.session do
|
165
|
+
sys = RubyPython.import 'sys'
|
166
|
+
|
167
|
+
sys.path = ['.']
|
168
|
+
|
169
|
+
sys.path = ['..']
|
170
|
+
|
171
|
+
assert_equal(['..'],
|
172
|
+
sys.path,
|
173
|
+
"Ruby failed to modify Python object as expected.")
|
174
|
+
|
108
175
|
end
|
109
176
|
end
|
110
177
|
|
111
178
|
end
|
179
|
+
|
180
|
+
class TestWithCustomObject < Test::Unit::TestCase
|
181
|
+
def setup
|
182
|
+
RubyPython.start
|
183
|
+
sys = RubyPython.import 'sys'
|
184
|
+
sys.path = ['./test/python_helpers']
|
185
|
+
@objects = RubyPython.import 'objects'
|
186
|
+
end
|
187
|
+
|
188
|
+
def teardown
|
189
|
+
RubyPython.stop
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_string_access
|
193
|
+
assert_equal("STRING",
|
194
|
+
@objects.RubyPythonMockObject.STRING,
|
195
|
+
"String class members not being converted correctly.")
|
196
|
+
rbString = @objects.RubyPythonMockObject.STRING
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_string_ary_access
|
200
|
+
assert_equal(["STRING1", "STRING2"],
|
201
|
+
@objects.RubyPythonMockObject.STRING_LIST,
|
202
|
+
"List of strings class member not being converted correctly.")
|
203
|
+
rbStringList = @objects.RubyPythonMockObject.STRING_LIST
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_string_ary_modify
|
207
|
+
rbStringList = @objects.RubyPythonMockObject.STRING_LIST
|
208
|
+
rbStringList.push"NEW_STRING"
|
209
|
+
@objects.RubyPythonMockObject.STRING_LIST = rbStringList
|
210
|
+
assert_equal("NEW_STRING",
|
211
|
+
@objects.RubyPythonMockObject.STRING_LIST[2],
|
212
|
+
"Failed to add object to list.")
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
@@ -6,30 +6,51 @@ require "rubypython_bridge.so"
|
|
6
6
|
class TestRubyPythonBridgeExtn < Test::Unit::TestCase
|
7
7
|
|
8
8
|
def test_func_with_module
|
9
|
-
pickle_return=RubyPythonBridge.func("cPickle",
|
9
|
+
pickle_return = RubyPythonBridge.func("cPickle",
|
10
|
+
"loads", "(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns.")
|
11
|
+
|
10
12
|
assert_equal({"a"=>"n", [1, "2"]=>4},pickle_return)
|
11
13
|
end
|
12
14
|
|
13
15
|
def test_start_stop
|
14
|
-
assert(RubyPythonBridge.start)
|
15
|
-
|
16
|
-
assert(RubyPythonBridge.
|
17
|
-
|
16
|
+
assert(RubyPythonBridge.start, "Embedded python interpreter failed to start correctly.")
|
17
|
+
|
18
|
+
assert(!RubyPythonBridge.start, "Interpreter attempted to start while running.")
|
19
|
+
|
20
|
+
assert(RubyPythonBridge.stop, "Interpreter failed to halt.")
|
21
|
+
|
22
|
+
assert(!RubyPythonBridge.stop, "Interpreter ran into trouble while halting.")
|
18
23
|
end
|
19
24
|
|
20
25
|
def test_new_instance
|
21
26
|
RubyPythonBridge.start
|
22
|
-
|
23
|
-
|
24
|
-
|
27
|
+
|
28
|
+
urllib2 = RubyPythonBridge.import "urllib2"
|
29
|
+
|
30
|
+
assert_instance_of(RubyPythonBridge::RubyPyClass,
|
31
|
+
urllib2.Request,
|
32
|
+
"Wrapped Python class not of correct type.")
|
33
|
+
|
34
|
+
assert_instance_of(RubyPythonBridge::RubyPyInstance,
|
35
|
+
urllib2.Request("google.com"),
|
36
|
+
"Wrapped python instance not of correct type.")
|
37
|
+
|
25
38
|
RubyPythonBridge.stop
|
26
39
|
end
|
27
40
|
|
28
41
|
def test_new_instance_with_new_method
|
29
42
|
RubyPythonBridge.start
|
43
|
+
|
30
44
|
urllib2=RubyPythonBridge.import "urllib2"
|
31
|
-
|
32
|
-
assert_instance_of(RubyPythonBridge::
|
45
|
+
|
46
|
+
assert_instance_of(RubyPythonBridge::RubyPyClass,
|
47
|
+
urllib2.Request,
|
48
|
+
"Wrapped Python class not of correct type.")
|
49
|
+
|
50
|
+
assert_instance_of(RubyPythonBridge::RubyPyInstance,
|
51
|
+
urllib2.Request.new("google.com"),
|
52
|
+
"New call misbehaving of wrapped class.")
|
53
|
+
|
33
54
|
RubyPythonBridge.stop
|
34
55
|
end
|
35
56
|
|
@@ -49,27 +70,39 @@ class TestRubyPythonBridgeWithCPickle < Test::Unit::TestCase
|
|
49
70
|
end
|
50
71
|
|
51
72
|
def test_mod_respond_to
|
52
|
-
assert(@cPickle.respond_to?
|
73
|
+
assert(@cPickle.respond_to?(:loads),
|
74
|
+
"Ruby respond to method not working on wrapped module.")
|
53
75
|
end
|
54
76
|
|
55
77
|
def test_data_passing
|
56
|
-
assert_equal({"a"=>"n", [1, "2"]=>4}
|
57
|
-
|
58
|
-
|
78
|
+
assert_equal({"a"=>"n", [1, "2"]=>4},
|
79
|
+
@cPickle.loads( "(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns."),
|
80
|
+
"Data returned from wrapped cPickle is incorrect." )
|
81
|
+
|
82
|
+
orig_array = [1,2,3,4]
|
83
|
+
dumped_array = @cPickle.dumps(orig_array)
|
84
|
+
|
85
|
+
assert_equal(orig_array,
|
86
|
+
@cPickle.loads(dumped_array),
|
87
|
+
"Array returned from cPickle is not equivalent to input array.")
|
59
88
|
end
|
60
89
|
|
61
|
-
def
|
62
|
-
assert_raise NoMethodError do
|
90
|
+
def test_unknown_method
|
91
|
+
assert_raise(NoMethodError, "Missing method failed to raise NoMethodError") do
|
63
92
|
@cPickle.splack
|
64
93
|
end
|
65
94
|
end
|
66
95
|
|
67
96
|
def test_class_wrapping
|
68
|
-
assert_instance_of(RubyPythonBridge::RubyPyClass
|
97
|
+
assert_instance_of(RubyPythonBridge::RubyPyClass,
|
98
|
+
@cPickle.PicklingError,
|
99
|
+
"Wrapped class is not an instance of RubyPyClass.")
|
69
100
|
end
|
70
101
|
|
71
|
-
def
|
72
|
-
assert_instance_of(RubyPythonBridge::RubyPyModule
|
102
|
+
def test_module_wrapping
|
103
|
+
assert_instance_of(RubyPythonBridge::RubyPyModule,
|
104
|
+
@cPickle,
|
105
|
+
"Wrapped module is not of class RubyPyModule.")
|
73
106
|
end
|
74
107
|
|
75
108
|
end
|