rubypython 0.6.2 → 0.6.3
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.tar.gz.sig +0 -0
- data/Contributors.rdoc +1 -0
- data/History.rdoc +9 -0
- data/Manifest.txt +0 -2
- data/Rakefile +1 -1
- data/lib/rubypython.rb +16 -71
- data/lib/rubypython/conversion.rb +60 -17
- data/lib/rubypython/interpreter.rb +10 -1
- data/lib/rubypython/operators.rb +3 -7
- data/lib/rubypython/pyobject.rb +10 -53
- data/lib/rubypython/python.rb +177 -175
- data/lib/rubypython/pythonerror.rb +1 -1
- data/lib/rubypython/rubypyproxy.rb +29 -37
- data/spec/basic_spec.rb +2 -2
- data/spec/pyobject_spec.rb +0 -44
- data/spec/refcnt_spec.rb +38 -2
- data/spec/spec_helper.rb +5 -1
- metadata +17 -19
- metadata.gz.sig +0 -0
- data/lib/rubypython/legacy.rb +0 -18
- data/spec/legacy_spec.rb +0 -46
data/lib/rubypython/python.rb
CHANGED
@@ -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
|
-
|
17
|
-
|
18
|
-
|
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.
|
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.
|
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.
|
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
|
-
|
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
|