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 +12 -0
- data/License.txt +1 -1
- data/Manifest.txt +1 -1
- data/PostInstall.txt +3 -1
- data/README.txt +3 -5
- data/ext/rubypython_bridge/cbridge.c +2 -4
- data/ext/rubypython_bridge/ptor.c +6 -1
- data/ext/rubypython_bridge/rp_error.c +1 -1
- data/ext/rubypython_bridge/rp_object.c +142 -6
- data/ext/rubypython_bridge/rp_object.h +9 -0
- data/ext/rubypython_bridge/rtop.c +12 -2
- data/ext/rubypython_bridge/rubypython_bridge.c +17 -23
- data/lib/rubypython.rb +1 -1
- data/lib/rubypython/version.rb +1 -1
- data/lib/rubypython/wrapper_extensions.rb +7 -2
- data/test/test.wav +0 -0
- data/test/test_rubypython.rb +10 -0
- data/test/test_rubypython_bridge_extn.rb +81 -12
- data/website/index.html +11 -10
- data/website/index.txt +8 -8
- data/website/template.html.erb +1 -1
- metadata +6 -4
- data/ext/rubypython_bridge/test.rb +0 -25
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
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
|
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
|
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=
|
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
|
-
|
66
|
-
|
67
|
-
|
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=
|
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
|
-
|
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
|
-
|
148
|
-
|
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
|
-
*
|
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
data/lib/rubypython/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class RubyPythonBridge::RubyPyObject
|
2
2
|
def inspect
|
3
|
-
"<#{self.class}
|
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
|
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
|
data/test/test_rubypython.rb
CHANGED
@@ -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
|
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
|
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
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
24
|
-
|
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
|
-
|
88
|
+
RubyPythonBridge.stop
|
29
89
|
end
|
30
90
|
|
31
|
-
|
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.
|
36
|
+
<a href="http://rubyforge.org/projects/rubypython" class="numbers">0.2.2</a>
|
37
37
|
</div>
|
38
|
-
<
|
39
|
-
<
|
40
|
-
<
|
38
|
+
<h2>What</h2>
|
39
|
+
<p>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.<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’t worry if you got some ugly output from <span class="caps">RDOC</span> and RI.</p>
|
42
44
|
<h2>The basics</h2>
|
43
|
-
<
|
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’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’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
|
49
|
-
<
|
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="
|
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. → '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
|
-
|
12
|
+
Don't worry if you got some ugly output from RDOC and RI.
|
14
13
|
|
14
|
+
h2. The basics
|
15
15
|
|
16
|
-
|
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
|
29
|
-
|
29
|
+
You can fetch the source from:
|
30
30
|
|
31
|
-
|
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
|
|
data/website/template.html.erb
CHANGED
@@ -37,7 +37,7 @@
|
|
37
37
|
</div>
|
38
38
|
<%= body %>
|
39
39
|
<p class="coda">
|
40
|
-
<a href="
|
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.
|
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-
|
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
|
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
|