rubypython 0.2.0

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 (46) hide show
  1. data/.autotest +9 -0
  2. data/History.txt +17 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +45 -0
  5. data/PostInstall.txt +6 -0
  6. data/README.txt +56 -0
  7. data/Rakefile +4 -0
  8. data/config/hoe.rb +73 -0
  9. data/config/requirements.rb +16 -0
  10. data/ext/rubypython_bridge/cbridge.c +149 -0
  11. data/ext/rubypython_bridge/cbridge.h +25 -0
  12. data/ext/rubypython_bridge/config.h +14 -0
  13. data/ext/rubypython_bridge/extconf.rb +7 -0
  14. data/ext/rubypython_bridge/ptor.c +178 -0
  15. data/ext/rubypython_bridge/ptor.h +31 -0
  16. data/ext/rubypython_bridge/rp_error.c +23 -0
  17. data/ext/rubypython_bridge/rp_error.h +8 -0
  18. data/ext/rubypython_bridge/rp_object.c +237 -0
  19. data/ext/rubypython_bridge/rp_object.h +46 -0
  20. data/ext/rubypython_bridge/rtop.c +151 -0
  21. data/ext/rubypython_bridge/rtop.h +22 -0
  22. data/ext/rubypython_bridge/rubypython_bridge.c +100 -0
  23. data/ext/rubypython_bridge/rubypython_bridge.h +7 -0
  24. data/ext/rubypython_bridge/test.rb +25 -0
  25. data/lib/rubypython.rb +84 -0
  26. data/lib/rubypython/version.rb +9 -0
  27. data/lib/rubypython/wrapper_extensions.rb +34 -0
  28. data/script/console +10 -0
  29. data/script/destroy +14 -0
  30. data/script/generate +14 -0
  31. data/script/txt2html +82 -0
  32. data/setup.rb +1585 -0
  33. data/tasks/deployment.rake +34 -0
  34. data/tasks/environment.rake +7 -0
  35. data/tasks/extconf.rake +13 -0
  36. data/tasks/extconf/rubypython_bridge.rake +49 -0
  37. data/tasks/website.rake +17 -0
  38. data/test/test_helper.rb +2 -0
  39. data/test/test_rubypython.rb +57 -0
  40. data/test/test_rubypython_bridge_extn.rb +31 -0
  41. data/website/index.html +83 -0
  42. data/website/index.txt +77 -0
  43. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  44. data/website/stylesheets/screen.css +138 -0
  45. data/website/template.html.erb +48 -0
  46. metadata +113 -0
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+
3
+ dir_config("rubypython_bridge")
4
+ find_library("python2.5",nil)
5
+ find_header("python2.5/Python.h")
6
+
7
+ create_makefile("rubypython_bridge")
@@ -0,0 +1,178 @@
1
+ #include "ptor.h"
2
+
3
+ VALUE ptor_string(PyObject* pString)
4
+ {
5
+ if(!PyString_Check(pString)) return Qnil;
6
+
7
+ char *cstr;
8
+ cstr=malloc(PyString_Size(pString)*sizeof(char));
9
+ strcpy(cstr,PyString_AsString(pString));
10
+ return rb_str_new2(cstr);
11
+ }
12
+
13
+ VALUE ptor_list(PyObject* pList)
14
+ {
15
+ if(!PyList_Check(pList)) return Qnil;
16
+ VALUE rArray;
17
+ VALUE rElement;
18
+ PyObject* element;
19
+ int i=0;
20
+
21
+ rArray=rb_ary_new();
22
+ int list_size=PyList_Size(pList);
23
+ for(i=0;i<list_size;i++)
24
+ {
25
+ element=PyList_GetItem(pList,i);
26
+ Py_INCREF(element);
27
+ rElement=ptor_obj(element);
28
+ rb_ary_push(rArray,rElement);
29
+ }
30
+ return rArray;
31
+ }
32
+
33
+ VALUE ptor_int(PyObject* pNum)
34
+ {
35
+ VALUE rNum;
36
+ if(!PyInt_Check(pNum)) return Qnil;
37
+ rNum=INT2NUM(PyInt_AsLong(pNum));
38
+ return rNum;
39
+
40
+ }
41
+
42
+ VALUE ptor_long(PyObject* pNum)
43
+ {
44
+ VALUE rNum;
45
+ long cNum;
46
+ if(!PyLong_Check(pNum)) return Qnil;
47
+ cNum=PyLong_AsLong(pNum);
48
+ if(PyErr_ExceptionMatches(PyExc_OverflowError))
49
+ {
50
+ raise_PyError();
51
+ return Qnil;
52
+ }
53
+ rNum=INT2NUM(cNum);
54
+ return rNum;
55
+
56
+ }
57
+
58
+ VALUE ptor_float(PyObject* pNum)
59
+ {
60
+ VALUE rNum;
61
+ if(!PyFloat_Check(pNum)) return Qnil;
62
+ rNum=rb_float_new(PyFloat_AsDouble(pNum));
63
+ return rNum;
64
+ }
65
+
66
+ VALUE ptor_tuple(PyObject* pTuple)
67
+ {
68
+ VALUE rArray;
69
+ PyObject* pList;
70
+ if(!PyTuple_Check(pTuple)) return Qnil;
71
+ pList=PySequence_List(pTuple);
72
+ rArray=ptor_list(pList);
73
+ Py_DECREF(pList);
74
+ return rArray;
75
+ }
76
+
77
+
78
+ VALUE ptor_dict(PyObject* pDict)
79
+ {
80
+ VALUE rHash;
81
+ if(!PyDict_Check(pDict)) return Qnil;
82
+ rHash=rb_hash_new();
83
+ PyObject *key,*val;
84
+ Py_ssize_t pos=0;
85
+ VALUE rKey,rVal;
86
+ while(PyDict_Next(pDict,&pos,&key,&val))
87
+ {
88
+ Py_XINCREF(key);
89
+ Py_XINCREF(val);
90
+ rKey=ptor_obj(key);
91
+ rVal=ptor_obj(val);
92
+ if(rKey==Qnil) continue;
93
+ rb_hash_aset(rHash,rKey,rVal);
94
+ }
95
+ return rHash;
96
+ }
97
+
98
+ static VALUE ptor_obj_core(PyObject *pObj,int destructive)
99
+ {
100
+ VALUE rObj;
101
+ if(PyObject_TypeCheck(pObj,&PyString_Type))
102
+ {
103
+ rObj=ptor_string(pObj);
104
+ if(destructive) Py_DECREF(pObj);
105
+ return rObj;
106
+ }
107
+
108
+ if(PyObject_TypeCheck(pObj,&PyList_Type))
109
+ {
110
+ rObj=ptor_list(pObj);
111
+ if(destructive) Py_DECREF(pObj);
112
+ return rObj;
113
+ }
114
+ if(PyObject_TypeCheck(pObj,&PyInt_Type))
115
+ {
116
+ rObj=ptor_int(pObj);
117
+ if(destructive) Py_DECREF(pObj);
118
+ return rObj;
119
+ }
120
+ if(PyObject_TypeCheck(pObj,&PyLong_Type))
121
+ {
122
+ rObj=ptor_long(pObj);
123
+ if(destructive) Py_DECREF(pObj);
124
+ return rObj;
125
+ }
126
+ if(PyObject_TypeCheck(pObj,&PyFloat_Type))
127
+ {
128
+ rObj=ptor_float(pObj);
129
+ if(destructive) Py_DECREF(pObj);
130
+ return rObj;
131
+ }
132
+ if(PyObject_TypeCheck(pObj,&PyTuple_Type))
133
+ {
134
+ rObj=ptor_tuple(pObj);
135
+ if(destructive) Py_DECREF(pObj);
136
+ return rObj;
137
+ }
138
+ if(PyObject_TypeCheck(pObj,&PyDict_Type))
139
+ {
140
+ rObj=ptor_dict(pObj);
141
+ if(destructive) Py_DECREF(pObj);
142
+ return rObj;
143
+ }
144
+
145
+ if(pObj==Py_True)
146
+ {
147
+ if(destructive) Py_DECREF(Py_True);
148
+ return Qtrue;
149
+ }
150
+ if(pObj==Py_False)
151
+ {
152
+ if(destructive) Py_DECREF(Py_False);
153
+ return Qfalse;
154
+ }
155
+ if(pObj==Py_None)
156
+ {
157
+ return Qnil;
158
+ }
159
+ if(PyFunction_Check(pObj)||PyMethod_Check(pObj)||!PyObject_HasAttrString(pObj,"__dict__"))
160
+ {
161
+ return rp_func_from_function(pObj);
162
+
163
+ }
164
+ return rp_cla_from_class(pObj);
165
+ }
166
+ VALUE ptor_obj_no_destruct(PyObject *pObj)
167
+ {
168
+ VALUE rObj;
169
+ rObj=ptor_obj_core(pObj,0);
170
+ return rObj;
171
+ }
172
+ VALUE ptor_obj(PyObject* pObj)
173
+ {
174
+ VALUE rObj;
175
+ rObj=ptor_obj_core(pObj,1);
176
+ return rObj;
177
+ }
178
+
@@ -0,0 +1,31 @@
1
+ #include "config.h"
2
+
3
+ #ifndef _RP_ERROR_H_
4
+ #include "rp_error.h"
5
+ #endif
6
+
7
+ #ifndef _PTOR_H_
8
+ #define _PTOR_H_
9
+
10
+ //Python to Ruby Conversion
11
+ VALUE ptor_string(PyObject* pString);
12
+
13
+ VALUE ptor_list(PyObject* pList);
14
+
15
+ VALUE ptor_obj(PyObject* pObj);
16
+
17
+ VALUE ptor_int(PyObject* pNum);
18
+
19
+ VALUE ptor_long(PyObject* pNum);
20
+
21
+ VALUE ptor_float(PyObject* pNum);
22
+
23
+ VALUE ptor_tuple(PyObject* pTuple);
24
+
25
+ VALUE ptor_dict(PyObject* pDict);
26
+
27
+ VALUE ptor_obj_no_destruct(PyObject *pObj);
28
+
29
+
30
+
31
+ #endif /* _PTOR_H_ */
@@ -0,0 +1,23 @@
1
+ #include "rp_error.h"
2
+
3
+ VALUE ePythonError;
4
+
5
+ void rp_pythonerror()
6
+ {
7
+ PyObject *pType,*pValue,*pTraceback;
8
+ PyObject *pTypeName;
9
+ PyErr_Fetch(&pType,&pValue,&pTraceback);
10
+ pTypeName=PyObject_GetAttrString(pType,"__name__");
11
+ Py_XDECREF(pType);
12
+ rb_raise(ePythonError,"%s:(%s)\n",STR2CSTR(ptor_obj(pTypeName)),STR2CSTR(ptor_obj(pValue)));
13
+ Py_XDECREF(pTraceback);
14
+ }
15
+
16
+ /*
17
+ Used to pass error information back into Ruby should an error occur in the embedded Python
18
+ interpreter.
19
+ */
20
+ void Init_RubyPyError()
21
+ {
22
+ ePythonError=rb_define_class("PythonError",rb_eException);
23
+ }
@@ -0,0 +1,8 @@
1
+ #include "config.h"
2
+
3
+ #ifndef _RP_ERROR_H_
4
+ #define _RP_ERROR_H_
5
+
6
+ void rp_pythonerror();
7
+
8
+ #endif /* _RP_ERROR_H_ */
@@ -0,0 +1,237 @@
1
+ #include "rp_object.h"
2
+ #include "stdio.h"
3
+
4
+ extern VALUE mRubyPythonBridge;
5
+
6
+ VALUE cRubyPyObject;
7
+ VALUE cRubyPyModule;
8
+ VALUE cRubyPyClass;
9
+ VALUE cRubyPyFunction;
10
+
11
+ void rp_obj_mark(PObj* self)
12
+ {}
13
+
14
+ void rp_obj_free(PObj* self)
15
+ {
16
+ if(Py_IsInitialized()&&self->pObject)
17
+ {
18
+ Py_XDECREF(self->pObject);
19
+ }
20
+ free(self);
21
+ }
22
+
23
+
24
+ /*
25
+ Decreases the reference count on the object wrapped by this instance.
26
+ This is used for cleanup in RubyPython.stop. RubyPyObject instance automatically
27
+ decrease the reference count on their associated objects before they are garbage collected.
28
+ */
29
+ VALUE rp_obj_free_pobj(VALUE self)
30
+ {
31
+ PObj *cself;
32
+ Data_Get_Struct(self,PObj,cself);
33
+ if(Py_IsInitialized()&&cself->pObject)
34
+ {
35
+ Py_XDECREF(cself->pObject);
36
+ cself->pObject=NULL;
37
+ return Qtrue;
38
+ }
39
+ return Qfalse;
40
+ }
41
+
42
+ VALUE rp_obj_alloc(VALUE klass)
43
+ {
44
+ PObj* self=ALLOC(PObj);
45
+ self->pObject=NULL;
46
+ return Data_Wrap_Struct(klass,rp_obj_mark,rp_obj_free,self);
47
+ }
48
+
49
+
50
+ PyObject* rp_obj_pobject(VALUE self)
51
+ {
52
+ PObj *cself;
53
+ Data_Get_Struct(self,PObj,cself);
54
+ return cself->pObject;
55
+ }
56
+
57
+ /*
58
+ Returns the name of the Python object which this instance wraps.
59
+
60
+ */
61
+ VALUE rp_obj_name(VALUE self)
62
+ {
63
+ if(Py_IsInitialized())
64
+ {
65
+ PyObject *pObject;
66
+ pObject=rp_obj_pobject(self);
67
+ return ptor_obj(PyObject_GetAttrString(pObject,"__name__"));
68
+ }
69
+ return rb_str_new2("__FREED__");
70
+
71
+ }
72
+
73
+ VALUE rp_obj_from_pyobject(PyObject *pObj)
74
+ {
75
+ PObj* self;
76
+ VALUE rObj=rb_class_new_instance(0,NULL,cRubyPyObject);
77
+ Data_Get_Struct(rObj,PObj,self);
78
+ self->pObject=pObj;
79
+ return rObj;
80
+ }
81
+
82
+
83
+ VALUE rp_cla_from_class(PyObject *pClass)
84
+ {
85
+ PObj* self;
86
+ VALUE rClass=rb_class_new_instance(0,NULL,cRubyPyClass);
87
+ Data_Get_Struct(rClass,PObj,self);
88
+ self->pObject=pClass;
89
+ return rClass;
90
+ }
91
+
92
+ VALUE rp_func_from_function(PyObject *pFunc)
93
+ {
94
+ PObj* self;
95
+ VALUE rFunc=rb_class_new_instance(0,NULL,cRubyPyFunction);
96
+ Data_Get_Struct(rFunc,PObj,self);
97
+ self->pObject=pFunc;
98
+ return rFunc;
99
+ }
100
+
101
+ VALUE rp_mod_call_func(VALUE self,VALUE func_name,VALUE args)
102
+ {
103
+ PObj *cself;
104
+ Data_Get_Struct(self,PObj,cself);
105
+ PyObject *pModule,*pFunc;
106
+ VALUE rReturn;
107
+
108
+ pModule=cself->pObject;
109
+ pFunc=rp_get_func_with_module(pModule,func_name);
110
+ rReturn=rp_call_func(pFunc,args);
111
+ Py_XDECREF(pFunc);
112
+
113
+ return rReturn;
114
+
115
+ }
116
+
117
+ int rp_has_attr(VALUE self,VALUE func_name)
118
+ {
119
+
120
+ PObj *cself;
121
+ VALUE rName;
122
+ Data_Get_Struct(self,PObj,cself);
123
+ rName=rb_funcall(func_name,rb_intern("to_s"),0);
124
+ if(PyObject_HasAttrString(cself->pObject,STR2CSTR(rName))) return 1;
125
+ return 0;
126
+ }
127
+
128
+ //:nodoc:
129
+ VALUE rp_mod_init(VALUE self, VALUE mname)
130
+ {
131
+ PObj* cself;
132
+ Data_Get_Struct(self,PObj,cself);
133
+ cself->pObject=rp_get_module(mname);
134
+ VALUE rDict;
135
+ PyObject *pModuleDict;
136
+ pModuleDict=PyModule_GetDict(cself->pObject);
137
+ Py_XINCREF(pModuleDict);
138
+ rDict=rp_cla_from_class(pModuleDict);
139
+ rb_iv_set(self,"@pdict",rDict);
140
+ return self;
141
+ }
142
+
143
+ //Not completely accurate
144
+ int rp_is_func(VALUE pObj)
145
+ {
146
+ PObj* self;
147
+ Data_Get_Struct(pObj,PObj,self);
148
+ Py_XINCREF(self->pObject);
149
+ return (PyFunction_Check(self->pObject)||PyMethod_Check(self->pObject));
150
+ }
151
+
152
+ //:nodoc:
153
+ VALUE rp_mod_delegate(VALUE self,VALUE args)
154
+ {
155
+ VALUE name,name_string,rDict,result;
156
+ PObj *pDict;
157
+ PyObject *pCalled;
158
+ if(!rp_has_attr(self,rb_ary_entry(args,0)))
159
+ {
160
+ int argc;
161
+
162
+ VALUE *argv;
163
+ argc=RARRAY(args)->len;
164
+ argv=ALLOC_N(VALUE,argc);
165
+ MEMCPY(argv,RARRAY(args)->ptr,VALUE,argc);
166
+ return rb_call_super(argc,argv);
167
+ }
168
+ name=rb_ary_shift(args);
169
+ name_string=rb_funcall(name,rb_intern("to_s"),0);
170
+
171
+ rDict=rb_iv_get(self,"@pdict");
172
+ Data_Get_Struct(rDict,PObj,pDict);
173
+ pCalled=PyDict_GetItemString(pDict->pObject,STR2CSTR(name_string));
174
+ result=ptor_obj_no_destruct(pCalled);
175
+ if(rb_obj_is_instance_of(result,cRubyPyFunction))
176
+ {
177
+ return rp_call_func(pCalled,args);
178
+ }
179
+ return result;
180
+
181
+ }
182
+
183
+ /*
184
+ A wrapper class for Python objects that allows them to manipulated from within ruby.
185
+
186
+ Important wrapper functionality is found in the RubyPyModule, RubyPyClass, and RubyPyFunction
187
+ classes which wrap Python objects of similar names.
188
+
189
+ */
190
+ inline void Init_RubyPyObject()
191
+ {
192
+ cRubyPyObject=rb_define_class_under(mRubyPythonBridge,"RubyPyObject",rb_cObject);
193
+ rb_define_alloc_func(cRubyPyObject,rp_obj_alloc);
194
+ rb_define_method(cRubyPyObject,"free_pobj",rp_obj_free_pobj,0);
195
+ rb_define_method(cRubyPyObject,"__name",rp_obj_name,0);
196
+
197
+ }
198
+
199
+
200
+ /*
201
+ A wrapper class for Python Modules.
202
+
203
+ Methods calls are delegated to the equivalent Python methods/functions. Attribute references
204
+ return either the equivalent attribute converted to a native Ruby type, or wrapped reference
205
+ to a Python object. RubyPyModule instances should be created through the use of RubyPython.import.
206
+
207
+ */
208
+ void Init_RubyPyModule()
209
+ {
210
+ cRubyPyModule=rb_define_class_under(mRubyPythonBridge,"RubyPyModule",cRubyPyObject);
211
+ rb_define_method(cRubyPyModule,"initialize",rp_mod_init,1);
212
+ rb_define_method(cRubyPyModule,"method_missing",rp_mod_delegate,-2);
213
+ }
214
+
215
+ /*
216
+ A wrapper class for Python classes and instances.
217
+
218
+ This allows objects which cannot easily be converted to native Ruby types to still be accessible
219
+ from within ruby. Most users need not concern themselves with anything about this class except
220
+ its existence.
221
+
222
+ */
223
+ void Init_RubyPyClass()
224
+ {
225
+ cRubyPyClass=rb_define_class_under(mRubyPythonBridge,"RubyPyClass",cRubyPyObject);
226
+ }
227
+
228
+ //
229
+ // A wrapper class for Python functions and methods.
230
+ //
231
+ // This is used internally to aid RubyPyClass in delegating method calls.
232
+ //
233
+
234
+ void Init_RubyPyFunction()
235
+ {
236
+ cRubyPyFunction=rb_define_class_under(mRubyPythonBridge,"RubyPyFunction",cRubyPyObject);
237
+ }