rubypython 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,6 +5,10 @@ require 'rubypython/interpreter'
5
5
  module RubyPython
6
6
  # This module will hold the loaded RubyPython interpreter.
7
7
  module Python #:nodoc: all
8
+ @lock = Mutex.new
9
+ def self.synchronize(&block)
10
+ @lock.synchronize(&block)
11
+ end
8
12
  end
9
13
  end
10
14
 
@@ -13,183 +17,181 @@ class RubyPython::Interpreter
13
17
  # has been infected, the #infect! method is removed from
14
18
  # RubyPython::Interpreter.
15
19
  def infect!(mod)
16
- Mutex.new.synchronize do
17
- self.class.class_eval do
18
- undef :infect!
19
- end
20
-
21
- mod.extend ::FFI::Library
22
- # FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL
23
- mod.ffi_lib_flags :lazy, :global
24
- mod.ffi_lib self.library
25
-
26
- # This class is a little bit of a hack to extract the address of
27
- # global structs. If someone knows a better way please let me know.
28
- mod.module_eval do
29
- self.const_set :DummyStruct, Class.new(::FFI::Struct)
30
- self::DummyStruct.layout :dummy_var, :int
31
-
32
- self.const_set(:PY_FILE_INPUT, 257)
33
- self.const_set(:PY_EVAL_INPUT, 258)
34
- self.const_set(:METH_VARARGS, 0x0001)
35
-
36
- # Function methods & constants
37
- attach_function :PyCFunction_New, [:pointer, :pointer], :pointer
38
- callback :PyCFunction, [:pointer, :pointer], :pointer
39
-
40
- attach_function :PyRun_String, [:string, :int, :pointer, :pointer], :pointer
41
- attach_function :PyRun_SimpleString, [:string], :pointer
42
- attach_function :Py_CompileString, [:string, :string, :int], :pointer
43
- attach_function :PyEval_EvalCode, [:pointer, :pointer, :pointer], :pointer
44
- attach_function :PyErr_SetString, [:pointer, :string], :void
45
-
46
- # Python interpreter startup and shutdown
47
- attach_function :Py_IsInitialized, [], :int
48
- attach_function :Py_Initialize, [], :void
49
- attach_function :Py_Finalize, [], :void
50
-
51
- # Module methods
52
- attach_function :PyImport_ImportModule, [:string], :pointer
53
-
54
- # Object Methods
55
- attach_function :PyObject_HasAttrString, [:pointer, :string], :int
56
- attach_function :PyObject_GetAttrString, [:pointer, :string], :pointer
57
- attach_function :PyObject_SetAttrString, [:pointer, :string, :pointer], :int
58
- attach_function :PyObject_Dir, [:pointer], :pointer
59
-
60
- attach_function :PyObject_Compare, [:pointer, :pointer], :int
61
-
62
- attach_function :PyObject_Call, [:pointer, :pointer, :pointer], :pointer
63
- attach_function :PyObject_CallObject, [:pointer, :pointer], :pointer
64
- attach_function :PyCallable_Check, [:pointer], :int
65
-
66
- ### Python To Ruby Conversion
67
- # String Methods
68
- attach_function :PyString_AsString, [:pointer], :string
69
- attach_function :PyString_FromString, [:string], :pointer
70
- attach_function :PyString_AsStringAndSize, [:pointer, :pointer, :pointer], :int
71
- attach_function :PyString_FromStringAndSize, [:buffer_in, :ssize_t], :pointer
72
-
73
- # List Methods
74
- attach_function :PyList_GetItem, [:pointer, :int], :pointer
75
- attach_function :PyList_Size, [:pointer], :int
76
- attach_function :PyList_New, [:int], :pointer
77
- attach_function :PyList_SetItem, [:pointer, :int, :pointer], :void
78
-
79
- # Integer Methods
80
- attach_function :PyInt_AsLong, [:pointer], :long
81
- attach_function :PyInt_FromLong, [:long], :pointer
82
-
83
- attach_function :PyLong_AsLong, [:pointer], :long
84
- attach_function :PyLong_FromLong, [:pointer], :long
85
-
86
- # Float Methods
87
- attach_function :PyFloat_AsDouble, [:pointer], :double
88
- attach_function :PyFloat_FromDouble, [:double], :pointer
89
-
90
- # Tuple Methods
91
- attach_function :PySequence_List, [:pointer], :pointer
92
- attach_function :PySequence_Tuple, [:pointer], :pointer
93
- attach_function :PyTuple_Pack, [:int, :varargs], :pointer
94
-
95
- # Dict/Hash Methods
96
- attach_function :PyDict_Next, [:pointer, :pointer, :pointer, :pointer], :int
97
- attach_function :PyDict_New, [], :pointer
98
- attach_function :PyDict_SetItem, [:pointer, :pointer, :pointer], :int
99
- attach_function :PyDict_Contains, [:pointer, :pointer], :int
100
- attach_function :PyDict_GetItem, [:pointer, :pointer], :pointer
101
-
102
- # Error Methods
103
- attach_variable :PyExc_Exception, self::DummyStruct.by_ref
104
- attach_variable :PyExc_StopIteration, self::DummyStruct.by_ref
105
- attach_function :PyErr_SetNone, [:pointer], :void
106
- attach_function :PyErr_Fetch, [:pointer, :pointer, :pointer], :void
107
- attach_function :PyErr_Occurred, [], :pointer
108
- attach_function :PyErr_Clear, [], :void
109
-
110
- # Reference Counting
111
- attach_function :Py_IncRef, [:pointer], :void
112
- attach_function :Py_DecRef, [:pointer], :void
113
-
114
- # Type Objects
115
- # attach_variable :PyBaseObject_Type, self::DummyStruct.by_value # built-in 'object'
116
- # attach_variable :PyBaseString_Type, self::DummyStruct.by_value
117
- # attach_variable :PyBool_Type, self::DummyStruct.by_value
118
- # attach_variable :PyBuffer_Type, self::DummyStruct.by_value
119
- # attach_variable :PyByteArrayIter_Type, self::DummyStruct.by_value
120
- # attach_variable :PyByteArray_Type, self::DummyStruct.by_value
121
- attach_variable :PyCFunction_Type, self::DummyStruct.by_value
122
- # attach_variable :PyCObject_Type, self::DummyStruct.by_value
123
- # attach_variable :PyCallIter_Type, self::DummyStruct.by_value
124
- # attach_variable :PyCapsule_Type, self::DummyStruct.by_value
125
- # attach_variable :PyCell_Type, self::DummyStruct.by_value
126
- # attach_variable :PyClassMethod_Type, self::DummyStruct.by_value
127
- attach_variable :PyClass_Type, self::DummyStruct.by_value
128
- # attach_variable :PyCode_Type, self::DummyStruct.by_value
129
- # attach_variable :PyComplex_Type, self::DummyStruct.by_value
130
- # attach_variable :PyDictItems_Type, self::DummyStruct.by_value
131
- # attach_variable :PyDictIterItem_Type, self::DummyStruct.by_value
132
- # attach_variable :PyDictIterKey_Type, self::DummyStruct.by_value
133
- # attach_variable :PyDictIterValue_Type, self::DummyStruct.by_value
134
- # attach_variable :PyDictKeys_Type, self::DummyStruct.by_value
135
- # attach_variable :PyDictProxy_Type, self::DummyStruct.by_value
136
- # attach_variable :PyDictValues_Type, self::DummyStruct.by_value
137
- attach_variable :PyDict_Type, self::DummyStruct.by_value
138
- # attach_variable :PyEllipsis_Type, self::DummyStruct.by_value
139
- # attach_variable :PyEnum_Type, self::DummyStruct.by_value
140
- # attach_variable :PyFile_Type, self::DummyStruct.by_value
141
- attach_variable :PyFloat_Type, self::DummyStruct.by_value
142
- # attach_variable :PyFrame_Type, self::DummyStruct.by_value
143
- # attach_variable :PyFrozenSet_Type, self::DummyStruct.by_value
144
- attach_variable :PyFunction_Type, self::DummyStruct.by_value
145
- # attach_variable :PyGen_Type, self::DummyStruct.by_value
146
- # attach_variable :PyGetSetDescr_Type, self::DummyStruct.by_value
147
- # attach_variable :PyInstance_Type, self::DummyStruct.by_value
148
- attach_variable :PyInt_Type, self::DummyStruct.by_value
149
- attach_variable :PyList_Type, self::DummyStruct.by_value
150
- attach_variable :PyLong_Type, self::DummyStruct.by_value
151
- # attach_variable :PyMemberDescr_Type, self::DummyStruct.by_value
152
- # attach_variable :PyMemoryView_Type, self::DummyStruct.by_value
153
- attach_variable :PyMethod_Type, self::DummyStruct.by_value
154
- # attach_variable :PyModule_Type, self::DummyStruct.by_value
155
- # attach_variable :PyNullImporter_Type, self::DummyStruct.by_value
156
- # attach_variable :PyProperty_Type, self::DummyStruct.by_value
157
- # attach_variable :PyRange_Type, self::DummyStruct.by_value
158
- # attach_variable :PyReversed_Type, self::DummyStruct.by_value
159
- # attach_variable :PySTEntry_Type, self::DummyStruct.by_value
160
- # attach_variable :PySeqIter_Type, self::DummyStruct.by_value
161
- # attach_variable :PySet_Type, self::DummyStruct.by_value
162
- # attach_variable :PySlice_Type, self::DummyStruct.by_value
163
- # attach_variable :PyStaticMethod_Type, self::DummyStruct.by_value
164
- attach_variable :PyString_Type, self::DummyStruct.by_value
165
- # attach_variable :PySuper_Type, self::DummyStruct.by_value # built-in 'super'
166
- # attach_variable :PyTraceBack_Type, self::DummyStruct.by_value
167
- attach_variable :PyTuple_Type, self::DummyStruct.by_value
168
- attach_variable :PyType_Type, self::DummyStruct.by_value
169
- # attach_variable :PyUnicode_Type, self::DummyStruct.by_value
170
- # attach_variable :PyWrapperDescr_Type, self::DummyStruct.by_value
171
-
172
- attach_variable :Py_TrueStruct, :_Py_TrueStruct, self::DummyStruct.by_value
173
- attach_variable :Py_ZeroStruct, :_Py_ZeroStruct, self::DummyStruct.by_value
174
- attach_variable :Py_NoneStruct, :_Py_NoneStruct, self::DummyStruct.by_value
175
-
176
- # This is an implementation of the basic structure of a Python PyObject
177
- # struct. The C struct is actually much larger, but since we only access
178
- # the first two data members via FFI and always deal with struct
179
- # pointers there is no need to mess around with the rest of the object.
180
- self.const_set :PyObjectStruct, Class.new(::FFI::Struct)
181
- self::PyObjectStruct.layout :ob_refcnt, :ssize_t,
182
- :ob_type, :pointer
183
-
184
- # This struct is used when defining Python methods.
185
- self.const_set :PyMethodDef, Class.new(::FFI::Struct)
186
- self::PyMethodDef.layout :ml_name, :pointer,
187
- :ml_meth, :PyCFunction,
188
- :ml_flags, :int,
189
- :ml_doc, :pointer
190
- end
20
+ self.class.class_eval do
21
+ undef :infect!
22
+ end
191
23
 
24
+ mod.extend ::FFI::Library
25
+ # FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL
26
+ mod.ffi_lib_flags :lazy, :global
27
+ mod.ffi_lib self.library
28
+
29
+ # This class is a little bit of a hack to extract the address of
30
+ # global structs. If someone knows a better way please let me know.
31
+ mod.module_eval do
32
+ self.const_set :DummyStruct, Class.new(::FFI::Struct)
33
+ self::DummyStruct.layout :dummy_var, :int
34
+
35
+ self.const_set(:PY_FILE_INPUT, 257)
36
+ self.const_set(:PY_EVAL_INPUT, 258)
37
+ self.const_set(:METH_VARARGS, 0x0001)
38
+
39
+ # Function methods & constants
40
+ attach_function :PyCFunction_New, [:pointer, :pointer], :pointer
41
+ callback :PyCFunction, [:pointer, :pointer], :pointer
42
+
43
+ attach_function :PyRun_String, [:string, :int, :pointer, :pointer], :pointer
44
+ attach_function :PyRun_SimpleString, [:string], :pointer
45
+ attach_function :Py_CompileString, [:string, :string, :int], :pointer
46
+ attach_function :PyEval_EvalCode, [:pointer, :pointer, :pointer], :pointer
47
+ attach_function :PyErr_SetString, [:pointer, :string], :void
48
+
49
+ # Python interpreter startup and shutdown
50
+ attach_function :Py_IsInitialized, [], :int
51
+ attach_function :Py_Initialize, [], :void
52
+ attach_function :Py_Finalize, [], :void
53
+
54
+ # Module methods
55
+ attach_function :PyImport_ImportModule, [:string], :pointer
56
+
57
+ # Object Methods
58
+ attach_function :PyObject_HasAttrString, [:pointer, :string], :int
59
+ attach_function :PyObject_GetAttrString, [:pointer, :string], :pointer
60
+ attach_function :PyObject_SetAttrString, [:pointer, :string, :pointer], :int
61
+ attach_function :PyObject_Dir, [:pointer], :pointer
62
+
63
+ attach_function :PyObject_Compare, [:pointer, :pointer], :int
64
+
65
+ attach_function :PyObject_Call, [:pointer, :pointer, :pointer], :pointer
66
+ attach_function :PyObject_CallObject, [:pointer, :pointer], :pointer
67
+ attach_function :PyCallable_Check, [:pointer], :int
68
+
69
+ ### Python To Ruby Conversion
70
+ # String Methods
71
+ attach_function :PyString_AsString, [:pointer], :string
72
+ attach_function :PyString_FromString, [:string], :pointer
73
+ attach_function :PyString_AsStringAndSize, [:pointer, :pointer, :pointer], :int
74
+ attach_function :PyString_FromStringAndSize, [:buffer_in, :ssize_t], :pointer
75
+
76
+ # List Methods
77
+ attach_function :PyList_GetItem, [:pointer, :int], :pointer
78
+ attach_function :PyList_Size, [:pointer], :int
79
+ attach_function :PyList_New, [:int], :pointer
80
+ attach_function :PyList_SetItem, [:pointer, :int, :pointer], :void
81
+
82
+ # Integer Methods
83
+ attach_function :PyInt_AsLong, [:pointer], :long
84
+ attach_function :PyInt_FromLong, [:long], :pointer
85
+
86
+ attach_function :PyLong_AsLong, [:pointer], :long
87
+ attach_function :PyLong_FromLong, [:pointer], :long
88
+
89
+ # Float Methods
90
+ attach_function :PyFloat_AsDouble, [:pointer], :double
91
+ attach_function :PyFloat_FromDouble, [:double], :pointer
92
+
93
+ # Tuple Methods
94
+ attach_function :PySequence_List, [:pointer], :pointer
95
+ attach_function :PyList_AsTuple, [:pointer], :pointer
96
+ attach_function :PyTuple_Pack, [:int, :varargs], :pointer
97
+
98
+ # Dict/Hash Methods
99
+ attach_function :PyDict_Next, [:pointer, :pointer, :pointer, :pointer], :int
100
+ attach_function :PyDict_New, [], :pointer
101
+ attach_function :PyDict_SetItem, [:pointer, :pointer, :pointer], :int
102
+ attach_function :PyDict_Contains, [:pointer, :pointer], :int
103
+ attach_function :PyDict_GetItem, [:pointer, :pointer], :pointer
104
+
105
+ # Error Methods
106
+ attach_variable :PyExc_Exception, self::DummyStruct.by_ref
107
+ attach_variable :PyExc_StopIteration, self::DummyStruct.by_ref
108
+ attach_function :PyErr_SetNone, [:pointer], :void
109
+ attach_function :PyErr_Fetch, [:pointer, :pointer, :pointer], :void
110
+ attach_function :PyErr_Occurred, [], :pointer
111
+ attach_function :PyErr_Clear, [], :void
112
+
113
+ # Reference Counting
114
+ attach_function :Py_IncRef, [:pointer], :void
115
+ attach_function :Py_DecRef, [:pointer], :void
116
+
117
+ # Type Objects
118
+ # attach_variable :PyBaseObject_Type, self::DummyStruct.by_value # built-in 'object'
119
+ # attach_variable :PyBaseString_Type, self::DummyStruct.by_value
120
+ # attach_variable :PyBool_Type, self::DummyStruct.by_value
121
+ # attach_variable :PyBuffer_Type, self::DummyStruct.by_value
122
+ # attach_variable :PyByteArrayIter_Type, self::DummyStruct.by_value
123
+ # attach_variable :PyByteArray_Type, self::DummyStruct.by_value
124
+ attach_variable :PyCFunction_Type, self::DummyStruct.by_value
125
+ # attach_variable :PyCObject_Type, self::DummyStruct.by_value
126
+ # attach_variable :PyCallIter_Type, self::DummyStruct.by_value
127
+ # attach_variable :PyCapsule_Type, self::DummyStruct.by_value
128
+ # attach_variable :PyCell_Type, self::DummyStruct.by_value
129
+ # attach_variable :PyClassMethod_Type, self::DummyStruct.by_value
130
+ attach_variable :PyClass_Type, self::DummyStruct.by_value
131
+ # attach_variable :PyCode_Type, self::DummyStruct.by_value
132
+ # attach_variable :PyComplex_Type, self::DummyStruct.by_value
133
+ # attach_variable :PyDictItems_Type, self::DummyStruct.by_value
134
+ # attach_variable :PyDictIterItem_Type, self::DummyStruct.by_value
135
+ # attach_variable :PyDictIterKey_Type, self::DummyStruct.by_value
136
+ # attach_variable :PyDictIterValue_Type, self::DummyStruct.by_value
137
+ # attach_variable :PyDictKeys_Type, self::DummyStruct.by_value
138
+ # attach_variable :PyDictProxy_Type, self::DummyStruct.by_value
139
+ # attach_variable :PyDictValues_Type, self::DummyStruct.by_value
140
+ attach_variable :PyDict_Type, self::DummyStruct.by_value
141
+ # attach_variable :PyEllipsis_Type, self::DummyStruct.by_value
142
+ # attach_variable :PyEnum_Type, self::DummyStruct.by_value
143
+ # attach_variable :PyFile_Type, self::DummyStruct.by_value
144
+ attach_variable :PyFloat_Type, self::DummyStruct.by_value
145
+ # attach_variable :PyFrame_Type, self::DummyStruct.by_value
146
+ # attach_variable :PyFrozenSet_Type, self::DummyStruct.by_value
147
+ attach_variable :PyFunction_Type, self::DummyStruct.by_value
148
+ # attach_variable :PyGen_Type, self::DummyStruct.by_value
149
+ # attach_variable :PyGetSetDescr_Type, self::DummyStruct.by_value
150
+ # attach_variable :PyInstance_Type, self::DummyStruct.by_value
151
+ attach_variable :PyInt_Type, self::DummyStruct.by_value
152
+ attach_variable :PyList_Type, self::DummyStruct.by_value
153
+ attach_variable :PyLong_Type, self::DummyStruct.by_value
154
+ # attach_variable :PyMemberDescr_Type, self::DummyStruct.by_value
155
+ # attach_variable :PyMemoryView_Type, self::DummyStruct.by_value
156
+ attach_variable :PyMethod_Type, self::DummyStruct.by_value
157
+ # attach_variable :PyModule_Type, self::DummyStruct.by_value
158
+ # attach_variable :PyNullImporter_Type, self::DummyStruct.by_value
159
+ # attach_variable :PyProperty_Type, self::DummyStruct.by_value
160
+ # attach_variable :PyRange_Type, self::DummyStruct.by_value
161
+ # attach_variable :PyReversed_Type, self::DummyStruct.by_value
162
+ # attach_variable :PySTEntry_Type, self::DummyStruct.by_value
163
+ # attach_variable :PySeqIter_Type, self::DummyStruct.by_value
164
+ # attach_variable :PySet_Type, self::DummyStruct.by_value
165
+ # attach_variable :PySlice_Type, self::DummyStruct.by_value
166
+ # attach_variable :PyStaticMethod_Type, self::DummyStruct.by_value
167
+ attach_variable :PyString_Type, self::DummyStruct.by_value
168
+ # attach_variable :PySuper_Type, self::DummyStruct.by_value # built-in 'super'
169
+ # attach_variable :PyTraceBack_Type, self::DummyStruct.by_value
170
+ attach_variable :PyTuple_Type, self::DummyStruct.by_value
171
+ attach_variable :PyType_Type, self::DummyStruct.by_value
172
+ # attach_variable :PyUnicode_Type, self::DummyStruct.by_value
173
+ # attach_variable :PyWrapperDescr_Type, self::DummyStruct.by_value
174
+
175
+ attach_variable :Py_TrueStruct, :_Py_TrueStruct, self::DummyStruct.by_value
176
+ attach_variable :Py_ZeroStruct, :_Py_ZeroStruct, self::DummyStruct.by_value
177
+ attach_variable :Py_NoneStruct, :_Py_NoneStruct, self::DummyStruct.by_value
178
+
179
+ # This is an implementation of the basic structure of a Python PyObject
180
+ # struct. The C struct is actually much larger, but since we only access
181
+ # the first two data members via FFI and always deal with struct
182
+ # pointers there is no need to mess around with the rest of the object.
183
+ self.const_set :PyObjectStruct, Class.new(::FFI::Struct)
184
+ self::PyObjectStruct.layout :ob_refcnt, :ssize_t,
185
+ :ob_type, :pointer
186
+
187
+ # This struct is used when defining Python methods.
188
+ self.const_set :PyMethodDef, Class.new(::FFI::Struct)
189
+ self::PyMethodDef.layout :ml_name, :pointer,
190
+ :ml_meth, :PyCFunction,
191
+ :ml_flags, :int,
192
+ :ml_doc, :pointer
192
193
  end
194
+
193
195
  end
194
196
  private :infect!
195
197
  end
@@ -41,7 +41,7 @@ class RubyPython::PythonError < RuntimeError
41
41
 
42
42
  # Decrease the reference count. This will happen anyway when they go out
43
43
  # of scope but might as well.
44
- rbValue.xDecref
44
+ rbValue.xDecref if not rbValue.null?
45
45
  pyName = rbType.getAttr("__name__")
46
46
 
47
47
  rbType.xDecref
@@ -88,16 +88,10 @@ module RubyPython
88
88
  end
89
89
 
90
90
  # Handles the job of wrapping up anything returned by a RubyPyProxy
91
- # instance. The behavior differs depending on the value of
92
- # +RubyPython.legacy_mode+. If legacy mode is inactive, every returned
93
- # object is wrapped by an instance of +RubyPyProxy+. If legacy mode is
94
- # active, RubyPython first attempts to convert the returned object to a
95
- # native Ruby type, and then only wraps the object if this fails.
91
+ # instance. Every returned # object is wrapped by an instance of +RubyPyProxy+
96
92
  def _wrap(pyobject)
97
93
  if pyobject.class?
98
94
  RubyPyClass.new(pyobject)
99
- elsif RubyPython.__send__ :legacy_mode?
100
- pyobject.rubify
101
95
  else
102
96
  RubyPyProxy.new(pyobject)
103
97
  end
@@ -136,7 +130,6 @@ module RubyPython
136
130
  # attempting to call a method with keyword arguments.
137
131
  # 4. The Python method or value will be called, if it's callable.
138
132
  # 5. RubyPython will wrap the return value in a RubyPyProxy object
139
- # (unless legacy_mode has been turned on).
140
133
  # 6. If a block has been provided, the wrapped return value will be
141
134
  # passed into the block.
142
135
  def method_missing(name, *args, &block)
@@ -156,7 +149,7 @@ module RubyPython
156
149
 
157
150
  if name =~ /=$/
158
151
  return @pObject.setAttr(name.chomp('='),
159
- PyObject.convert(*args).first)
152
+ PyObject.new(args.pop))
160
153
  elsif name =~ /!$/
161
154
  kwargs = true
162
155
  name.chomp! "!"
@@ -171,31 +164,10 @@ module RubyPython
171
164
  pReturn = pFunc
172
165
  else
173
166
  if kwargs and args.last.is_a?(Hash)
174
- pKeywords = PyObject.convert(args.pop).first
167
+ pKeywords = PyObject.new args.pop
175
168
  end
176
-
177
- orig_args = args
178
- args = PyObject.convert(*args)
179
- pTuple = PyObject.buildArgTuple(*args)
180
- pReturn = if pKeywords
181
- pFunc.callObjectKeywords(pTuple, pKeywords)
182
- else
183
- pFunc.callObject(pTuple)
184
- end
185
-
186
- # Clean up unused Python vars instead of waiting on Ruby's GC to
187
- # do it.
169
+ pReturn = _method_call(pFunc, args, pKeywords)
188
170
  pFunc.xDecref
189
- pTuple.xDecref
190
- pKeywords.xDecref if pKeywords
191
- orig_args.each_with_index do |arg, i|
192
- # Only decref objects that were created in PyObject.convert.
193
- if !arg.kind_of?(RubyPython::PyObject) and !arg.kind_of?(RubyPython::RubyPyProxy)
194
- args[i].xDecref
195
- end
196
- end
197
-
198
- raise PythonError.handle_error if PythonError.error?
199
171
  end
200
172
  else
201
173
  pReturn = pFunc
@@ -210,10 +182,33 @@ module RubyPython
210
182
  end
211
183
  end
212
184
 
185
+ #Handles the of calling a wrapped callable Python object at a higher level
186
+ #than +PyObject#callObject+. For internal use only.
187
+ def _method_call(pFunc, args, pKeywords)
188
+ pTuple = PyObject.buildArgTuple(*args)
189
+ pReturn = if pKeywords
190
+ pFunc.callObjectKeywords(pTuple, pKeywords)
191
+ else
192
+ pFunc.callObject(pTuple)
193
+ end
194
+
195
+ # Clean up unused Python vars instead of waiting on Ruby's GC to
196
+ # do it.
197
+ pTuple.xDecref
198
+ pKeywords.xDecref if pKeywords
199
+ raise PythonError.handle_error if PythonError.error?
200
+ pReturn
201
+ end
202
+ private :_method_call
203
+
213
204
  # RubyPython will attempt to translate the wrapped object into a native
214
205
  # Ruby object. This will only succeed for simple built-in type.
215
206
  def rubify
216
- @pObject.rubify
207
+ converted = @pObject.rubify
208
+ if converted.kind_of? ::FFI::Pointer
209
+ converted = self.class.new converted
210
+ end
211
+ converted
217
212
  end
218
213
 
219
214
  # Returns the String representation of the wrapped object via a call to
@@ -305,10 +300,7 @@ module RubyPython
305
300
  # Create an instance of the wrapped class. This is a workaround for the
306
301
  # fact that \Python classes are meant to be callable.
307
302
  def new(*args)
308
- args = PyObject.convert(*args)
309
- pTuple = PyObject.buildArgTuple(*args)
310
- pReturn = @pObject.callObject(pTuple)
311
- raise PythonError.handle_error if PythonError.error?
303
+ pReturn = _method_call(@pObject, args, nil)
312
304
  RubyPyInstance.new pReturn
313
305
  end
314
306
  end