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.
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