rubypython 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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