rubypython 0.2.1 → 0.2.2

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 CHANGED
@@ -1,3 +1,15 @@
1
+ == 0.2.2 2008-08-07
2
+ * Major Enhancements
3
+ * Wrapped classes and instances should now behave as expected.
4
+ * Gave RubyPyClasses a "new" method for creating instances.
5
+ * Callable class can now be called provided that at least one argument is given
6
+ * A wrapped object's respond_to? method now has some relation to its actually methods.
7
+
8
+ * Bug fixes
9
+ * Fixed bug with inspect method of RubyPyObject that caused a bus error when inspecting
10
+ certain objects
11
+
12
+
1
13
  == 0.2.1 2008-08-02
2
14
  * 1 Bug Fix
3
15
  * Incorrect require fixed
data/License.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 FIXME full name
1
+ Copyright (c) 2008 Zach Raines
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/Manifest.txt CHANGED
@@ -21,7 +21,6 @@ ext/rubypython_bridge/rtop.c
21
21
  ext/rubypython_bridge/rtop.h
22
22
  ext/rubypython_bridge/rubypython_bridge.c
23
23
  ext/rubypython_bridge/rubypython_bridge.h
24
- ext/rubypython_bridge/test.rb
25
24
  lib/rubypython.rb
26
25
  lib/rubypython/version.rb
27
26
  lib/rubypython/wrapper_extensions.rb
@@ -35,6 +34,7 @@ tasks/environment.rake
35
34
  tasks/extconf.rake
36
35
  tasks/extconf/rubypython_bridge.rake
37
36
  tasks/website.rake
37
+ test/test.wav
38
38
  test/test_helper.rb
39
39
  test/test_rubypython.rb
40
40
  test/test_rubypython_bridge_extn.rb
data/PostInstall.txt CHANGED
@@ -1,6 +1,8 @@
1
1
 
2
- For more information on rubypython, see http://rubypython.rubyforge.org
2
+ For more information on RubyPython, see http://rubypython.rubyforge.org
3
3
 
4
4
  If you find a bug, or have any suggestions, email me at: achatesavc+rubypython@gmail.com
5
5
 
6
+ If you would like to help develop RubyPython, also send me an email.
7
+
6
8
 
data/README.txt CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- RubyPython is a a C bridge between ruby and python with a ruby interface.
7
+ RubyPython is a C bridge between Ruby and Python with a Ruby interface. It's aim is to make the power of the Python's great standard library available to Ruby programmers from within Ruby.
8
8
 
9
9
  == FEATURES/PROBLEMS:
10
10
 
@@ -13,9 +13,7 @@
13
13
  * Can import python modules
14
14
  * Can execute arbitrary methods on imported modules and return the result
15
15
  * Python objects can be treated as Ruby objects!
16
-
17
- Problems:
18
- * Issues with the run method
16
+ * Python's standard library available to you from within ruby.
19
17
 
20
18
  == SYNOPSIS:
21
19
  RubyPython.start
@@ -24,7 +22,7 @@
24
22
  RubyPython.stop
25
23
 
26
24
  == REQUIREMENTS:
27
-
25
+ Python must be installed. Currently, RubyPython requires python2.5 but it may soon be able to work on other platforms. I have only tested it on Mac OSX 10.5, so I'm not sure what parts may need correcting for other systems.
28
26
 
29
27
  == INSTALL:
30
28
 
@@ -122,6 +122,7 @@ VALUE rp_call_func(PyObject* pFunc, VALUE args)
122
122
  PyObject *pReturn,*pArgs;
123
123
  if(!(TYPE(args)==T_ARRAY))
124
124
  {
125
+
125
126
  rArgs=rb_ary_new();
126
127
  rb_ary_push(rArgs,args);
127
128
  }
@@ -139,11 +140,8 @@ VALUE rp_call_func(PyObject* pFunc, VALUE args)
139
140
  rp_pythonerror();
140
141
  return Qnil;
141
142
  }
142
- rReturn=ptor_obj(pReturn);
143
+ rReturn=ptor_obj_no_destruct(pReturn);
143
144
 
144
145
  Py_XDECREF(pArgs);
145
- Py_XDECREF(pReturn);
146
-
147
146
  return rReturn;
148
147
  }
149
-
@@ -160,7 +160,12 @@ static VALUE ptor_obj_core(PyObject *pObj,int destructive)
160
160
  {
161
161
  return rp_func_from_function(pObj);
162
162
 
163
- }
163
+ }
164
+ if(PyInstance_Check(pObj))
165
+ {
166
+ rObj=rp_inst_from_instance(pObj);
167
+ return rObj;
168
+ }
164
169
  return rp_cla_from_class(pObj);
165
170
  }
166
171
  VALUE ptor_obj_no_destruct(PyObject *pObj)
@@ -9,7 +9,7 @@ void rp_pythonerror()
9
9
  PyErr_Fetch(&pType,&pValue,&pTraceback);
10
10
  pTypeName=PyObject_GetAttrString(pType,"__name__");
11
11
  Py_XDECREF(pType);
12
- rb_raise(ePythonError,"%s:(%s)\n",STR2CSTR(ptor_obj(pTypeName)),STR2CSTR(ptor_obj(pValue)));
12
+ rb_raise(ePythonError,"%s:(%s)\n",STR2CSTR(ptor_obj(pTypeName)),STR2CSTR(rb_inspect(ptor_obj(pValue))));
13
13
  Py_XDECREF(pTraceback);
14
14
  }
15
15
 
@@ -2,11 +2,13 @@
2
2
  #include "stdio.h"
3
3
 
4
4
  extern VALUE mRubyPythonBridge;
5
+ extern VALUE ePythonError;
5
6
 
6
7
  VALUE cRubyPyObject;
7
8
  VALUE cRubyPyModule;
8
9
  VALUE cRubyPyClass;
9
10
  VALUE cRubyPyFunction;
11
+ VALUE cRubyPyInstance;
10
12
 
11
13
  void rp_obj_mark(PObj* self)
12
14
  {}
@@ -36,6 +38,10 @@ VALUE rp_obj_free_pobj(VALUE self)
36
38
  cself->pObject=NULL;
37
39
  return Qtrue;
38
40
  }
41
+ else
42
+ {
43
+ cself->pObject=NULL;
44
+ }
39
45
  return Qfalse;
40
46
  }
41
47
 
@@ -51,6 +57,10 @@ PyObject* rp_obj_pobject(VALUE self)
51
57
  {
52
58
  PObj *cself;
53
59
  Data_Get_Struct(self,PObj,cself);
60
+ if(!cself->pObject)
61
+ {
62
+ rb_raise(ePythonError,"RubyPython tried to access a freed object");
63
+ }
54
64
  return cself->pObject;
55
65
  }
56
66
 
@@ -62,9 +72,32 @@ VALUE rp_obj_name(VALUE self)
62
72
  {
63
73
  if(Py_IsInitialized())
64
74
  {
65
- PyObject *pObject;
66
- pObject=rp_obj_pobject(self);
67
- return ptor_obj(PyObject_GetAttrString(pObject,"__name__"));
75
+ PyObject *pObject,*pName,*pRepr;
76
+ VALUE rName;
77
+ pObject=rp_obj_pobject(self);
78
+ pName=PyObject_GetAttrString(pObject,"__name__");
79
+ if(!pName)
80
+ {
81
+ PyErr_Clear();
82
+ pName=PyObject_GetAttrString(pObject,"__class__");
83
+ pRepr=PyObject_Repr(pName);
84
+ rName=ptor_string(pRepr);
85
+ Py_XDECREF(pRepr);
86
+ return rb_str_concat(rb_str_new2("An instance of "),rName);
87
+ if(!pName)
88
+ {
89
+ PyErr_Clear();
90
+ pName=PyObject_Repr(pObject);
91
+ if(!pName)
92
+ {
93
+ PyErr_Clear();
94
+ return rb_str_new2("__Unnameable__");
95
+ }
96
+ }
97
+ }
98
+ rName=ptor_string(pName);
99
+ Py_XDECREF(pName);
100
+ return rName;
68
101
  }
69
102
  return rb_str_new2("__FREED__");
70
103
 
@@ -79,13 +112,83 @@ VALUE rp_obj_from_pyobject(PyObject *pObj)
79
112
  return rObj;
80
113
  }
81
114
 
115
+ VALUE rp_inst_from_instance(PyObject *pInst)
116
+ {
117
+ PObj* self;
118
+ VALUE rInst=rb_class_new_instance(0,NULL,cRubyPyInstance);
119
+ PyObject *pClassDict,*pClass,*pInstDict;
120
+ VALUE rInstDict,rClassDict;
121
+ Data_Get_Struct(rInst,PObj,self);
122
+ self->pObject=pInst;
123
+ pClass=PyObject_GetAttrString(pInst,"__class__");
124
+ pClassDict=PyObject_GetAttrString(pClass,"__dict__");
125
+ pInstDict=PyObject_GetAttrString(pInst,"__dict__");
126
+ Py_XINCREF(pClassDict);
127
+ Py_XINCREF(pInstDict);
128
+ rClassDict=rp_obj_from_pyobject(pClassDict);
129
+ rInstDict=rp_obj_from_pyobject(pInstDict);
130
+ rb_iv_set(rInst,"@pclassdict",rClassDict);
131
+ rb_iv_set(rInst,"@pinstdict",rInstDict);
132
+ return rInst;
133
+ }
134
+
135
+ //:nodoc:
136
+ VALUE rp_inst_delegate(VALUE self,VALUE args)
137
+ {
138
+ VALUE name,name_string,rClassDict,result,rInstDict;
139
+ VALUE ret;
140
+ char *cname;
141
+ PObj *pClassDict,*pInstDict;
142
+ PyObject *pCalled;
143
+ if(!rp_has_attr(self,rb_ary_entry(args,0)))
144
+ {
145
+ int argc;
146
+
147
+ VALUE *argv;
148
+ argc=RARRAY(args)->len;
149
+ argv=ALLOC_N(VALUE,argc);
150
+ MEMCPY(argv,RARRAY(args)->ptr,VALUE,argc);
151
+ return rb_call_super(argc,argv);
152
+ }
153
+ name=rb_ary_shift(args);
154
+ name_string=rb_funcall(name,rb_intern("to_s"),0);
155
+ cname=STR2CSTR(name_string);
156
+
157
+ rClassDict=rb_iv_get(self,"@pclassdict");
158
+ rInstDict=rb_iv_get(self,"@pinstdict");
159
+ Data_Get_Struct(rClassDict,PObj,pClassDict);
160
+ Data_Get_Struct(rInstDict,PObj,pInstDict);
161
+ pCalled=PyDict_GetItemString(pInstDict->pObject,cname);
162
+ if(!pCalled)
163
+ {
164
+ pCalled=PyDict_GetItemString(pClassDict->pObject,cname);
165
+ }
166
+ Py_XINCREF(pCalled);
167
+ result=ptor_obj_no_destruct(pCalled);
168
+ if(rb_obj_is_instance_of(result,cRubyPyFunction))
169
+ {
170
+ Py_XINCREF(rp_obj_pobject(self));
171
+ rb_ary_unshift(args,self);
172
+ ret=rp_call_func(pCalled,args);
173
+ return ret;
174
+ }
175
+ return result;
176
+
177
+ }
178
+
82
179
 
83
180
  VALUE rp_cla_from_class(PyObject *pClass)
84
181
  {
85
182
  PObj* self;
86
183
  VALUE rClass=rb_class_new_instance(0,NULL,cRubyPyClass);
184
+ PyObject *pClassDict;
185
+ VALUE rDict;
87
186
  Data_Get_Struct(rClass,PObj,self);
88
187
  self->pObject=pClass;
188
+ pClassDict=PyObject_GetAttrString(pClass,"__dict__");
189
+ Py_XINCREF(pClassDict);
190
+ rDict=rp_obj_from_pyobject(pClassDict);
191
+ rb_iv_set(rClass,"@pdict",rDict);
89
192
  return rClass;
90
193
  }
91
194
 
@@ -114,6 +217,7 @@ VALUE rp_mod_call_func(VALUE self,VALUE func_name,VALUE args)
114
217
 
115
218
  }
116
219
 
220
+
117
221
  int rp_has_attr(VALUE self,VALUE func_name)
118
222
  {
119
223
 
@@ -135,7 +239,7 @@ VALUE rp_mod_init(VALUE self, VALUE mname)
135
239
  PyObject *pModuleDict;
136
240
  pModuleDict=PyModule_GetDict(cself->pObject);
137
241
  Py_XINCREF(pModuleDict);
138
- rDict=rp_cla_from_class(pModuleDict);
242
+ rDict=rp_obj_from_pyobject(pModuleDict);
139
243
  rb_iv_set(self,"@pdict",rDict);
140
244
  return self;
141
245
  }
@@ -149,10 +253,26 @@ int rp_is_func(VALUE pObj)
149
253
  return (PyFunction_Check(self->pObject)||PyMethod_Check(self->pObject));
150
254
  }
151
255
 
256
+ VALUE rp_cla_new_inst(VALUE self,VALUE args)
257
+ {
258
+ PyObject *pSelf;
259
+ pSelf=rp_obj_pobject(self);
260
+ return rp_call_func(pSelf,args);
261
+ }
262
+
263
+ VALUE rp_obj_responds(VALUE self,VALUE mname)
264
+ {
265
+ if(rp_has_attr(self,mname))
266
+ {
267
+ return Qtrue;
268
+ }
269
+ return Qfalse;
270
+ }
152
271
  //:nodoc:
153
272
  VALUE rp_mod_delegate(VALUE self,VALUE args)
154
273
  {
155
274
  VALUE name,name_string,rDict,result;
275
+ VALUE ret;
156
276
  PObj *pDict;
157
277
  PyObject *pCalled;
158
278
  if(!rp_has_attr(self,rb_ary_entry(args,0)))
@@ -167,14 +287,21 @@ VALUE rp_mod_delegate(VALUE self,VALUE args)
167
287
  }
168
288
  name=rb_ary_shift(args);
169
289
  name_string=rb_funcall(name,rb_intern("to_s"),0);
170
-
290
+
171
291
  rDict=rb_iv_get(self,"@pdict");
172
292
  Data_Get_Struct(rDict,PObj,pDict);
173
293
  pCalled=PyDict_GetItemString(pDict->pObject,STR2CSTR(name_string));
294
+ Py_XINCREF(pCalled);
174
295
  result=ptor_obj_no_destruct(pCalled);
175
296
  if(rb_obj_is_instance_of(result,cRubyPyFunction))
176
297
  {
177
- return rp_call_func(pCalled,args);
298
+ ret=rp_call_func(pCalled,args);
299
+ return ret;
300
+ }
301
+ else if(rb_obj_is_instance_of(result,cRubyPyClass)&&(rb_funcall(args,rb_intern("empty?"),0)==Qfalse)&&PyCallable_Check(pCalled))
302
+ {
303
+ ret=rp_call_func(pCalled,args);
304
+ return ret;
178
305
  }
179
306
  return result;
180
307
 
@@ -193,6 +320,7 @@ inline void Init_RubyPyObject()
193
320
  rb_define_alloc_func(cRubyPyObject,rp_obj_alloc);
194
321
  rb_define_method(cRubyPyObject,"free_pobj",rp_obj_free_pobj,0);
195
322
  rb_define_method(cRubyPyObject,"__name",rp_obj_name,0);
323
+ rb_define_method(cRubyPyObject,"respond_to?",rp_obj_responds,1);
196
324
 
197
325
  }
198
326
 
@@ -223,6 +351,8 @@ its existence.
223
351
  void Init_RubyPyClass()
224
352
  {
225
353
  cRubyPyClass=rb_define_class_under(mRubyPythonBridge,"RubyPyClass",cRubyPyObject);
354
+ rb_define_method(cRubyPyClass,"method_missing",rp_mod_delegate,-2);
355
+ rb_define_method(cRubyPyClass,"new",rp_cla_new_inst,-2);
226
356
  }
227
357
 
228
358
  //
@@ -234,4 +364,10 @@ void Init_RubyPyClass()
234
364
  void Init_RubyPyFunction()
235
365
  {
236
366
  cRubyPyFunction=rb_define_class_under(mRubyPythonBridge,"RubyPyFunction",cRubyPyObject);
367
+ }
368
+
369
+ void Init_RubyPyInstance()
370
+ {
371
+ cRubyPyInstance=rb_define_class_under(mRubyPythonBridge,"RubyPyInstance",cRubyPyObject);
372
+ rb_define_method(cRubyPyInstance,"method_missing",rp_inst_delegate,-2);
237
373
  }
@@ -43,4 +43,13 @@ int rp_is_func(VALUE pObj);
43
43
 
44
44
  VALUE rp_obj_from_pyobject(PyObject *pObj);
45
45
 
46
+ VALUE rp_inst_from_instance(PyObject *pInst);
47
+
48
+ VALUE rp_inst_delegate(VALUE self,VALUE args);
49
+
50
+ VALUE rp_cla_new_inst(VALUE self,VALUE args);
51
+
52
+ VALUE rp_obj_responds(VALUE self,VALUE mname);
53
+
54
+
46
55
  #endif /* _RP_OBJECT_H_ */
@@ -1,5 +1,7 @@
1
1
  #include "rtop.h"
2
2
 
3
+ extern VALUE cRubyPyObject;
4
+
3
5
  PyObject* rtop_string(VALUE rString)
4
6
  {
5
7
  PyObject* pString;
@@ -93,6 +95,7 @@ PyObject* rtop_symbol(VALUE rSymbol)
93
95
  return pString;
94
96
 
95
97
  }
98
+
96
99
  PyObject* rtop_obj(VALUE rObj,int is_key)
97
100
  {
98
101
  PyObject *pObj;
@@ -144,8 +147,15 @@ PyObject* rtop_obj(VALUE rObj,int is_key)
144
147
  break;
145
148
 
146
149
  default:
147
- rInspect=rb_inspect(rObj);
148
- pObj=rtop_string(rInspect);
150
+ if(rb_obj_is_kind_of(rObj,cRubyPyObject)==Qtrue)
151
+ {
152
+ pObj=rp_obj_pobject(rObj);
153
+ }
154
+ else
155
+ {
156
+ rInspect=rb_inspect(rObj);
157
+ pObj=rtop_string(rInspect);
158
+ }
149
159
  }
150
160
  return pObj;
151
161
  }
@@ -5,6 +5,15 @@ extern VALUE cRubyPyObject;
5
5
  extern VALUE cRubyPyModule;
6
6
  extern VALUE cRubyPyClass;
7
7
 
8
+
9
+ /*
10
+ call-seq: func(modname,funcname,*args)
11
+ Given a python module name _modname_ and a function name _funcname_ calls the given function
12
+ with the supplied arguments.
13
+
14
+ Use builtins as the module for a built in function.
15
+
16
+ */
8
17
  static VALUE func_with_module(VALUE self, VALUE args)
9
18
  {
10
19
  int started_here=safe_start();
@@ -17,40 +26,20 @@ static VALUE func_with_module(VALUE self, VALUE args)
17
26
  return return_val;
18
27
  }
19
28
 
20
- static VALUE rp_import_module(VALUE self,VALUE module)
21
- {
22
- VALUE instance=rb_class_instance_new(1,&module,cRubyPyModule);
23
- return instance;
24
- }
25
-
26
-
27
-
28
29
  /*
29
30
  * call-seq: import(modname)
30
31
  *
31
- * imports a python file_module using the interpreter and returns a ruby wrapper
32
-
32
+ * Imports the python module _modname_ using the interpreter and returns a ruby wrapper
33
33
  */
34
34
  static VALUE rp_import(VALUE self,VALUE mname)
35
35
  {
36
36
  return rb_class_new_instance(1,&mname,cRubyPyModule);
37
37
  }
38
38
 
39
- static VALUE rp_python_block(VALUE self)
40
- {
41
- rb_funcall(self,rb_intern("start"),0);
42
- rb_obj_instance_eval(0,NULL,self);
43
- rb_funcall(self,rb_intern("stop"),0);
44
-
45
- }
46
-
47
-
48
-
49
39
  /*
50
40
  * call-seq: start()
51
41
  *
52
42
  * Starts the python interpreter
53
- * RubyPythonBridge.start
54
43
  */
55
44
  VALUE rp_start(VALUE self)
56
45
  {
@@ -64,6 +53,11 @@ VALUE rp_start(VALUE self)
64
53
  return Qtrue;
65
54
  }
66
55
 
56
+ /*
57
+ * call-seq: stop()
58
+ *
59
+ * Stop the python interpreter
60
+ */
67
61
  VALUE rp_stop(VALUE self)
68
62
  {
69
63
 
@@ -87,14 +81,14 @@ void Init_rubypython_bridge()
87
81
  {
88
82
  mRubyPythonBridge=rb_define_module("RubyPythonBridge");
89
83
  rb_define_module_function(mRubyPythonBridge,"func",func_with_module,-2);
90
- rb_define_module_function(mRubyPythonBridge,"import_module",rp_import_module,1);
91
84
  rb_define_module_function(mRubyPythonBridge,"start",rp_start,0);
92
85
  rb_define_module_function(mRubyPythonBridge,"stop",rp_stop,0);
93
- rb_define_module_function(mRubyPythonBridge,"run",rp_python_block,0);
94
86
  rb_define_module_function(mRubyPythonBridge,"import",rp_import,1);
95
87
  Init_RubyPyObject();
96
88
  Init_RubyPyModule();
97
89
  Init_RubyPyClass();
98
90
  Init_RubyPyFunction();
99
91
  Init_RubyPyError();
92
+ Init_RubyPyInstance();
93
+
100
94
  }
data/lib/rubypython.rb CHANGED
@@ -77,7 +77,7 @@ module RubyPython
77
77
  # as the embedded interpreter will be halted at its end.
78
78
  def self.run(&block)
79
79
  start
80
- module_eval(&block)
80
+ module_eval(&block)
81
81
  stop
82
82
  end
83
83
 
@@ -2,7 +2,7 @@ module RubyPython
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 1
5
+ TINY = 2
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -1,6 +1,6 @@
1
1
  class RubyPythonBridge::RubyPyObject
2
2
  def inspect
3
- "<#{self.class}: #{__name}>"
3
+ "<#{self.class}:#{__name}>"
4
4
  end
5
5
  end
6
6
 
@@ -15,7 +15,7 @@ class RubyPythonBridge::RubyPyModule
15
15
  end
16
16
 
17
17
 
18
- # A wrapper class for Python classes and instances.
18
+ # A wrapper class for Python classes.
19
19
  #
20
20
  # This allows objects which cannot easily be converted to native Ruby types to still be accessible
21
21
  # from within ruby. Most users need not concern themselves with anything about this class except
@@ -31,4 +31,9 @@ end
31
31
  # This is used internally to aid RubyPyClass in delegating method calls.
32
32
  class RubyPythonBridge::RubyPyFunction
33
33
 
34
+ end
35
+
36
+ # A wrapper class for Python instances
37
+ class RubyPythonBridge::RubyPyInstance
38
+
34
39
  end
data/test/test.wav ADDED
Binary file
@@ -49,9 +49,19 @@ class TestRubypython < Test::Unit::TestCase
49
49
  unpickled=nil
50
50
  RubyPython.run do
51
51
  cPickle=import "cPickle"
52
+ cPickle.inspect
52
53
  unpickled=cPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns.")
53
54
  end
54
55
  assert_equal(unpickled,{"a"=>"n", [1, "2"]=>4})
55
56
  assert(!RubyPython.stop)
56
57
  end
58
+
59
+ def test_instance_method_delegation
60
+ RubyPython.start
61
+ wave=RubyPython.import "wave"
62
+ w=wave.open("test/test.wav","rb")
63
+ assert_equal(w.getframerate,9600)
64
+ w.close
65
+ RubyPython.stop
66
+ end
57
67
  end
@@ -3,29 +3,98 @@ require "test/unit"
3
3
  $:.unshift File.dirname(__FILE__) + "/../ext/rubypython_bridge"
4
4
  require "rubypython_bridge.so"
5
5
 
6
- class TestRubypythonBridgeExtn < Test::Unit::TestCase
6
+ class TestRubyPythonBridgeExtn < Test::Unit::TestCase
7
7
 
8
8
  def test_func_with_module
9
9
  pickle_return=RubyPythonBridge.func("cPickle","loads","(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns.")
10
10
  assert_equal(pickle_return,{"a"=>"n", [1, "2"]=>4})
11
11
  end
12
12
 
13
- def test_module_delegation
13
+ def test_start_stop
14
+ assert(RubyPythonBridge.start)
15
+ assert(!RubyPythonBridge.start)
16
+ assert(RubyPythonBridge.stop)
17
+ assert(!RubyPythonBridge.stop)
18
+ end
19
+
20
+ def test_new_instance
21
+ 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"))
25
+ RubyPythonBridge.stop
26
+ end
27
+
28
+ def test_new_instance_with_new_method
29
+ RubyPythonBridge.start
30
+ urllib2=RubyPythonBridge.import "urllib2"
31
+ assert_instance_of(RubyPythonBridge::RubyPyClass,urllib2.Request)
32
+ assert_instance_of(RubyPythonBridge::RubyPyInstance,urllib2.Request.new("google.com"))
33
+ RubyPythonBridge.stop
34
+ end
35
+
36
+ end
37
+
38
+ class TestRubyPythonBridgeWithCPickle < Test::Unit::TestCase
39
+ def setup
14
40
  RubyPythonBridge.start
15
- cPickle=RubyPythonBridge.import("cPickle")
16
- assert_instance_of(RubyPythonBridge::RubyPyModule,cPickle)
17
- assert_equal(cPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns."),{"a"=>"n", [1, "2"]=>4})
18
- dumped_array=cPickle.dumps([1,2,3,4])
19
- assert_equal(cPickle.loads(dumped_array),[1,2,3,4])
41
+ @cPickle=RubyPythonBridge.import "cPickle"
42
+ end
43
+
44
+ def teardown
45
+ ObjectSpace.each_object(RubyPythonBridge::RubyPyObject) do |o|
46
+ o.free_pobj
47
+ end
48
+ RubyPythonBridge.stop
49
+ end
50
+
51
+ def test_mod_respond_to
52
+ assert(@cPickle.respond_to? :loads)
53
+ end
54
+
55
+ def test_data_passing
56
+ assert_equal(@cPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns."),{"a"=>"n", [1, "2"]=>4})
57
+ dumped_array=@cPickle.dumps([1,2,3,4])
58
+ assert_equal(@cPickle.loads(dumped_array),[1,2,3,4])
59
+ end
60
+
61
+ def test_method_missing
20
62
  assert_raise NoMethodError do
21
- cPickle.splack
63
+ @cPickle.splack
22
64
  end
23
- assert_instance_of(RubyPythonBridge::RubyPyClass,cPickle.PicklingError)
24
- cPickle.free_pobj
65
+ end
66
+
67
+ def test_class_wrapping
68
+ assert_instance_of(RubyPythonBridge::RubyPyClass,@cPickle.PicklingError)
69
+ end
70
+
71
+ def test_module_method_wrapping
72
+ assert_instance_of(RubyPythonBridge::RubyPyModule,@cPickle)
73
+ end
74
+
75
+ end
76
+
77
+
78
+ class TestRubyPythonBridgeWithUrllib2 < Test::Unit::TestCase
79
+ def setup
80
+ RubyPythonBridge.start
81
+ @urllib2=RubyPythonBridge.import "urllib2"
82
+ end
83
+
84
+ def teardown
25
85
  ObjectSpace.each_object(RubyPythonBridge::RubyPyObject) do |o|
26
86
  o.free_pobj
27
87
  end
28
- assert(RubyPythonBridge.stop)
88
+ RubyPythonBridge.stop
29
89
  end
30
90
 
31
- end
91
+ def test_class_respond_to
92
+ assert(@urllib2.Request.respond_to? :get_data)
93
+ end
94
+
95
+ def test_instance_respond_to
96
+ assert(@urllib2.Request.new("google.com").respond_to? :get_data)
97
+ end
98
+
99
+ end
100
+
data/website/index.html CHANGED
@@ -33,22 +33,23 @@
33
33
  <h1>rubypython</h1>
34
34
  <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/rubypython"; return false'>
35
35
  <p>Get Version</p>
36
- <a href="http://rubyforge.org/projects/rubypython" class="numbers">0.2.0</a>
36
+ <a href="http://rubyforge.org/projects/rubypython" class="numbers">0.2.2</a>
37
37
  </div>
38
- <h1>&amp;#x2192; &#8216;rubypython&#8217;</h1>
39
- <h2>What</h2>
40
- <h2>Installing</h2>
38
+ <h2>What</h2>
39
+ <p>RubyPython is a C bridge between Ruby and Python with a Ruby interface. It&#8217;s aim is to make the power of the Python&#8217;s great standard library available to Ruby programmers from within Ruby.<br />
40
+ <br />
41
+ h2. Installing</p>
41
42
  <p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">rubypython</span></pre></p>
43
+ <p>Don&#8217;t worry if you got some ugly output from <span class="caps">RDOC</span> and RI.</p>
42
44
  <h2>The basics</h2>
43
- <h2>Demonstration of usage</h2>
45
+ <p>Check out the <span class="caps">RDOC</span> pages at <a href="http://rubypython.rubyforge.org/rdoc">http://rubypython.rubyforge.org/rdoc</a></p>
46
+ <p>I have only tested this on Mac OS 10.5 with Python 2.5. If anyone has issues with another setup let me know and I&#8217;ll do what I can.</p>
44
47
  <h2>Forum</h2>
45
48
  <p><a href="http://groups.google.com/group/rubypython">http://groups.google.com/group/rubypython</a></p>
46
49
  <h2>How to submit patches</h2>
47
50
  <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
48
- <p>You can fetch the source from either:</p>
49
- <ul>
50
- <li>rubyforge: <a href="http://rubyforge.org/scm/?group_id=6737">http://rubyforge.org/scm/?group_id=6737</a></li>
51
- </ul>
51
+ <p>You can fetch the source from:</p>
52
+ <p><a href="http://rubyforge.org/scm/?group_id=6737">http://rubyforge.org/scm/?group_id=6737</a></p>
52
53
  <pre>git clone git://rubyforge.org/rubypython.git</pre>
53
54
  <h3>Build and test instructions</h3>
54
55
  <pre>cd rubypython
@@ -59,7 +60,7 @@ rake install_gem</pre>
59
60
  <h2>Contact</h2>
60
61
  <p>Comments are welcome. Send an email to <a href="mailto:achatesavc+rubypython@gmail.com">Zach Raines</a> email via the <a href="http://groups.google.com/group/rubypython">forum</a></p>
61
62
  <p class="coda">
62
- <a href="FIXME email">FIXME full name</a>, 2nd August 2008<br>
63
+ <a href="mailto:achatesavc+rubypython@gmail.com">Zach Raines</a>, 7th August 2008<br>
63
64
  Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
64
65
  </p>
65
66
  </div>
data/website/index.txt CHANGED
@@ -1,20 +1,21 @@
1
1
  h1. rubypython
2
2
 
3
- h1. &#x2192; 'rubypython'
4
-
5
3
 
6
4
  h2. What
7
5
 
8
-
6
+ RubyPython is a C bridge between Ruby and Python with a Ruby interface. It's aim is to make the power of the Python's great standard library available to Ruby programmers from within Ruby.
7
+
9
8
  h2. Installing
10
9
 
11
10
  <pre syntax="ruby">sudo gem install rubypython</pre>
12
11
 
13
- h2. The basics
12
+ Don't worry if you got some ugly output from RDOC and RI.
14
13
 
14
+ h2. The basics
15
15
 
16
- h2. Demonstration of usage
16
+ Check out the RDOC pages at "http://rubypython.rubyforge.org/rdoc":http://rubypython.rubyforge.org/rdoc
17
17
 
18
+ I have only tested this on Mac OS 10.5 with Python 2.5. If anyone has issues with another setup let me know and I'll do what I can.
18
19
 
19
20
 
20
21
  h2. Forum
@@ -25,10 +26,9 @@ h2. How to submit patches
25
26
 
26
27
  Read the "8 steps for fixing other people's code":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/ and for section "8b: Submit patch to Google Groups":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups, use the Google Group above.
27
28
 
28
- You can fetch the source from either:
29
-
29
+ You can fetch the source from:
30
30
 
31
- * rubyforge: "http://rubyforge.org/scm/?group_id=6737":http://rubyforge.org/scm/?group_id=6737
31
+ "http://rubyforge.org/scm/?group_id=6737":http://rubyforge.org/scm/?group_id=6737
32
32
 
33
33
  <pre>git clone git://rubyforge.org/rubypython.git</pre>
34
34
 
@@ -37,7 +37,7 @@
37
37
  </div>
38
38
  <%= body %>
39
39
  <p class="coda">
40
- <a href="FIXME email">FIXME full name</a>, <%= modified.pretty %><br>
40
+ <a href="mailto:achatesavc+rubypython@gmail.com">Zach Raines</a>, <%= modified.pretty %><br>
41
41
  Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
42
42
  </p>
43
43
  </div>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubypython
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Raines
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-08-02 00:00:00 -04:00
12
+ date: 2008-08-07 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -51,7 +51,6 @@ files:
51
51
  - ext/rubypython_bridge/rtop.h
52
52
  - ext/rubypython_bridge/rubypython_bridge.c
53
53
  - ext/rubypython_bridge/rubypython_bridge.h
54
- - ext/rubypython_bridge/test.rb
55
54
  - lib/rubypython.rb
56
55
  - lib/rubypython/version.rb
57
56
  - lib/rubypython/wrapper_extensions.rb
@@ -65,6 +64,7 @@ files:
65
64
  - tasks/extconf.rake
66
65
  - tasks/extconf/rubypython_bridge.rake
67
66
  - tasks/website.rake
67
+ - test/test.wav
68
68
  - test/test_helper.rb
69
69
  - test/test_rubypython.rb
70
70
  - test/test_rubypython_bridge_extn.rb
@@ -77,10 +77,12 @@ has_rdoc: true
77
77
  homepage: http://rubypython.rubyforge.org
78
78
  post_install_message: |+
79
79
 
80
- For more information on rubypython, see http://rubypython.rubyforge.org
80
+ For more information on RubyPython, see http://rubypython.rubyforge.org
81
81
 
82
82
  If you find a bug, or have any suggestions, email me at: achatesavc+rubypython@gmail.com
83
83
 
84
+ If you would like to help develop RubyPython, also send me an email.
85
+
84
86
 
85
87
  rdoc_options:
86
88
  - --main
@@ -1,25 +0,0 @@
1
- require "rubypython_bridge"
2
- p RubyPythonBridge.func_with_module("cPickle","loads","(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns.")
3
- RubyPythonBridge.start
4
- CPickle=RubyPythonBridge.import("cPickle")
5
- p CPickle
6
- p CPickle.loads("(dp1\nS'a'\nS'n'\ns(I1\nS'2'\ntp2\nI4\ns.")
7
- p dumped_array=CPickle.dumps([1,2,3,4])
8
- p CPickle.loads(dumped_array)
9
- begin
10
- p CPickle.splack
11
- rescue
12
- p $!
13
- end
14
- p CPickle.PicklingError
15
- # p CPickle.instance_variable_get("@pdict")
16
- # CPickle.free_pobj
17
- ObjectSpace.each_object(RubyPythonBridge::RubyPyModule) do |o|
18
- o.free_pobj
19
- end
20
- p RubyPythonBridge.stop
21
-
22
- RubyPythonBridge.start
23
- RubyPythonBridge.import "urllib"
24
- RubyPythonBridge.import "cPickle"
25
- RubyPythonBridge.stop