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