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.
- 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
|