rubypython 0.2.8 → 0.2.9

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 (41) hide show
  1. data/History.txt +4 -1
  2. data/Manifest.txt +16 -1
  3. data/PostInstall.txt +1 -1
  4. data/README.txt +7 -2
  5. data/config/hoe.rb +12 -12
  6. data/ext/rubypython_bridge/cbridge.c +92 -90
  7. data/ext/rubypython_bridge/cbridge.h +6 -16
  8. data/ext/rubypython_bridge/ptor.c +110 -56
  9. data/ext/rubypython_bridge/ptor.h +9 -25
  10. data/ext/rubypython_bridge/rp_blankobject.c +42 -0
  11. data/ext/rubypython_bridge/rp_blankobject.h +10 -0
  12. data/ext/rubypython_bridge/rp_class.c +56 -0
  13. data/ext/rubypython_bridge/rp_class.h +6 -0
  14. data/ext/rubypython_bridge/rp_error.c +14 -4
  15. data/ext/rubypython_bridge/rp_error.h +3 -1
  16. data/ext/rubypython_bridge/rp_function.c +31 -0
  17. data/ext/rubypython_bridge/rp_function.h +6 -0
  18. data/ext/rubypython_bridge/rp_instance.c +165 -0
  19. data/ext/rubypython_bridge/rp_instance.h +6 -0
  20. data/ext/rubypython_bridge/rp_module.c +159 -0
  21. data/ext/rubypython_bridge/rp_module.h +7 -0
  22. data/ext/rubypython_bridge/rp_object.c +93 -427
  23. data/ext/rubypython_bridge/rp_object.h +8 -54
  24. data/ext/rubypython_bridge/rp_util.c +61 -0
  25. data/ext/rubypython_bridge/rp_util.h +11 -0
  26. data/ext/rubypython_bridge/rtop.c +103 -54
  27. data/ext/rubypython_bridge/rtop.h +11 -16
  28. data/ext/rubypython_bridge/rubypython_bridge.c +48 -20
  29. data/ext/rubypython_bridge/rubypython_bridge.h +5 -6
  30. data/lib/rubypython.rb +2 -2
  31. data/lib/rubypython/session.rb +4 -0
  32. data/lib/rubypython/version.rb +1 -1
  33. data/test/python_helpers/objects.py +12 -0
  34. data/test/python_helpers/objects.pyc +0 -0
  35. data/test/test_rubypython.rb +123 -19
  36. data/test/test_rubypython_bridge_extn.rb +52 -19
  37. data/test/test_session.rb +1 -1
  38. data/website/index.html +25 -9
  39. data/website/index.txt +26 -3
  40. metadata +20 -5
  41. 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 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
-
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,10 @@
1
+ #include "config.h"
2
+
3
+ #ifndef _RP_BLANKOBJECT_H_
4
+ #define _RP_BLANKOBJECT_H_
5
+
6
+
7
+ VALUE blank_undef_if(VALUE, VALUE);
8
+ VALUE blank_obj_prep(VALUE);
9
+
10
+ #endif
@@ -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
+ }
@@ -0,0 +1,6 @@
1
+ #include "config.h"
2
+
3
+ #ifndef _RP_CLASS_H_
4
+ #define _RP_CLASS_H_
5
+ VALUE rpClassFromPyObject(PyObject*);
6
+ #endif
@@ -1,23 +1,33 @@
1
1
  #include "rp_error.h"
2
2
 
3
3
  VALUE ePythonError;
4
+ VALUE eRubyPyError;
4
5
 
5
- void rp_pythonerror()
6
+ void rpPythonError()
6
7
  {
7
8
  PyObject *pType,*pValue,*pTraceback;
8
9
  PyObject *pTypeName;
10
+
9
11
  PyErr_Fetch(&pType,&pValue,&pTraceback);
10
- pTypeName=PyObject_GetAttrString(pType,"__name__");
12
+
13
+ pTypeName = PyObject_GetAttrString(pType,"__name__");
11
14
  Py_XDECREF(pType);
12
- rb_raise(ePythonError,"%s:(%s)\n",STR2CSTR(ptor_obj(pTypeName)),STR2CSTR(rb_inspect(ptor_obj(pValue))));
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
  }
@@ -3,6 +3,8 @@
3
3
  #ifndef _RP_ERROR_H_
4
4
  #define _RP_ERROR_H_
5
5
 
6
- void rp_pythonerror();
6
+ void rpPythonError();
7
+
8
+ void rpRubyPyError(char*);
7
9
 
8
10
  #endif /* _RP_ERROR_H_ */
@@ -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,6 @@
1
+ #include "config.h"
2
+
3
+ #ifndef _RP_FUNCTION_H_
4
+ #define _RP_FUNCTION_H_
5
+ VALUE rpFunctionFromPyObject(PyObject*);
6
+ #endif
@@ -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,6 @@
1
+ #include "config.h"
2
+
3
+ #ifndef _RP_INSTANCE_H_
4
+ #define _RP_INSTANCE_H_
5
+ VALUE rpInstanceFromPyObject(PyObject*);
6
+ #endif
@@ -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
+ }