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,46 @@
|
|
1
|
+
#include "config.h"
|
2
|
+
#include "ptor.h"
|
3
|
+
#include "rtop.h"
|
4
|
+
#include "cbridge.h"
|
5
|
+
|
6
|
+
#ifndef _RP_OBJECT_H_
|
7
|
+
#define _RP_OBJECT_H_
|
8
|
+
|
9
|
+
struct RubyPyObj
|
10
|
+
{
|
11
|
+
PyObject* pObject;
|
12
|
+
};
|
13
|
+
|
14
|
+
typedef struct RubyPyObj PObj;
|
15
|
+
|
16
|
+
void rp_obj_mark(PObj* self);
|
17
|
+
|
18
|
+
void rp_obj_free(PObj* self);
|
19
|
+
|
20
|
+
VALUE rp_obj_alloc(VALUE klass);
|
21
|
+
|
22
|
+
PyObject* rp_obj_pobject(VALUE self);
|
23
|
+
|
24
|
+
VALUE rp_obj_name(VALUE self);
|
25
|
+
|
26
|
+
|
27
|
+
//Ruby wrapper for Python Modules
|
28
|
+
VALUE rp_mod_init(VALUE self,VALUE mname);
|
29
|
+
|
30
|
+
int rp_has_attr(VALUE self,ID func_hame);
|
31
|
+
|
32
|
+
VALUE rp_mod_call_func(VALUE self,VALUE func_name,VALUE args);
|
33
|
+
|
34
|
+
VALUE rp_mod_delegate(VALUE self,VALUE args);
|
35
|
+
|
36
|
+
//Ruby wrapper for Python classes
|
37
|
+
|
38
|
+
VALUE rp_cla_from_class(PyObject *pClass);
|
39
|
+
|
40
|
+
VALUE rp_func_from_function(PyObject *pFunc);
|
41
|
+
|
42
|
+
int rp_is_func(VALUE pObj);
|
43
|
+
|
44
|
+
VALUE rp_obj_from_pyobject(PyObject *pObj);
|
45
|
+
|
46
|
+
#endif /* _RP_OBJECT_H_ */
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#include "rtop.h"
|
2
|
+
|
3
|
+
PyObject* rtop_string(VALUE rString)
|
4
|
+
{
|
5
|
+
PyObject* pString;
|
6
|
+
char *cString;
|
7
|
+
char *cStringCopy;
|
8
|
+
cString=STR2CSTR(rString);
|
9
|
+
cStringCopy=malloc(strlen(cString)*sizeof(char));
|
10
|
+
strcpy(cStringCopy,cString);
|
11
|
+
pString=PyString_FromString(cStringCopy);
|
12
|
+
return pString;
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
PyObject* rtop_array_list(VALUE rArray)
|
17
|
+
{
|
18
|
+
PyObject* pList;
|
19
|
+
int size=RARRAY(rArray)->len;
|
20
|
+
pList=PyList_New(size);
|
21
|
+
int i;
|
22
|
+
for(i=0;i<size;i++)
|
23
|
+
{
|
24
|
+
PyList_SetItem(pList,i,rtop_obj(rb_ary_entry(rArray,i),0));
|
25
|
+
}
|
26
|
+
return pList;
|
27
|
+
}
|
28
|
+
|
29
|
+
PyObject* rtop_array_tuple(VALUE rArray)
|
30
|
+
{
|
31
|
+
PyObject *pTuple,*pList;
|
32
|
+
pList=rtop_array_list(rArray);
|
33
|
+
pTuple=PySequence_Tuple(pList);
|
34
|
+
Py_XDECREF(pList);
|
35
|
+
return pTuple;
|
36
|
+
}
|
37
|
+
|
38
|
+
PyObject* rtop_hash(VALUE rHash)
|
39
|
+
{
|
40
|
+
PyObject *pDict,*pKey,*pVal;
|
41
|
+
VALUE rKeys=rb_funcall(rHash,rb_intern("keys"),0);
|
42
|
+
VALUE rKey,rVal;
|
43
|
+
int i;
|
44
|
+
|
45
|
+
pDict=PyDict_New();
|
46
|
+
for(i=0;i<RARRAY(rKeys)->len;i++)
|
47
|
+
{
|
48
|
+
rKey=rb_ary_entry(rKeys,i);
|
49
|
+
rVal=rb_hash_aref(rHash,rKey);
|
50
|
+
PyDict_SetItem(pDict,rtop_obj(rKey,1),rtop_obj(rVal,0));
|
51
|
+
}
|
52
|
+
return pDict;
|
53
|
+
}
|
54
|
+
|
55
|
+
PyObject* rtop_fixnum(VALUE rNum)
|
56
|
+
{
|
57
|
+
PyObject* pNum;
|
58
|
+
long cNum=NUM2LONG(rNum);
|
59
|
+
pNum=PyInt_FromLong(cNum);
|
60
|
+
return pNum;
|
61
|
+
}
|
62
|
+
|
63
|
+
PyObject* rtop_bignum(VALUE rNum)
|
64
|
+
{
|
65
|
+
PyObject* pNum;
|
66
|
+
long cNum=NUM2LONG(rNum);
|
67
|
+
pNum=PyLong_FromLong(cNum);
|
68
|
+
return pNum;
|
69
|
+
}
|
70
|
+
|
71
|
+
PyObject* rtop_float(VALUE rNum)
|
72
|
+
{
|
73
|
+
PyObject* pNum;
|
74
|
+
double cNum=NUM2DBL(rNum);
|
75
|
+
pNum=PyFloat_FromDouble(cNum);
|
76
|
+
return pNum;
|
77
|
+
}
|
78
|
+
|
79
|
+
PyObject* rtop_false()
|
80
|
+
{
|
81
|
+
Py_RETURN_FALSE;
|
82
|
+
}
|
83
|
+
|
84
|
+
PyObject* rtop_true()
|
85
|
+
{
|
86
|
+
Py_RETURN_TRUE;
|
87
|
+
}
|
88
|
+
|
89
|
+
PyObject* rtop_symbol(VALUE rSymbol)
|
90
|
+
{
|
91
|
+
PyObject* pString;
|
92
|
+
pString=PyString_FromString(rb_id2name(rSymbol));
|
93
|
+
return pString;
|
94
|
+
|
95
|
+
}
|
96
|
+
PyObject* rtop_obj(VALUE rObj,int is_key)
|
97
|
+
{
|
98
|
+
PyObject *pObj;
|
99
|
+
VALUE rInspect;
|
100
|
+
switch(TYPE(rObj))
|
101
|
+
{
|
102
|
+
case T_STRING:
|
103
|
+
pObj=rtop_string(rObj);
|
104
|
+
break;
|
105
|
+
|
106
|
+
case T_ARRAY:
|
107
|
+
if(is_key) pObj=rtop_array_tuple(rObj);
|
108
|
+
else
|
109
|
+
{
|
110
|
+
pObj=rtop_array_list(rObj);
|
111
|
+
}
|
112
|
+
break;
|
113
|
+
|
114
|
+
case T_HASH:
|
115
|
+
pObj=rtop_hash(rObj);
|
116
|
+
break;
|
117
|
+
|
118
|
+
case T_FIXNUM:
|
119
|
+
pObj=rtop_fixnum(rObj);
|
120
|
+
break;
|
121
|
+
|
122
|
+
case T_BIGNUM:
|
123
|
+
pObj=rtop_bignum(rObj);
|
124
|
+
break;
|
125
|
+
|
126
|
+
case T_FLOAT:
|
127
|
+
pObj=rtop_float(rObj);
|
128
|
+
break;
|
129
|
+
|
130
|
+
case T_NIL:
|
131
|
+
pObj=Py_None;
|
132
|
+
break;
|
133
|
+
|
134
|
+
case T_TRUE:
|
135
|
+
pObj=rtop_true();
|
136
|
+
break;
|
137
|
+
|
138
|
+
case T_FALSE:
|
139
|
+
pObj=rtop_false();
|
140
|
+
break;
|
141
|
+
|
142
|
+
case T_SYMBOL:
|
143
|
+
pObj=rtop_symbol(rObj);
|
144
|
+
break;
|
145
|
+
|
146
|
+
default:
|
147
|
+
rInspect=rb_inspect(rObj);
|
148
|
+
pObj=rtop_string(rInspect);
|
149
|
+
}
|
150
|
+
return pObj;
|
151
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#include "config.h"
|
2
|
+
|
3
|
+
#ifndef _RP_ERROR_H_
|
4
|
+
#include "rp_error.h"
|
5
|
+
#endif
|
6
|
+
|
7
|
+
#ifndef _RTOP_H_
|
8
|
+
#define _RTOP_H_
|
9
|
+
PyObject* rtop_string(VALUE rString);
|
10
|
+
PyObject* rtop_array_list(VALUE rArray);
|
11
|
+
PyObject* rtop_array_tuple(VALUE rArray);
|
12
|
+
PyObject* rtop_hash(VALUE rHash);
|
13
|
+
PyObject* rtop_fixnum(VALUE rNum);
|
14
|
+
PyObject* rtop_bignum(VALUE rNum);
|
15
|
+
PyObject* rtop_float(VALUE rNum);
|
16
|
+
PyObject* rtop_false(void);
|
17
|
+
PyObject* rtop_true(void);
|
18
|
+
PyObject* rtop_symbol(VALUE rSymbol);
|
19
|
+
|
20
|
+
PyObject* rtop_obj(VALUE rObj,int is_key);
|
21
|
+
|
22
|
+
#endif /* _RTOP_H_ */
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#include "rubypython_bridge.h"
|
2
|
+
|
3
|
+
VALUE mRubyPythonBridge;
|
4
|
+
extern VALUE cRubyPyObject;
|
5
|
+
extern VALUE cRubyPyModule;
|
6
|
+
extern VALUE cRubyPyClass;
|
7
|
+
|
8
|
+
static VALUE func_with_module(VALUE self, VALUE args)
|
9
|
+
{
|
10
|
+
int started_here=safe_start();
|
11
|
+
VALUE module,func,return_val;
|
12
|
+
if(RARRAY(args)->len<2) return Qfalse;
|
13
|
+
module=rb_ary_shift(args);
|
14
|
+
func=rb_ary_shift(args);
|
15
|
+
return_val=rp_call_func_with_module_name(module,func,args);
|
16
|
+
safe_stop(started_here);
|
17
|
+
return return_val;
|
18
|
+
}
|
19
|
+
|
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
|
+
* call-seq: import(modname)
|
30
|
+
*
|
31
|
+
* imports a python file_module using the interpreter and returns a ruby wrapper
|
32
|
+
|
33
|
+
*/
|
34
|
+
static VALUE rp_import(VALUE self,VALUE mname)
|
35
|
+
{
|
36
|
+
return rb_class_new_instance(1,&mname,cRubyPyModule);
|
37
|
+
}
|
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
|
+
/*
|
50
|
+
* call-seq: start()
|
51
|
+
*
|
52
|
+
* Starts the python interpreter
|
53
|
+
* RubyPythonBridge.start
|
54
|
+
*/
|
55
|
+
VALUE rp_start(VALUE self)
|
56
|
+
{
|
57
|
+
|
58
|
+
|
59
|
+
if(Py_IsInitialized())
|
60
|
+
{
|
61
|
+
return Qfalse;
|
62
|
+
}
|
63
|
+
Py_Initialize();
|
64
|
+
return Qtrue;
|
65
|
+
}
|
66
|
+
|
67
|
+
VALUE rp_stop(VALUE self)
|
68
|
+
{
|
69
|
+
|
70
|
+
if(Py_IsInitialized())
|
71
|
+
{
|
72
|
+
Py_Finalize();
|
73
|
+
return Qtrue;
|
74
|
+
}
|
75
|
+
return Qfalse;
|
76
|
+
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
/*
|
81
|
+
* Module containing an interface to the the python interpreter.
|
82
|
+
*
|
83
|
+
* Use RubyPython instead.
|
84
|
+
*/
|
85
|
+
|
86
|
+
void Init_rubypython_bridge()
|
87
|
+
{
|
88
|
+
mRubyPythonBridge=rb_define_module("RubyPythonBridge");
|
89
|
+
rb_define_module_function(mRubyPythonBridge,"func",func_with_module,-2);
|
90
|
+
rb_define_module_function(mRubyPythonBridge,"import_module",rp_import_module,1);
|
91
|
+
rb_define_module_function(mRubyPythonBridge,"start",rp_start,0);
|
92
|
+
rb_define_module_function(mRubyPythonBridge,"stop",rp_stop,0);
|
93
|
+
rb_define_module_function(mRubyPythonBridge,"run",rp_python_block,0);
|
94
|
+
rb_define_module_function(mRubyPythonBridge,"import",rp_import,1);
|
95
|
+
Init_RubyPyObject();
|
96
|
+
Init_RubyPyModule();
|
97
|
+
Init_RubyPyClass();
|
98
|
+
Init_RubyPyFunction();
|
99
|
+
Init_RubyPyError();
|
100
|
+
}
|
@@ -0,0 +1,25 @@
|
|
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
|
data/lib/rubypython.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'rubypython_bridge.so'
|
2
|
+
require 'wrapper_extension'
|
3
|
+
|
4
|
+
|
5
|
+
=begin rdoc
|
6
|
+
This module provides the direct user interface for the RubyPython extension.
|
7
|
+
|
8
|
+
The majority of the functionality lies in the _RubyPythonBridge_ module, which is provided
|
9
|
+
by the C extension. However, the end user should only worry about dealing with the RubyPython
|
10
|
+
module as that is designed for user interaction. Furthermore the RubyPythonBridge is somewhat
|
11
|
+
bad with memory management and using it directly may result in some strange crashes.
|
12
|
+
|
13
|
+
==Usage
|
14
|
+
It is important to remember that the Python Interpreter must be started before the bridge
|
15
|
+
is functional. This may be done by two methods. One is to use the +start+ function.
|
16
|
+
This will start the embedded interpreter. If this approach is used, the user should
|
17
|
+
remember to call RubyPython.stop when they are finished with Python.
|
18
|
+
Example:
|
19
|
+
RubyPython.start
|
20
|
+
cPickle=RubyPython.import "cPickle"
|
21
|
+
puts cPickle.dumps "RubyPython is awesome!"
|
22
|
+
RubyPython.stop
|
23
|
+
|
24
|
+
The other method is preferable if one wants a simpler approach. This other method is to use
|
25
|
+
<tt>RubyPython.run</tt>. run takes a block which is evaluated in the scope of the RubyPython module.
|
26
|
+
In addition, the interpreter is started before the block is run and halted at its completion.
|
27
|
+
This allows one to do something like the following:
|
28
|
+
RubyPython.run do
|
29
|
+
cPickle=import "cPickle"
|
30
|
+
puts cPickle.dumps "RubyPython is still awesome!"
|
31
|
+
end
|
32
|
+
|
33
|
+
==Errors
|
34
|
+
The RubyPythonModule defines a new error object, PythonError. Should any error occur within
|
35
|
+
the Python interpreter, the class and value of the error will be passed back into ruby within
|
36
|
+
the text of the raised PythonError.
|
37
|
+
irb(main):001:0> RubyPython.start
|
38
|
+
=> true
|
39
|
+
irb(main):002:0> RubyPython.import "does not exist"
|
40
|
+
PythonError: ImportError:(No module named does not exist)
|
41
|
+
|
42
|
+
from ./rubypython.rb:66:in `initialize'
|
43
|
+
from ./rubypython.rb:66:in `import'
|
44
|
+
from ./rubypython.rb:66:in `import'
|
45
|
+
from (irb):2
|
46
|
+
=end
|
47
|
+
module RubyPython
|
48
|
+
|
49
|
+
# Used to started the python interpreter. Delegates to RubyPythonBridge
|
50
|
+
#
|
51
|
+
# RubyPython.start
|
52
|
+
# --Some python code--
|
53
|
+
# RubyPython.stop
|
54
|
+
#
|
55
|
+
# Also see, _stop_
|
56
|
+
def self.start() # true||false
|
57
|
+
RubyPythonBridge.start
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
# Used to end the python session. Adds some cleanup on top of RubyPythonBridge.stop
|
63
|
+
def self.stop() #=> true,false
|
64
|
+
ObjectSpace.each_object(RubyPythonBridge::RubyPyObject) do |o|
|
65
|
+
o.free_pobj
|
66
|
+
end
|
67
|
+
RubyPythonBridge.stop
|
68
|
+
end
|
69
|
+
|
70
|
+
# Import the python module +mod+ and return it wrapped as a ruby object
|
71
|
+
def self.import(mod)
|
72
|
+
RubyPythonBridge.import(mod)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Handles the setup and cleanup involved with using the interpreter for you.
|
76
|
+
# Note that all Python object will be effectively scope to within the block
|
77
|
+
# as the embedded interpreter will be halted at its end.
|
78
|
+
def self.run(&block)
|
79
|
+
start
|
80
|
+
module_eval(&block)
|
81
|
+
stop
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|