rubypython 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +9 -0
- data/History.txt +17 -0
- data/License.txt +20 -0
- data/Manifest.txt +45 -0
- data/PostInstall.txt +6 -0
- data/README.txt +56 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +73 -0
- data/config/requirements.rb +16 -0
- data/ext/rubypython_bridge/cbridge.c +149 -0
- data/ext/rubypython_bridge/cbridge.h +25 -0
- data/ext/rubypython_bridge/config.h +14 -0
- data/ext/rubypython_bridge/extconf.rb +7 -0
- data/ext/rubypython_bridge/ptor.c +178 -0
- data/ext/rubypython_bridge/ptor.h +31 -0
- data/ext/rubypython_bridge/rp_error.c +23 -0
- data/ext/rubypython_bridge/rp_error.h +8 -0
- data/ext/rubypython_bridge/rp_object.c +237 -0
- data/ext/rubypython_bridge/rp_object.h +46 -0
- data/ext/rubypython_bridge/rtop.c +151 -0
- data/ext/rubypython_bridge/rtop.h +22 -0
- data/ext/rubypython_bridge/rubypython_bridge.c +100 -0
- data/ext/rubypython_bridge/rubypython_bridge.h +7 -0
- data/ext/rubypython_bridge/test.rb +25 -0
- data/lib/rubypython.rb +84 -0
- data/lib/rubypython/version.rb +9 -0
- data/lib/rubypython/wrapper_extensions.rb +34 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/extconf.rake +13 -0
- data/tasks/extconf/rubypython_bridge.rake +49 -0
- data/tasks/website.rake +17 -0
- data/test/test_helper.rb +2 -0
- data/test/test_rubypython.rb +57 -0
- data/test/test_rubypython_bridge_extn.rb +31 -0
- data/website/index.html +83 -0
- data/website/index.txt +77 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.html.erb +48 -0
- metadata +113 -0
@@ -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,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
|
+
}
|