rubypython 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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,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 actually methods.
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
@@ -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
@@ -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: achatesavc+rubypython@gmail.com
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
- Python must be installed. Currently, RubyPython requires python2.5 but it may soon be able to work with other versions. It should work fine with Python 2.4 but you may experience issues with lower versions. I have only tested it on Mac OSX 10.5, so I'm not sure what parts may need correcting for other systems.
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
@@ -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.new(GEM_NAME, VERS) do |p|
54
- p.developer(AUTHOR, EMAIL)
55
- p.description = DESCRIPTION
56
- p.summary = DESCRIPTION
57
- p.url = HOMEPATH
58
- p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
59
- p.test_globs = ["test/**/test_*.rb"]
60
- p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
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
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
63
+ self.changes = self.paragraphs_of("History.txt", 0..1).join("\n\n")
64
64
  #p.extra_deps = EXTRA_DEPENDENCIES
65
65
 
66
- p.spec_extras = {
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
- #define SAFE_START(reg) do { \
4
- reg=0; \
5
- if(!Py_IsInitialized())\
6
- {\
7
- Py_Initialize();\
8
- reg=1;\
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
- SAFE_START(here);
12
+
13
+ if(!Py_IsInitialized())
14
+ {
15
+ Py_Initialize();
16
+ here = 1;
17
+ }
18
+
23
19
  return here;
24
20
  }
25
21
 
26
- void safe_stop(int here)
22
+ /* Attempt to stop the embedded python interpreter.*/
23
+ void rpSafeStop(int here)
27
24
  {
28
- SAFE_END(here);
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
- char* func_name=STR2CSTR(name);
36
- VALUE rArgs;
37
- VALUE rReturn;
38
- if(!(TYPE(args)==T_ARRAY))
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
- rArgs=rb_ary_new();
41
- rb_ary_push(rArgs,args);
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
- rp_pythonerror();
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
- pFunc=PyObject_GetAttrString(pModule,func_name);
64
-
65
- pArgs=rtop_obj(rArgs,1);
88
+ Py_XDECREF(pModule);
66
89
 
67
- pReturn=PyObject_CallObject(pFunc,pArgs);
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
- Py_XDECREF(pModule);
75
- rp_pythonerror();
97
+ rpPythonError();
76
98
  return Qnil;
77
99
  }
78
100
 
79
- rReturn=ptor_obj(pReturn);
80
-
81
- Py_XDECREF(pArgs);
101
+ // Cleanup temporary objects
82
102
  Py_XDECREF(pFunc);
83
- Py_XDECREF(pModule);
103
+
84
104
  return rReturn;
85
105
  }
86
106
 
87
- PyObject* rp_get_module(VALUE mname)
107
+ PyObject* rpGetModule(VALUE mname)
88
108
  {
89
- if(rb_eql(mname,rb_str_new2("builtins")))
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
- PyObject *pModule,*pModuleName;
94
- pModuleName=rtop_string(mname);
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
- rp_pythonerror();
126
+ rpPythonError();
101
127
  return Py_None;
102
128
  }
129
+
103
130
  return pModule;
104
131
  }
105
132
 
106
- PyObject* rp_get_func_with_module(PyObject* pModule,VALUE name)
133
+ PyObject* rpGetFunctionWithModule(PyObject* pModule, VALUE name)
107
134
  {
108
135
  PyObject *pFunc;
109
- pFunc=PyObject_GetAttrString(pModule,STR2CSTR(name));
136
+
137
+ pFunc = PyObject_GetAttrString(pModule, STR2CSTR(name));
138
+
110
139
  if(PyErr_Occurred())
111
140
  {
112
141
  Py_XDECREF(pFunc);
113
- rp_pythonerror();
142
+ rpPythonError();
114
143
  return Py_None;
115
144
  }
145
+
116
146
  return pFunc;
117
147
  }
118
148
 
119
- VALUE rp_call_func(PyObject* pFunc, VALUE args)
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
- int safe_start();
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
- VALUE ptor_string(PyObject* pString)
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
- char *cstr;
8
- cstr=malloc(PyString_Size(pString)*sizeof(char));
9
- strcpy(cstr,PyString_AsString(pString));
10
- return rb_str_new2(cstr);
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 ptor_list(PyObject* pList)
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
- int i=0;
20
-
21
- rArray=rb_ary_new();
22
- int list_size=PyList_Size(pList);
23
- for(i=0;i<list_size;i++)
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=ptor_obj(element);
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 ptor_int(PyObject* pNum)
58
+ VALUE ptorInt(PyObject* pNum)
34
59
  {
35
- VALUE rNum;
36
60
  if(!PyInt_Check(pNum)) return Qnil;
37
- rNum=INT2NUM(PyInt_AsLong(pNum));
61
+
62
+ VALUE rNum;
63
+
64
+ rNum = INT2NUM(PyInt_AsLong(pNum));
38
65
  return rNum;
39
66
 
40
67
  }
41
68
 
42
- VALUE ptor_long(PyObject* pNum)
69
+ VALUE ptorLong(PyObject* pNum)
43
70
  {
71
+ if(!PyLong_Check(pNum)) return Qnil;
72
+
44
73
  VALUE rNum;
45
74
  long cNum;
46
- if(!PyLong_Check(pNum)) return Qnil;
47
- cNum=PyLong_AsLong(pNum);
75
+
76
+ cNum = PyLong_AsLong(pNum);
77
+
48
78
  if(PyErr_ExceptionMatches(PyExc_OverflowError))
49
79
  {
50
- rp_pythonerror();
80
+ rpPythonError();
51
81
  return Qnil;
52
82
  }
53
- rNum=INT2NUM(cNum);
83
+
84
+ rNum = INT2NUM(cNum);
85
+
54
86
  return rNum;
55
87
 
56
88
  }
57
89
 
58
- VALUE ptor_float(PyObject* pNum)
90
+ VALUE ptorFloat(PyObject* pNum)
59
91
  {
60
- VALUE rNum;
61
92
  if(!PyFloat_Check(pNum)) return Qnil;
62
- rNum=rb_float_new(PyFloat_AsDouble(pNum));
93
+
94
+ VALUE rNum;
95
+
96
+ rNum = rb_float_new(PyFloat_AsDouble(pNum));
97
+
63
98
  return rNum;
64
99
  }
65
100
 
66
- VALUE ptor_tuple(PyObject* pTuple)
101
+ VALUE ptorTuple(PyObject* pTuple)
67
102
  {
103
+ if(!PyTuple_Check(pTuple)) return Qnil;
104
+
68
105
  VALUE rArray;
69
106
  PyObject* pList;
70
- if(!PyTuple_Check(pTuple)) return Qnil;
71
- pList=PySequence_List(pTuple);
72
- rArray=ptor_list(pList);
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 ptor_dict(PyObject* pDict)
116
+ VALUE ptorDict(PyObject* pDict)
79
117
  {
80
- VALUE rHash;
81
118
  if(!PyDict_Check(pDict)) return Qnil;
82
- rHash=rb_hash_new();
119
+
120
+ VALUE rHash;
121
+ VALUE rKey, rVal;
83
122
  PyObject *key,*val;
84
- Py_ssize_t pos=0;
85
- VALUE rKey,rVal;
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=ptor_obj(key);
91
- rVal=ptor_obj(val);
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 ptor_obj_core(PyObject *pObj,int destructive)
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=ptor_string(pObj);
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=ptor_list(pObj);
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=ptor_int(pObj);
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=ptor_long(pObj);
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=ptor_float(pObj);
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=ptor_tuple(pObj);
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=ptor_dict(pObj);
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 rp_func_from_function(pObj);
208
+ return rpFunctionFromPyObject(pObj);
162
209
 
163
210
  }
164
211
  if(PyInstance_Check(pObj))
165
212
  {
166
- rObj=rp_inst_from_instance(pObj);
213
+ rObj = rpInstanceFromPyObject(pObj);
167
214
  return rObj;
168
215
  }
169
- return rp_cla_from_class(pObj);
216
+
217
+ // Fallthrough behavior: The object is a class which should be wrapped
218
+ return rpClassFromPyObject(pObj);
170
219
  }
171
- VALUE ptor_obj_no_destruct(PyObject *pObj)
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=ptor_obj_core(pObj,0);
225
+ rObj = ptorObjectBasic(pObj, 0);
175
226
  return rObj;
176
227
  }
177
- VALUE ptor_obj(PyObject* pObj)
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=ptor_obj_core(pObj,1);
234
+ rObj = ptorObjectBasic(pObj, 1);
181
235
  return rObj;
182
236
  }
183
237