rubypython 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/History.txt +4 -1
  2. data/Manifest.txt +16 -1
  3. data/PostInstall.txt +1 -1
  4. data/README.txt +7 -2
  5. data/config/hoe.rb +12 -12
  6. data/ext/rubypython_bridge/cbridge.c +92 -90
  7. data/ext/rubypython_bridge/cbridge.h +6 -16
  8. data/ext/rubypython_bridge/ptor.c +110 -56
  9. data/ext/rubypython_bridge/ptor.h +9 -25
  10. data/ext/rubypython_bridge/rp_blankobject.c +42 -0
  11. data/ext/rubypython_bridge/rp_blankobject.h +10 -0
  12. data/ext/rubypython_bridge/rp_class.c +56 -0
  13. data/ext/rubypython_bridge/rp_class.h +6 -0
  14. data/ext/rubypython_bridge/rp_error.c +14 -4
  15. data/ext/rubypython_bridge/rp_error.h +3 -1
  16. data/ext/rubypython_bridge/rp_function.c +31 -0
  17. data/ext/rubypython_bridge/rp_function.h +6 -0
  18. data/ext/rubypython_bridge/rp_instance.c +165 -0
  19. data/ext/rubypython_bridge/rp_instance.h +6 -0
  20. data/ext/rubypython_bridge/rp_module.c +159 -0
  21. data/ext/rubypython_bridge/rp_module.h +7 -0
  22. data/ext/rubypython_bridge/rp_object.c +93 -427
  23. data/ext/rubypython_bridge/rp_object.h +8 -54
  24. data/ext/rubypython_bridge/rp_util.c +61 -0
  25. data/ext/rubypython_bridge/rp_util.h +11 -0
  26. data/ext/rubypython_bridge/rtop.c +103 -54
  27. data/ext/rubypython_bridge/rtop.h +11 -16
  28. data/ext/rubypython_bridge/rubypython_bridge.c +48 -20
  29. data/ext/rubypython_bridge/rubypython_bridge.h +5 -6
  30. data/lib/rubypython.rb +2 -2
  31. data/lib/rubypython/session.rb +4 -0
  32. data/lib/rubypython/version.rb +1 -1
  33. data/test/python_helpers/objects.py +12 -0
  34. data/test/python_helpers/objects.pyc +0 -0
  35. data/test/test_rubypython.rb +123 -19
  36. data/test/test_rubypython_bridge_extn.rb +52 -19
  37. data/test/test_session.rb +1 -1
  38. data/website/index.html +25 -9
  39. data/website/index.txt +26 -3
  40. metadata +20 -5
  41. 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,*args)
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
- int started_here=safe_start();
21
- VALUE module,func,return_val;
22
- if(RARRAY_LEN(args)<2) return Qfalse;
23
- module=rb_ary_shift(args);
24
- func=rb_ary_shift(args);
25
- return_val=rp_call_func_with_module_name(module,func,args);
26
- safe_stop(started_here);
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
- #include "ptor.h" //PyObject to VALUE conversion
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
@@ -80,7 +80,7 @@ module RubyPython
80
80
  # RubyPython.stop
81
81
  #
82
82
  # Also see, _stop_
83
- def self.start() # true||false
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
@@ -0,0 +1,4 @@
1
+ require File::expand_path(File.dirname(__FILE__) + '/../rubypython.rb') if RubyPython.nil?
2
+ RubyPython.start
3
+
4
+ at_exit {RubyPython.stop}
@@ -2,7 +2,7 @@ module RubyPython
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 8
5
+ TINY = 9
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env python
2
+
3
+ def identity(object):
4
+ return object
5
+
6
+ class RubyPythonMockObject:
7
+ STRING = "STRING"
8
+ STRING_LIST = ["STRING1", "STRING2"]
9
+ INT = 1
10
+ INT_LIST = [1,1]
11
+ FLOAT = 1.0
12
+ FLOAT_LIST = [1.0,1.0]
@@ -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
- assert_instance_of(RubyPythonBridge::RubyPyModule,cPickle)
20
- assert_equal({"a"=>"n", [1, "2"]=>4},cPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns."))
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
- assert_equal([1,2,3,4],cPickle.loads(dumped_array))
23
- assert_raise NoMethodError do
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
- assert_instance_of(RubyPythonBridge::RubyPyClass,cPickle.PicklingError)
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
- assert(RubyPython.stop)
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
- RubyPython.import "cPickle"
37
- RubyPython.import "urllib"
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
- assert_raise PythonError do
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
- assert_equal({"a"=>"n", [1, "2"]=>4},unpickled)
57
- assert(!RubyPython.stop)
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,w.getframerate)
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
- assert_equal(42.to_f,PyMain.float(42))
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
- returned=PyMain.float(22) do |f|
113
+
114
+ returned = PyMain.float(22) do |f|
79
115
  f*2
80
116
  end
81
- assert_equal(44.0,returned)
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
- assert_equal({"a"=>"n", [1, "2"]=>4},cPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns."))
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
- sys.path=[""]
98
- assert_equal([""],sys.path)
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},req.headers)
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","loads","(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns.")
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
- assert(!RubyPythonBridge.start)
16
- assert(RubyPythonBridge.stop)
17
- assert(!RubyPythonBridge.stop)
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
- urllib2=RubyPythonBridge.import "urllib2"
23
- assert_instance_of(RubyPythonBridge::RubyPyClass,urllib2.Request)
24
- assert_instance_of(RubyPythonBridge::RubyPyInstance,urllib2.Request("google.com"))
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
- assert_instance_of(RubyPythonBridge::RubyPyClass,urllib2.Request)
32
- assert_instance_of(RubyPythonBridge::RubyPyInstance,urllib2.Request.new("google.com"))
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? :loads)
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},@cPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns."))
57
- dumped_array=@cPickle.dumps([1,2,3,4])
58
- assert_equal(@cPickle.loads(dumped_array),[1,2,3,4])
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 test_method_missing
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,@cPickle.PicklingError)
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 test_module_method_wrapping
72
- assert_instance_of(RubyPythonBridge::RubyPyModule,@cPickle)
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