rubypython 0.2.8 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -1
- data/Manifest.txt +16 -1
- data/PostInstall.txt +1 -1
- data/README.txt +7 -2
- data/config/hoe.rb +12 -12
- data/ext/rubypython_bridge/cbridge.c +92 -90
- data/ext/rubypython_bridge/cbridge.h +6 -16
- data/ext/rubypython_bridge/ptor.c +110 -56
- data/ext/rubypython_bridge/ptor.h +9 -25
- data/ext/rubypython_bridge/rp_blankobject.c +42 -0
- data/ext/rubypython_bridge/rp_blankobject.h +10 -0
- data/ext/rubypython_bridge/rp_class.c +56 -0
- data/ext/rubypython_bridge/rp_class.h +6 -0
- data/ext/rubypython_bridge/rp_error.c +14 -4
- data/ext/rubypython_bridge/rp_error.h +3 -1
- data/ext/rubypython_bridge/rp_function.c +31 -0
- data/ext/rubypython_bridge/rp_function.h +6 -0
- data/ext/rubypython_bridge/rp_instance.c +165 -0
- data/ext/rubypython_bridge/rp_instance.h +6 -0
- data/ext/rubypython_bridge/rp_module.c +159 -0
- data/ext/rubypython_bridge/rp_module.h +7 -0
- data/ext/rubypython_bridge/rp_object.c +93 -427
- data/ext/rubypython_bridge/rp_object.h +8 -54
- data/ext/rubypython_bridge/rp_util.c +61 -0
- data/ext/rubypython_bridge/rp_util.h +11 -0
- data/ext/rubypython_bridge/rtop.c +103 -54
- data/ext/rubypython_bridge/rtop.h +11 -16
- data/ext/rubypython_bridge/rubypython_bridge.c +48 -20
- data/ext/rubypython_bridge/rubypython_bridge.h +5 -6
- data/lib/rubypython.rb +2 -2
- data/lib/rubypython/session.rb +4 -0
- data/lib/rubypython/version.rb +1 -1
- data/test/python_helpers/objects.py +12 -0
- data/test/python_helpers/objects.pyc +0 -0
- data/test/test_rubypython.rb +123 -19
- data/test/test_rubypython_bridge_extn.rb +52 -19
- data/test/test_session.rb +1 -1
- data/website/index.html +25 -9
- data/website/index.txt +26 -3
- metadata +20 -5
- data/.autotest +0 -9
@@ -1,31 +1,15 @@
|
|
1
1
|
#include "config.h"
|
2
2
|
|
3
|
-
#ifndef _RP_ERROR_H_
|
4
|
-
#include "rp_error.h"
|
5
|
-
#endif
|
6
|
-
|
7
3
|
#ifndef _PTOR_H_
|
8
4
|
#define _PTOR_H_
|
9
|
-
|
10
5
|
//Python to Ruby Conversion
|
11
|
-
VALUE
|
12
|
-
|
13
|
-
VALUE
|
14
|
-
|
15
|
-
VALUE
|
16
|
-
|
17
|
-
VALUE
|
18
|
-
|
19
|
-
VALUE
|
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
|
-
|
6
|
+
VALUE ptorString(PyObject* pString);
|
7
|
+
VALUE ptorList(PyObject* pList);
|
8
|
+
VALUE ptorInt(PyObject* pNum);
|
9
|
+
VALUE ptorLong(PyObject* pNum);
|
10
|
+
VALUE ptorFloat(PyObject* pNum);
|
11
|
+
VALUE ptorTuple(PyObject* pTuple);
|
12
|
+
VALUE ptorDict(PyObject* pDict);
|
13
|
+
VALUE ptorObject(PyObject* pObj);
|
14
|
+
VALUE ptorObjectKeep(PyObject *pObj);
|
31
15
|
#endif /* _PTOR_H_ */
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#include "rp_blankobject.h"
|
2
|
+
|
3
|
+
RUBY_EXTERN VALUE mRubyPythonBridge;
|
4
|
+
|
5
|
+
VALUE cBlankObject;
|
6
|
+
|
7
|
+
// :nodoc:
|
8
|
+
/* This functions is used as a predicate function. Every function name
|
9
|
+
for which it returns true will be removed from the blank object
|
10
|
+
dictionary.
|
11
|
+
*/
|
12
|
+
VALUE blank_undef_if(VALUE name, VALUE klass)
|
13
|
+
{
|
14
|
+
VALUE mname = rb_funcall(name, rb_intern("to_s"), 0);
|
15
|
+
VALUE methodRe = rb_str_new2("(?:^__)|(?:\\?$)|(?:^send$)|(?:^class$)");
|
16
|
+
|
17
|
+
if(rb_funcall(mname, rb_intern("match"), 1, methodRe) == Qnil)
|
18
|
+
{
|
19
|
+
rb_undef_method(klass, STR2CSTR(mname));
|
20
|
+
return Qtrue;
|
21
|
+
}
|
22
|
+
else
|
23
|
+
{
|
24
|
+
return Qfalse;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
// :nodoc:
|
29
|
+
VALUE blank_obj_prep(VALUE self)
|
30
|
+
{
|
31
|
+
VALUE instance_methods = rb_funcall(self, rb_intern("instance_methods"), 0);
|
32
|
+
|
33
|
+
rb_iterate(rb_each, instance_methods, blank_undef_if, self);
|
34
|
+
return self;
|
35
|
+
}
|
36
|
+
|
37
|
+
// :nodoc:
|
38
|
+
inline void Init_BlankObject()
|
39
|
+
{
|
40
|
+
cBlankObject = rb_define_class_under(mRubyPythonBridge,"BlankObject", rb_cObject);
|
41
|
+
blank_obj_prep(cBlankObject);
|
42
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#include "rp_class.h"
|
2
|
+
|
3
|
+
#include "rp_module.h"
|
4
|
+
#include "rp_object.h"
|
5
|
+
|
6
|
+
RUBY_EXTERN VALUE mRubyPythonBridge;
|
7
|
+
RUBY_EXTERN VALUE ePythonError;
|
8
|
+
RUBY_EXTERN VALUE cRubyPyObject;
|
9
|
+
RUBY_EXTERN VALUE cBlankObject;
|
10
|
+
|
11
|
+
VALUE cRubyPyClass;
|
12
|
+
|
13
|
+
VALUE rpClassFromPyObject(PyObject *pClass)
|
14
|
+
{
|
15
|
+
PObj* self;
|
16
|
+
PyObject* pClassDict;
|
17
|
+
VALUE rDict;
|
18
|
+
VALUE rClass = rb_class_new_instance(0, NULL, cRubyPyClass);
|
19
|
+
|
20
|
+
Data_Get_Struct(rClass, PObj, self);
|
21
|
+
self->pObject = pClass;
|
22
|
+
|
23
|
+
pClassDict = PyObject_GetAttrString(pClass,"__dict__");
|
24
|
+
Py_XINCREF(pClassDict);
|
25
|
+
|
26
|
+
rDict = rpObjectFromPyObject
|
27
|
+
(pClassDict);
|
28
|
+
rb_iv_set(rClass,"@pdict", rDict);
|
29
|
+
|
30
|
+
return rClass;
|
31
|
+
}
|
32
|
+
|
33
|
+
static
|
34
|
+
VALUE rpClassNew(VALUE self, VALUE args)
|
35
|
+
{
|
36
|
+
PyObject* pSelf;
|
37
|
+
|
38
|
+
pSelf = rpObjectGetPyObject(self);
|
39
|
+
|
40
|
+
return rpCall(pSelf, args);
|
41
|
+
}
|
42
|
+
|
43
|
+
/*
|
44
|
+
A wrapper class for Python classes and instances.
|
45
|
+
|
46
|
+
This allows objects which cannot easily be converted to native Ruby types to still be accessible
|
47
|
+
from within ruby. Most users need not concern themselves with anything about this class except
|
48
|
+
its existence.
|
49
|
+
|
50
|
+
*/
|
51
|
+
void Init_RubyPyClass()
|
52
|
+
{
|
53
|
+
cRubyPyClass = rb_define_class_under(mRubyPythonBridge,"RubyPyClass", cRubyPyObject);
|
54
|
+
rb_define_method(cRubyPyClass,"method_missing", rpModuleDelegate,- 2);
|
55
|
+
rb_define_method(cRubyPyClass,"new", rpClassNew,- 2);
|
56
|
+
}
|
@@ -1,23 +1,33 @@
|
|
1
1
|
#include "rp_error.h"
|
2
2
|
|
3
3
|
VALUE ePythonError;
|
4
|
+
VALUE eRubyPyError;
|
4
5
|
|
5
|
-
void
|
6
|
+
void rpPythonError()
|
6
7
|
{
|
7
8
|
PyObject *pType,*pValue,*pTraceback;
|
8
9
|
PyObject *pTypeName;
|
10
|
+
|
9
11
|
PyErr_Fetch(&pType,&pValue,&pTraceback);
|
10
|
-
|
12
|
+
|
13
|
+
pTypeName = PyObject_GetAttrString(pType,"__name__");
|
11
14
|
Py_XDECREF(pType);
|
12
|
-
|
15
|
+
|
16
|
+
rb_raise(ePythonError,"%s:(%s)\n", STR2CSTR(ptorObject(pTypeName)), STR2CSTR(rb_inspect(ptorObject(pValue))));
|
17
|
+
|
13
18
|
Py_XDECREF(pTraceback);
|
14
19
|
}
|
15
20
|
|
21
|
+
void rpRubyPyError(char* eString) {
|
22
|
+
rb_raise(eRubyPyError, eString);
|
23
|
+
}
|
24
|
+
|
16
25
|
/*
|
17
26
|
Used to pass error information back into Ruby should an error occur in the embedded Python
|
18
27
|
interpreter.
|
19
28
|
*/
|
20
29
|
void Init_RubyPyError()
|
21
30
|
{
|
22
|
-
ePythonError=rb_define_class("PythonError",rb_eException);
|
31
|
+
ePythonError = rb_define_class("PythonError", rb_eException);
|
32
|
+
eRubyPyError = rb_define_class("RubyPyError", rb_eException);
|
23
33
|
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#include "rp_function.h"
|
2
|
+
#include "rp_object.h"
|
3
|
+
|
4
|
+
RUBY_EXTERN VALUE mRubyPythonBridge;
|
5
|
+
RUBY_EXTERN VALUE cRubyPyObject;
|
6
|
+
|
7
|
+
VALUE cRubyPyFunction;
|
8
|
+
|
9
|
+
VALUE rpFunctionFromPyObject(PyObject *pFunc)
|
10
|
+
{
|
11
|
+
PObj* self;
|
12
|
+
VALUE rFunc = rb_class_new_instance(0, NULL, cRubyPyFunction);
|
13
|
+
|
14
|
+
Data_Get_Struct(rFunc, PObj, self);
|
15
|
+
|
16
|
+
self->pObject = pFunc;
|
17
|
+
|
18
|
+
return rFunc;
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
//
|
23
|
+
// A wrapper class for Python functions and methods.
|
24
|
+
//
|
25
|
+
// This is used internally to aid RubyPyClass in delegating method calls.
|
26
|
+
//
|
27
|
+
|
28
|
+
void Init_RubyPyFunction()
|
29
|
+
{
|
30
|
+
cRubyPyFunction = rb_define_class_under(mRubyPythonBridge,"RubyPyFunction", cRubyPyObject);
|
31
|
+
}
|
@@ -0,0 +1,165 @@
|
|
1
|
+
#include "rp_instance.h"
|
2
|
+
|
3
|
+
#include "rp_object.h"
|
4
|
+
#include "rp_function.h"
|
5
|
+
|
6
|
+
RUBY_EXTERN VALUE mRubyPythonBridge;
|
7
|
+
|
8
|
+
RUBY_EXTERN VALUE cRubyPyObject;
|
9
|
+
RUBY_EXTERN VALUE cRubyPyFunction;
|
10
|
+
|
11
|
+
VALUE cRubyPyInstance;
|
12
|
+
|
13
|
+
VALUE rpInstanceFromPyObject(PyObject* pInst)
|
14
|
+
{
|
15
|
+
PObj* self;
|
16
|
+
PyObject *pClassDict,*pClass,*pInstDict;
|
17
|
+
VALUE rInstDict, rClassDict;
|
18
|
+
VALUE rInst = rb_class_new_instance(0, NULL, cRubyPyInstance);
|
19
|
+
|
20
|
+
Data_Get_Struct(rInst, PObj, self);
|
21
|
+
self->pObject = pInst;
|
22
|
+
|
23
|
+
pClass = PyObject_GetAttrString(pInst,"__class__");
|
24
|
+
pClassDict = PyObject_GetAttrString(pClass,"__dict__");
|
25
|
+
pInstDict = PyObject_GetAttrString(pInst,"__dict__");
|
26
|
+
|
27
|
+
Py_XINCREF(pClassDict);
|
28
|
+
Py_XINCREF(pInstDict);
|
29
|
+
|
30
|
+
rClassDict = rpObjectFromPyObject(pClassDict);
|
31
|
+
rInstDict = rpObjectFromPyObject(pInstDict);
|
32
|
+
|
33
|
+
rb_iv_set(rInst,"@pclassdict", rClassDict);
|
34
|
+
rb_iv_set(rInst,"@pinstdict", rInstDict);
|
35
|
+
|
36
|
+
return rInst;
|
37
|
+
}
|
38
|
+
|
39
|
+
static
|
40
|
+
VALUE rpInstanceSetAttr(VALUE self, VALUE args)
|
41
|
+
{
|
42
|
+
VALUE name, name_string, rClassDict, result, rInstDict;
|
43
|
+
VALUE ret;
|
44
|
+
|
45
|
+
int instance;
|
46
|
+
char* cname;
|
47
|
+
|
48
|
+
PObj *pClassDict,*pInstDict,*pDict;
|
49
|
+
|
50
|
+
PyObject* pName;
|
51
|
+
|
52
|
+
name = rb_ary_shift(args);
|
53
|
+
name_string = rb_funcall(name, rb_intern("to_s"), 0);
|
54
|
+
|
55
|
+
rb_funcall(name_string, rb_intern("chop!"), 0);
|
56
|
+
|
57
|
+
if(!rpHasSymbol(self, name_string))
|
58
|
+
{
|
59
|
+
int argc;
|
60
|
+
VALUE* argv;
|
61
|
+
|
62
|
+
argc = RARRAY_LEN(args);
|
63
|
+
argv = ALLOC_N(VALUE, argc);
|
64
|
+
MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
|
65
|
+
return rb_call_super(argc, argv);
|
66
|
+
}
|
67
|
+
|
68
|
+
cname = STR2CSTR(name_string);
|
69
|
+
|
70
|
+
if((NUM2INT(rb_funcall(args, rb_intern("size"), 0)) == 1))
|
71
|
+
{
|
72
|
+
args = rb_ary_entry(args, 0);
|
73
|
+
}
|
74
|
+
|
75
|
+
rClassDict = rb_iv_get(self,"@pclassdict");
|
76
|
+
rInstDict = rb_iv_get(self,"@pinstdict");
|
77
|
+
|
78
|
+
Data_Get_Struct(rClassDict, PObj, pClassDict);
|
79
|
+
Data_Get_Struct(rInstDict, PObj, pInstDict);
|
80
|
+
|
81
|
+
pName = PyString_FromString(cname);
|
82
|
+
|
83
|
+
if(PyDict_Contains(pInstDict->pObject, pName))
|
84
|
+
{
|
85
|
+
pDict = pInstDict;
|
86
|
+
|
87
|
+
}
|
88
|
+
else
|
89
|
+
{
|
90
|
+
pDict = pClassDict;
|
91
|
+
|
92
|
+
}
|
93
|
+
|
94
|
+
Py_XDECREF(pName);
|
95
|
+
PyDict_SetItemString(pDict->pObject, STR2CSTR(name_string), rtopObject(args, 0));
|
96
|
+
|
97
|
+
return Qtrue;
|
98
|
+
}
|
99
|
+
|
100
|
+
//:nodoc:
|
101
|
+
static
|
102
|
+
VALUE rpInstanceDelegate(VALUE self, VALUE args)
|
103
|
+
{
|
104
|
+
VALUE name, name_string, rClassDict, result, rInstDict;
|
105
|
+
VALUE ret;
|
106
|
+
char* cname;
|
107
|
+
PObj *pClassDict,*pInstDict;
|
108
|
+
PyObject* pCalled;
|
109
|
+
|
110
|
+
if(rpSymbolIsSetter(args))
|
111
|
+
{
|
112
|
+
return rpInstanceSetAttr(self, args);
|
113
|
+
}
|
114
|
+
|
115
|
+
if(!rpHasSymbol(self, rb_ary_entry(args, 0)))
|
116
|
+
{
|
117
|
+
int argc;
|
118
|
+
VALUE* argv;
|
119
|
+
|
120
|
+
argc = RARRAY_LEN(args);
|
121
|
+
argv = ALLOC_N(VALUE, argc);
|
122
|
+
MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
|
123
|
+
return rb_call_super(argc, argv);
|
124
|
+
}
|
125
|
+
|
126
|
+
name = rb_ary_shift(args);
|
127
|
+
name_string = rb_funcall(name, rb_intern("to_s"), 0);
|
128
|
+
cname = STR2CSTR(name_string);
|
129
|
+
|
130
|
+
rClassDict = rb_iv_get(self,"@pclassdict");
|
131
|
+
rInstDict = rb_iv_get(self,"@pinstdict");
|
132
|
+
|
133
|
+
Data_Get_Struct(rClassDict, PObj, pClassDict);
|
134
|
+
Data_Get_Struct(rInstDict, PObj, pInstDict);
|
135
|
+
|
136
|
+
pCalled = PyDict_GetItemString(pInstDict->pObject, cname);
|
137
|
+
|
138
|
+
if(!pCalled)
|
139
|
+
{
|
140
|
+
pCalled = PyDict_GetItemString(pClassDict->pObject, cname);
|
141
|
+
}
|
142
|
+
|
143
|
+
Py_XINCREF(pCalled);
|
144
|
+
result = ptorObjectKeep(pCalled);
|
145
|
+
|
146
|
+
if(rb_obj_is_instance_of(result, cRubyPyFunction))
|
147
|
+
{
|
148
|
+
Py_XINCREF(rpObjectGetPyObject(self));
|
149
|
+
rb_ary_unshift(args, self);
|
150
|
+
ret = rpCall(pCalled, args);
|
151
|
+
return ret;
|
152
|
+
}
|
153
|
+
|
154
|
+
return result;
|
155
|
+
|
156
|
+
}
|
157
|
+
|
158
|
+
|
159
|
+
void Init_RubyPyInstance()
|
160
|
+
{
|
161
|
+
cRubyPyInstance = rb_define_class_under(mRubyPythonBridge,"RubyPyInstance", cRubyPyObject);
|
162
|
+
rb_define_method(cRubyPyInstance,"method_missing", rpInstanceDelegate,- 2);
|
163
|
+
}
|
164
|
+
|
165
|
+
|
@@ -0,0 +1,159 @@
|
|
1
|
+
#include "rp_module.h"
|
2
|
+
|
3
|
+
#include "rp_object.h"
|
4
|
+
#include "rp_function.h"
|
5
|
+
|
6
|
+
VALUE cRubyPyModule;
|
7
|
+
|
8
|
+
RUBY_EXTERN VALUE mRubyPythonBridge;
|
9
|
+
RUBY_EXTERN VALUE cRubyPyFunction;
|
10
|
+
RUBY_EXTERN VALUE cRubyPyClass;
|
11
|
+
RUBY_EXTERN VALUE cRubyPyObject;
|
12
|
+
|
13
|
+
static
|
14
|
+
VALUE rpModuleCallFunction(VALUE self, VALUE func_name, VALUE args)
|
15
|
+
{
|
16
|
+
PyObject *pModule,*pFunc;
|
17
|
+
VALUE rReturn;
|
18
|
+
|
19
|
+
pModule = rpObjectGetPyObject(self);
|
20
|
+
|
21
|
+
pFunc = rpGetFunctionWithModule(pModule, func_name);
|
22
|
+
rReturn = rpCall(pFunc, args);
|
23
|
+
Py_XDECREF(pFunc);
|
24
|
+
|
25
|
+
return rReturn;
|
26
|
+
|
27
|
+
}
|
28
|
+
|
29
|
+
//:nodoc:
|
30
|
+
static
|
31
|
+
VALUE rpModuleInit(VALUE self, VALUE mname)
|
32
|
+
{
|
33
|
+
PObj* cself;
|
34
|
+
VALUE rDict;
|
35
|
+
PyObject *pModuleDict;
|
36
|
+
|
37
|
+
Data_Get_Struct(self, PObj, cself);
|
38
|
+
cself->pObject = rpGetModule(mname);
|
39
|
+
|
40
|
+
pModuleDict = PyModule_GetDict(cself->pObject);
|
41
|
+
Py_XINCREF(pModuleDict);
|
42
|
+
|
43
|
+
rDict = rpObjectFromPyObject(pModuleDict);
|
44
|
+
|
45
|
+
rb_iv_set(self,"@pdict", rDict);
|
46
|
+
|
47
|
+
return self;
|
48
|
+
}
|
49
|
+
|
50
|
+
static
|
51
|
+
VALUE rpModuleSetAttr(VALUE self, VALUE args)
|
52
|
+
{
|
53
|
+
VALUE rDict;
|
54
|
+
PyObject* pDict;
|
55
|
+
|
56
|
+
VALUE mname = rb_ary_shift(args);
|
57
|
+
VALUE name_string = rb_funcall(mname, rb_intern("to_s"), 0);
|
58
|
+
|
59
|
+
//The method name ends with "=" because it is a setter.
|
60
|
+
//We must chop that off before we pass the string to python.
|
61
|
+
rb_funcall(name_string, rb_intern("chop!"), 0);
|
62
|
+
|
63
|
+
//The wrapped python object does not have method or attribute with the
|
64
|
+
//request named. Check for it in the Ruby superclass.
|
65
|
+
if(!rpHasSymbol(self, name_string))
|
66
|
+
{
|
67
|
+
int argc;
|
68
|
+
|
69
|
+
VALUE* argv;
|
70
|
+
argc = RARRAY_LEN(args);
|
71
|
+
|
72
|
+
argv = ALLOC_N(VALUE, argc);
|
73
|
+
MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
|
74
|
+
|
75
|
+
return rb_call_super(argc, argv);
|
76
|
+
}
|
77
|
+
|
78
|
+
if(NUM2INT(rb_funcall(args, rb_intern("size"), 0)) == 1)
|
79
|
+
{
|
80
|
+
args = rb_ary_entry(args, 0);
|
81
|
+
}
|
82
|
+
|
83
|
+
rDict = rb_iv_get(self,"@pdict");
|
84
|
+
|
85
|
+
pDict = rpObjectGetPyObject(rDict);
|
86
|
+
|
87
|
+
PyDict_SetItemString(pDict, STR2CSTR(name_string), rtopObject(args, 0));
|
88
|
+
|
89
|
+
return Qtrue;
|
90
|
+
}
|
91
|
+
|
92
|
+
//:nodoc:
|
93
|
+
VALUE rpModuleDelegate(VALUE self, VALUE args)
|
94
|
+
{
|
95
|
+
VALUE name, name_string, rDict, result;
|
96
|
+
VALUE ret;
|
97
|
+
PyObject *pCalled, *pDict;
|
98
|
+
|
99
|
+
if(rpSymbolIsSetter(args))
|
100
|
+
{
|
101
|
+
return rpModuleSetAttr(self, args);
|
102
|
+
}
|
103
|
+
|
104
|
+
// if(rpSymbolIsDoubleBang)
|
105
|
+
// {
|
106
|
+
// return rp_mod_attr_db(args);
|
107
|
+
// }
|
108
|
+
if(!rpHasSymbol(self, rb_ary_entry(args, 0)))
|
109
|
+
{
|
110
|
+
int argc;
|
111
|
+
|
112
|
+
VALUE *argv;
|
113
|
+
argc = RARRAY_LEN(args);
|
114
|
+
argv = ALLOC_N(VALUE, argc);
|
115
|
+
MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
|
116
|
+
return rb_call_super(argc, argv);
|
117
|
+
}
|
118
|
+
name = rb_ary_shift(args);
|
119
|
+
name_string = rb_funcall(name, rb_intern("to_s"), 0);
|
120
|
+
|
121
|
+
rDict = rb_iv_get(self,"@pdict");
|
122
|
+
|
123
|
+
pDict = rpObjectGetPyObject(rDict);
|
124
|
+
|
125
|
+
pCalled = PyDict_GetItemString(pDict, STR2CSTR(name_string));
|
126
|
+
Py_XINCREF(pCalled);
|
127
|
+
|
128
|
+
result = ptorObjectKeep(pCalled);
|
129
|
+
|
130
|
+
if(rb_obj_is_instance_of(result, cRubyPyFunction))
|
131
|
+
{
|
132
|
+
ret = rpCall(pCalled, args);
|
133
|
+
return ret;
|
134
|
+
}
|
135
|
+
else if(rb_obj_is_instance_of(result, cRubyPyClass)&&(rb_funcall(args, rb_intern("empty?"), 0) == Qfalse)&&PyCallable_Check(pCalled))
|
136
|
+
{
|
137
|
+
ret = rpCall(pCalled, args);
|
138
|
+
return ret;
|
139
|
+
}
|
140
|
+
|
141
|
+
return result;
|
142
|
+
|
143
|
+
}
|
144
|
+
|
145
|
+
|
146
|
+
/*
|
147
|
+
A wrapper class for Python Modules.
|
148
|
+
|
149
|
+
Methods calls are delegated to the equivalent Python methods / functions. Attribute references
|
150
|
+
return either the equivalent attribute converted to a native Ruby type, or wrapped reference
|
151
|
+
to a Python object. RubyPyModule instances should be created through the use of RubyPython.import.
|
152
|
+
|
153
|
+
*/
|
154
|
+
void Init_RubyPyModule()
|
155
|
+
{
|
156
|
+
cRubyPyModule = rb_define_class_under(mRubyPythonBridge,"RubyPyModule", cRubyPyObject);
|
157
|
+
rb_define_method(cRubyPyModule,"initialize", rpModuleInit, 1);
|
158
|
+
rb_define_method(cRubyPyModule,"method_missing", rpModuleDelegate,- 2);
|
159
|
+
}
|