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.
- 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
data/History.txt
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
== 0.2.9 2009-10-19
|
2
|
+
* Minor Enhancements
|
3
|
+
* Updated the C code to make it cleaner, more readable, and more maintainable.
|
1
4
|
== 0.2.8 2009-10-05
|
2
5
|
* Bug Fixes
|
3
6
|
* Some test files were improperly formatted (minor bug fix).
|
@@ -38,7 +41,7 @@
|
|
38
41
|
* Wrapped classes and instances should now behave as expected.
|
39
42
|
* Gave RubyPyClasses a "new" method for creating instances.
|
40
43
|
* Callable class can now be called provided that at least one argument is given
|
41
|
-
* A wrapped object's respond_to? method now has some relation to its
|
44
|
+
* A wrapped object's respond_to? method now has some relation to its actual methods.
|
42
45
|
|
43
46
|
* Bug fixes
|
44
47
|
* Fixed bug with inspect method of RubyPyObject that caused a bus error when inspecting
|
data/Manifest.txt
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
.autotest
|
2
1
|
History.txt
|
3
2
|
License.txt
|
4
3
|
Manifest.txt
|
@@ -13,15 +12,28 @@ ext/rubypython_bridge/config.h
|
|
13
12
|
ext/rubypython_bridge/extconf.rb
|
14
13
|
ext/rubypython_bridge/ptor.c
|
15
14
|
ext/rubypython_bridge/ptor.h
|
15
|
+
ext/rubypython_bridge/rp_blankobject.c
|
16
|
+
ext/rubypython_bridge/rp_blankobject.h
|
17
|
+
ext/rubypython_bridge/rp_class.c
|
18
|
+
ext/rubypython_bridge/rp_class.h
|
16
19
|
ext/rubypython_bridge/rp_error.c
|
17
20
|
ext/rubypython_bridge/rp_error.h
|
21
|
+
ext/rubypython_bridge/rp_function.c
|
22
|
+
ext/rubypython_bridge/rp_function.h
|
23
|
+
ext/rubypython_bridge/rp_instance.c
|
24
|
+
ext/rubypython_bridge/rp_instance.h
|
25
|
+
ext/rubypython_bridge/rp_module.c
|
26
|
+
ext/rubypython_bridge/rp_module.h
|
18
27
|
ext/rubypython_bridge/rp_object.c
|
19
28
|
ext/rubypython_bridge/rp_object.h
|
29
|
+
ext/rubypython_bridge/rp_util.c
|
30
|
+
ext/rubypython_bridge/rp_util.h
|
20
31
|
ext/rubypython_bridge/rtop.c
|
21
32
|
ext/rubypython_bridge/rtop.h
|
22
33
|
ext/rubypython_bridge/rubypython_bridge.c
|
23
34
|
ext/rubypython_bridge/rubypython_bridge.h
|
24
35
|
lib/rubypython.rb
|
36
|
+
lib/rubypython/session.rb
|
25
37
|
lib/rubypython/version.rb
|
26
38
|
lib/rubypython/wrapper_extensions.rb
|
27
39
|
script/console
|
@@ -34,10 +46,13 @@ tasks/environment.rake
|
|
34
46
|
tasks/extconf.rake
|
35
47
|
tasks/extconf/rubypython_bridge.rake
|
36
48
|
tasks/website.rake
|
49
|
+
test/python_helpers/objects.py
|
50
|
+
test/python_helpers/objects.pyc
|
37
51
|
test/test.wav
|
38
52
|
test/test_helper.rb
|
39
53
|
test/test_rubypython.rb
|
40
54
|
test/test_rubypython_bridge_extn.rb
|
55
|
+
test/test_session.rb
|
41
56
|
website/index.html
|
42
57
|
website/index.txt
|
43
58
|
website/javascripts/rounded_corners_lite.inc.js
|
data/PostInstall.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
For more information on RubyPython, see http://rubypython.rubyforge.org
|
3
3
|
|
4
|
-
If you find a bug, or have any suggestions, email me at:
|
4
|
+
If you find a bug, or have any suggestions, email me at: raineszm+rubypython@gmail.com
|
5
5
|
|
6
6
|
If you would like to help develop RubyPython, also send me an email.
|
7
7
|
|
data/README.txt
CHANGED
@@ -22,8 +22,13 @@
|
|
22
22
|
RubyPython.stop
|
23
23
|
|
24
24
|
== REQUIREMENTS:
|
25
|
-
|
26
|
-
|
25
|
+
|
26
|
+
* Python >=2.4, < 3.0
|
27
|
+
|
28
|
+
Note: Rubypython has been test on Mac OS 10.5.x and 10.6.1 as well
|
29
|
+
as Ubuntu Jaunty 9.04.
|
30
|
+
|
31
|
+
|
27
32
|
== INSTALL:
|
28
33
|
|
29
34
|
sudo gem install rubypython
|
data/config/hoe.rb
CHANGED
@@ -50,20 +50,20 @@ end
|
|
50
50
|
|
51
51
|
# Generate all the Rake tasks
|
52
52
|
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
53
|
-
$hoe = Hoe.
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
$hoe = Hoe.spec(GEM_NAME) do
|
54
|
+
self.developer(AUTHOR, EMAIL)
|
55
|
+
self.description = DESCRIPTION
|
56
|
+
self.summary = DESCRIPTION
|
57
|
+
self.url = HOMEPATH
|
58
|
+
self.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
59
|
+
self.test_globs = ["test/**/test_*.rb"]
|
60
|
+
self.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
61
|
+
self.version = VERS
|
62
62
|
# == Optional
|
63
|
-
|
63
|
+
self.changes = self.paragraphs_of("History.txt", 0..1).join("\n\n")
|
64
64
|
#p.extra_deps = EXTRA_DEPENDENCIES
|
65
65
|
|
66
|
-
|
66
|
+
self.spec_extras = {
|
67
67
|
:requirements => ["Python, ~>2.4"]
|
68
68
|
} # A hash of extra values to set in the gemspec.
|
69
69
|
end
|
@@ -72,4 +72,4 @@ CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
|
72
72
|
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
73
73
|
$hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
74
74
|
$hoe.rsync_args = '-av --delete --ignore-errors'
|
75
|
-
$hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
|
75
|
+
$hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
|
@@ -1,147 +1,149 @@
|
|
1
1
|
#include "cbridge.h"
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
} while(0)
|
11
|
-
|
12
|
-
#define SAFE_END(reg) do {\
|
13
|
-
if(reg && Py_IsInitialized()) \
|
14
|
-
{\
|
15
|
-
Py_Finalize(); \
|
16
|
-
} \
|
17
|
-
} while(0)
|
18
|
-
|
19
|
-
int safe_start()
|
3
|
+
#import "rtop.h"
|
4
|
+
|
5
|
+
/* Attempt to initialize the embedded python interpreter.
|
6
|
+
Return 1 if we initialize it here and 0 if the interpreter is
|
7
|
+
already running.
|
8
|
+
*/
|
9
|
+
int rpSafeStart()
|
20
10
|
{
|
21
11
|
int here;
|
22
|
-
|
12
|
+
|
13
|
+
if(!Py_IsInitialized())
|
14
|
+
{
|
15
|
+
Py_Initialize();
|
16
|
+
here = 1;
|
17
|
+
}
|
18
|
+
|
23
19
|
return here;
|
24
20
|
}
|
25
21
|
|
26
|
-
|
22
|
+
/* Attempt to stop the embedded python interpreter.*/
|
23
|
+
void rpSafeStop(int here)
|
27
24
|
{
|
28
|
-
|
25
|
+
|
26
|
+
if(here && Py_IsInitialized())
|
27
|
+
{
|
28
|
+
Py_Finalize();
|
29
|
+
}
|
29
30
|
}
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
VALUE rp_call_func_with_module_name(VALUE module,VALUE name,VALUE args)
|
32
|
+
VALUE rpCall(PyObject* pFunc, VALUE args)
|
34
33
|
{
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
VALUE rArgs, rReturn;
|
35
|
+
PyObject *pReturn, *pArgs;
|
36
|
+
|
37
|
+
/* Check to see if the passed argument is an array. If it is we
|
38
|
+
* box it in another array so that the presentation of
|
39
|
+
* arguments is the same i.e. each method is supllied with an
|
40
|
+
* array of arguments.
|
41
|
+
*/
|
42
|
+
if(!(TYPE(args) == T_ARRAY))
|
39
43
|
{
|
40
|
-
|
41
|
-
|
44
|
+
|
45
|
+
rArgs = rb_ary_new();
|
46
|
+
rb_ary_push(rArgs, args);
|
42
47
|
}
|
43
48
|
else
|
44
49
|
{
|
45
|
-
rArgs=args;
|
50
|
+
rArgs = args;
|
46
51
|
}
|
52
|
+
|
53
|
+
// Convert the supplied arguments to python objects
|
54
|
+
pArgs = rtopObject(rArgs, 1);
|
55
|
+
|
56
|
+
// Execute the function and obtain a pointer to the return object
|
57
|
+
pReturn = PyObject_CallObject(pFunc, pArgs);
|
47
58
|
|
48
|
-
PyObject *pModuleName,*pModule,*pFunc,*pArgs,*pReturn;
|
49
|
-
if(rb_eql(module,rb_str_new2("builtins")))
|
50
|
-
{
|
51
|
-
module=rb_str_new2("__builtins__");
|
52
|
-
}
|
53
|
-
pModuleName=rtop_obj(module,0);
|
54
|
-
pModule=PyImport_Import(pModuleName);
|
55
|
-
Py_XDECREF(pModuleName);
|
56
59
|
if(PyErr_Occurred())
|
57
60
|
{
|
58
|
-
|
61
|
+
Py_XDECREF(pArgs);
|
62
|
+
Py_XDECREF(pReturn);
|
63
|
+
rpPythonError();
|
59
64
|
return Qnil;
|
60
65
|
}
|
66
|
+
|
67
|
+
rReturn = ptorObjectKeep(pReturn);
|
68
|
+
Py_XDECREF(pArgs);
|
69
|
+
|
70
|
+
return rReturn;
|
71
|
+
}
|
72
|
+
|
73
|
+
VALUE rpCallWithModule(VALUE module, VALUE name, VALUE args)
|
74
|
+
{
|
75
|
+
|
76
|
+
VALUE rArgs;
|
77
|
+
VALUE rReturn;
|
78
|
+
|
79
|
+
PyObject *pModule, *pFunc, *pArgs, *pReturn;
|
80
|
+
|
81
|
+
|
82
|
+
// Load the requested python module
|
83
|
+
pModule = rpGetModule(module);
|
61
84
|
|
85
|
+
// Get a pointer to the requested function
|
86
|
+
pFunc = rpGetFunctionWithModule(pModule, name);
|
62
87
|
|
63
|
-
|
64
|
-
|
65
|
-
pArgs=rtop_obj(rArgs,1);
|
88
|
+
Py_XDECREF(pModule);
|
66
89
|
|
67
|
-
|
90
|
+
rReturn = rpCall(pFunc, args);
|
68
91
|
|
92
|
+
// Check for an error and do any necessary cleanup before
|
93
|
+
// propagating error
|
69
94
|
if(PyErr_Occurred())
|
70
95
|
{
|
71
|
-
Py_XDECREF(pReturn);
|
72
|
-
Py_XDECREF(pArgs);
|
73
96
|
Py_XDECREF(pFunc);
|
74
|
-
|
75
|
-
rp_pythonerror();
|
97
|
+
rpPythonError();
|
76
98
|
return Qnil;
|
77
99
|
}
|
78
100
|
|
79
|
-
|
80
|
-
|
81
|
-
Py_XDECREF(pArgs);
|
101
|
+
// Cleanup temporary objects
|
82
102
|
Py_XDECREF(pFunc);
|
83
|
-
|
103
|
+
|
84
104
|
return rReturn;
|
85
105
|
}
|
86
106
|
|
87
|
-
PyObject*
|
107
|
+
PyObject* rpGetModule(VALUE mname)
|
88
108
|
{
|
89
|
-
|
109
|
+
PyObject *pModule, *pModuleName;
|
110
|
+
|
111
|
+
// A little syntatic sugar here. We will allow users access the
|
112
|
+
// __builtins__ module under the name builtins
|
113
|
+
// FIXME: replace this with a call to rb_get_module
|
114
|
+
if(rb_eql(mname, rb_str_new2("builtins")))
|
90
115
|
{
|
91
|
-
mname=rb_str_new2("__builtins__");
|
116
|
+
mname = rb_str_new2("__builtins__");
|
92
117
|
}
|
93
|
-
|
94
|
-
pModuleName=
|
95
|
-
pModule=PyImport_Import(pModuleName);
|
118
|
+
|
119
|
+
pModuleName = rtopString(mname);
|
120
|
+
pModule = PyImport_Import(pModuleName);
|
96
121
|
Py_XDECREF(pModuleName);
|
122
|
+
|
97
123
|
if(PyErr_Occurred())
|
98
124
|
{
|
99
125
|
Py_XDECREF(pModule);
|
100
|
-
|
126
|
+
rpPythonError();
|
101
127
|
return Py_None;
|
102
128
|
}
|
129
|
+
|
103
130
|
return pModule;
|
104
131
|
}
|
105
132
|
|
106
|
-
PyObject*
|
133
|
+
PyObject* rpGetFunctionWithModule(PyObject* pModule, VALUE name)
|
107
134
|
{
|
108
135
|
PyObject *pFunc;
|
109
|
-
|
136
|
+
|
137
|
+
pFunc = PyObject_GetAttrString(pModule, STR2CSTR(name));
|
138
|
+
|
110
139
|
if(PyErr_Occurred())
|
111
140
|
{
|
112
141
|
Py_XDECREF(pFunc);
|
113
|
-
|
142
|
+
rpPythonError();
|
114
143
|
return Py_None;
|
115
144
|
}
|
145
|
+
|
116
146
|
return pFunc;
|
117
147
|
}
|
118
148
|
|
119
|
-
|
120
|
-
{
|
121
|
-
VALUE rArgs,rReturn;
|
122
|
-
PyObject *pReturn,*pArgs;
|
123
|
-
if(!(TYPE(args)==T_ARRAY))
|
124
|
-
{
|
125
|
-
|
126
|
-
rArgs=rb_ary_new();
|
127
|
-
rb_ary_push(rArgs,args);
|
128
|
-
}
|
129
|
-
else
|
130
|
-
{
|
131
|
-
rArgs=args;
|
132
|
-
}
|
133
|
-
pArgs=rtop_obj(rArgs,1);
|
134
|
-
pReturn=PyObject_CallObject(pFunc,pArgs);
|
135
|
-
|
136
|
-
if(PyErr_Occurred())
|
137
|
-
{
|
138
|
-
Py_XDECREF(pArgs);
|
139
|
-
Py_XDECREF(pReturn);
|
140
|
-
rp_pythonerror();
|
141
|
-
return Qnil;
|
142
|
-
}
|
143
|
-
rReturn=ptor_obj_no_destruct(pReturn);
|
144
|
-
|
145
|
-
Py_XDECREF(pArgs);
|
146
|
-
return rReturn;
|
147
|
-
}
|
149
|
+
|
@@ -1,25 +1,15 @@
|
|
1
1
|
#include "config.h"
|
2
|
-
#include "ptor.h"
|
3
|
-
#include "rtop.h"
|
4
|
-
#include "rp_error.h"
|
5
2
|
|
6
3
|
#ifndef _BRIDGE_H_
|
7
4
|
#define _BRIDGE_H_
|
5
|
+
int rpSafeStart();
|
6
|
+
void rpSafeStop(int);
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
void safe_stop(int here);
|
12
|
-
|
13
|
-
|
14
|
-
VALUE rp_call_func_with_module_name(VALUE module,VALUE name,VALUE args);
|
15
|
-
|
16
|
-
PyObject* rp_get_module(VALUE mname);
|
17
|
-
|
18
|
-
PyObject* rp_get_func_with_module(PyObject* pModule,VALUE name);
|
19
|
-
|
20
|
-
VALUE rp_call_func(PyObject* pFunc, VALUE args);
|
21
|
-
|
8
|
+
VALUE rpCallWithModule(VALUE, VALUE, VALUE);
|
9
|
+
VALUE rpCall(PyObject*, VALUE);
|
22
10
|
|
11
|
+
PyObject* rpGetModule(VALUE);
|
12
|
+
PyObject* rpGetFunctionWithModule(PyObject*, VALUE);
|
23
13
|
#endif /* _BRIDGE_H_ */
|
24
14
|
|
25
15
|
|
@@ -1,183 +1,237 @@
|
|
1
1
|
#include "ptor.h"
|
2
2
|
|
3
|
-
|
3
|
+
|
4
|
+
/* Note:
|
5
|
+
The conversion functions for the builtin types are just that,
|
6
|
+
conversion functions. They create a new Ruby object equivalent to
|
7
|
+
the given Python object, they do not wrap the Python object.
|
8
|
+
|
9
|
+
*/
|
10
|
+
|
11
|
+
VALUE ptorString(PyObject* pString)
|
4
12
|
{
|
13
|
+
// Make sure pString is actually a string
|
5
14
|
if(!PyString_Check(pString)) return Qnil;
|
6
15
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
16
|
+
// Allocate a new string for Ruby and return it.
|
17
|
+
// Note that this is a new object, not a wrapper around a
|
18
|
+
// python object
|
19
|
+
char* cStr;
|
20
|
+
char* cStrCopy;
|
21
|
+
|
22
|
+
cStr = PyString_AsString(pString);
|
23
|
+
|
24
|
+
cStrCopy = malloc(PyString_Size(pString) * sizeof(char));
|
25
|
+
|
26
|
+
strcpy(cStrCopy, cStr);
|
27
|
+
|
28
|
+
|
29
|
+
return rb_str_new2(cStrCopy);
|
11
30
|
}
|
12
31
|
|
13
|
-
VALUE
|
32
|
+
VALUE ptorList(PyObject* pList)
|
14
33
|
{
|
34
|
+
// Verify that pList is a python list
|
15
35
|
if(!PyList_Check(pList)) return Qnil;
|
36
|
+
|
16
37
|
VALUE rArray;
|
17
38
|
VALUE rElement;
|
18
39
|
PyObject* element;
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
40
|
+
|
41
|
+
int i = 0;
|
42
|
+
|
43
|
+
// Allocate a new Ruby array
|
44
|
+
rArray = rb_ary_new();
|
45
|
+
|
46
|
+
// Iteratively add converted elements to the new Ruby list
|
47
|
+
int list_size = PyList_Size(pList);
|
48
|
+
for(i = 0; i < list_size; i++)
|
24
49
|
{
|
25
|
-
element=PyList_GetItem(pList,i);
|
50
|
+
element = PyList_GetItem(pList, i);
|
26
51
|
Py_INCREF(element);
|
27
|
-
rElement=
|
28
|
-
rb_ary_push(rArray,rElement);
|
52
|
+
rElement = ptorObject(element);
|
53
|
+
rb_ary_push(rArray, rElement);
|
29
54
|
}
|
30
55
|
return rArray;
|
31
56
|
}
|
32
57
|
|
33
|
-
VALUE
|
58
|
+
VALUE ptorInt(PyObject* pNum)
|
34
59
|
{
|
35
|
-
VALUE rNum;
|
36
60
|
if(!PyInt_Check(pNum)) return Qnil;
|
37
|
-
|
61
|
+
|
62
|
+
VALUE rNum;
|
63
|
+
|
64
|
+
rNum = INT2NUM(PyInt_AsLong(pNum));
|
38
65
|
return rNum;
|
39
66
|
|
40
67
|
}
|
41
68
|
|
42
|
-
VALUE
|
69
|
+
VALUE ptorLong(PyObject* pNum)
|
43
70
|
{
|
71
|
+
if(!PyLong_Check(pNum)) return Qnil;
|
72
|
+
|
44
73
|
VALUE rNum;
|
45
74
|
long cNum;
|
46
|
-
|
47
|
-
cNum=PyLong_AsLong(pNum);
|
75
|
+
|
76
|
+
cNum = PyLong_AsLong(pNum);
|
77
|
+
|
48
78
|
if(PyErr_ExceptionMatches(PyExc_OverflowError))
|
49
79
|
{
|
50
|
-
|
80
|
+
rpPythonError();
|
51
81
|
return Qnil;
|
52
82
|
}
|
53
|
-
|
83
|
+
|
84
|
+
rNum = INT2NUM(cNum);
|
85
|
+
|
54
86
|
return rNum;
|
55
87
|
|
56
88
|
}
|
57
89
|
|
58
|
-
VALUE
|
90
|
+
VALUE ptorFloat(PyObject* pNum)
|
59
91
|
{
|
60
|
-
VALUE rNum;
|
61
92
|
if(!PyFloat_Check(pNum)) return Qnil;
|
62
|
-
|
93
|
+
|
94
|
+
VALUE rNum;
|
95
|
+
|
96
|
+
rNum = rb_float_new(PyFloat_AsDouble(pNum));
|
97
|
+
|
63
98
|
return rNum;
|
64
99
|
}
|
65
100
|
|
66
|
-
VALUE
|
101
|
+
VALUE ptorTuple(PyObject* pTuple)
|
67
102
|
{
|
103
|
+
if(!PyTuple_Check(pTuple)) return Qnil;
|
104
|
+
|
68
105
|
VALUE rArray;
|
69
106
|
PyObject* pList;
|
70
|
-
|
71
|
-
pList=PySequence_List(pTuple);
|
72
|
-
rArray=
|
107
|
+
|
108
|
+
pList = PySequence_List(pTuple);
|
109
|
+
rArray = ptorList(pList);
|
73
110
|
Py_DECREF(pList);
|
111
|
+
|
74
112
|
return rArray;
|
75
113
|
}
|
76
114
|
|
77
115
|
|
78
|
-
VALUE
|
116
|
+
VALUE ptorDict(PyObject* pDict)
|
79
117
|
{
|
80
|
-
VALUE rHash;
|
81
118
|
if(!PyDict_Check(pDict)) return Qnil;
|
82
|
-
|
119
|
+
|
120
|
+
VALUE rHash;
|
121
|
+
VALUE rKey, rVal;
|
83
122
|
PyObject *key,*val;
|
84
|
-
Py_ssize_t pos=0;
|
85
|
-
|
123
|
+
Py_ssize_t pos = 0;
|
124
|
+
|
125
|
+
rHash = rb_hash_new();
|
126
|
+
|
86
127
|
while(PyDict_Next(pDict,&pos,&key,&val))
|
87
128
|
{
|
88
129
|
Py_XINCREF(key);
|
89
130
|
Py_XINCREF(val);
|
90
|
-
rKey=
|
91
|
-
rVal=
|
92
|
-
if(rKey==Qnil) continue;
|
93
|
-
rb_hash_aset(rHash,rKey,rVal);
|
131
|
+
rKey = ptorObject(key);
|
132
|
+
rVal = ptorObject(val);
|
133
|
+
if(rKey == Qnil) continue;
|
134
|
+
rb_hash_aset(rHash, rKey, rVal);
|
94
135
|
}
|
136
|
+
|
95
137
|
return rHash;
|
96
138
|
}
|
97
139
|
|
98
|
-
static VALUE
|
140
|
+
static VALUE ptorObjectBasic(PyObject *pObj, int destructive)
|
99
141
|
{
|
100
142
|
VALUE rObj;
|
143
|
+
|
144
|
+
// Test the Python object vs various types and convert / wrap it
|
145
|
+
// appropriately. If the destructive flag is set, we destroy
|
146
|
+
// the original.
|
147
|
+
|
101
148
|
if(PyObject_TypeCheck(pObj,&PyString_Type))
|
102
149
|
{
|
103
|
-
rObj=
|
150
|
+
rObj = ptorString(pObj);
|
104
151
|
if(destructive) Py_DECREF(pObj);
|
105
152
|
return rObj;
|
106
153
|
}
|
107
154
|
|
108
155
|
if(PyObject_TypeCheck(pObj,&PyList_Type))
|
109
156
|
{
|
110
|
-
rObj=
|
157
|
+
rObj = ptorList(pObj);
|
111
158
|
if(destructive) Py_DECREF(pObj);
|
112
159
|
return rObj;
|
113
160
|
}
|
114
161
|
if(PyObject_TypeCheck(pObj,&PyInt_Type))
|
115
162
|
{
|
116
|
-
rObj=
|
163
|
+
rObj = ptorInt(pObj);
|
117
164
|
if(destructive) Py_DECREF(pObj);
|
118
165
|
return rObj;
|
119
166
|
}
|
120
167
|
if(PyObject_TypeCheck(pObj,&PyLong_Type))
|
121
168
|
{
|
122
|
-
rObj=
|
169
|
+
rObj = ptorLong(pObj);
|
123
170
|
if(destructive) Py_DECREF(pObj);
|
124
171
|
return rObj;
|
125
172
|
}
|
126
173
|
if(PyObject_TypeCheck(pObj,&PyFloat_Type))
|
127
174
|
{
|
128
|
-
rObj=
|
175
|
+
rObj = ptorFloat(pObj);
|
129
176
|
if(destructive) Py_DECREF(pObj);
|
130
177
|
return rObj;
|
131
178
|
}
|
132
179
|
if(PyObject_TypeCheck(pObj,&PyTuple_Type))
|
133
180
|
{
|
134
|
-
rObj=
|
181
|
+
rObj = ptorTuple(pObj);
|
135
182
|
if(destructive) Py_DECREF(pObj);
|
136
183
|
return rObj;
|
137
184
|
}
|
138
185
|
if(PyObject_TypeCheck(pObj,&PyDict_Type))
|
139
186
|
{
|
140
|
-
rObj=
|
187
|
+
rObj = ptorDict(pObj);
|
141
188
|
if(destructive) Py_DECREF(pObj);
|
142
189
|
return rObj;
|
143
190
|
}
|
144
191
|
|
145
|
-
if(pObj==Py_True)
|
192
|
+
if(pObj == Py_True)
|
146
193
|
{
|
147
194
|
if(destructive) Py_DECREF(Py_True);
|
148
195
|
return Qtrue;
|
149
196
|
}
|
150
|
-
if(pObj==Py_False)
|
197
|
+
if(pObj == Py_False)
|
151
198
|
{
|
152
199
|
if(destructive) Py_DECREF(Py_False);
|
153
200
|
return Qfalse;
|
154
201
|
}
|
155
|
-
if(pObj==Py_None)
|
202
|
+
if(pObj == Py_None)
|
156
203
|
{
|
157
204
|
return Qnil;
|
158
205
|
}
|
159
206
|
if(PyFunction_Check(pObj)||PyMethod_Check(pObj)||!PyObject_HasAttrString(pObj,"__dict__"))
|
160
207
|
{
|
161
|
-
return
|
208
|
+
return rpFunctionFromPyObject(pObj);
|
162
209
|
|
163
210
|
}
|
164
211
|
if(PyInstance_Check(pObj))
|
165
212
|
{
|
166
|
-
rObj=
|
213
|
+
rObj = rpInstanceFromPyObject(pObj);
|
167
214
|
return rObj;
|
168
215
|
}
|
169
|
-
|
216
|
+
|
217
|
+
// Fallthrough behavior: The object is a class which should be wrapped
|
218
|
+
return rpClassFromPyObject(pObj);
|
170
219
|
}
|
171
|
-
|
220
|
+
|
221
|
+
// Convert a Python object to a Ruby object and destroy the original
|
222
|
+
VALUE ptorObjectKeep(PyObject *pObj)
|
172
223
|
{
|
173
224
|
VALUE rObj;
|
174
|
-
rObj=
|
225
|
+
rObj = ptorObjectBasic(pObj, 0);
|
175
226
|
return rObj;
|
176
227
|
}
|
177
|
-
|
228
|
+
|
229
|
+
|
230
|
+
// Convert a Python object to a Ruby object while keeping the original
|
231
|
+
VALUE ptorObject(PyObject* pObj)
|
178
232
|
{
|
179
233
|
VALUE rObj;
|
180
|
-
rObj=
|
234
|
+
rObj = ptorObjectBasic(pObj, 1);
|
181
235
|
return rObj;
|
182
236
|
}
|
183
237
|
|