Module: Rupy::Conversion

Defined in:
lib/rupy/conversion.rb

Overview

This modules encapsulates the work of converting between native Ruby and Python types. Unsupported conversions raise UnsupportedConversion.

Defined Under Namespace

Classes: UnsupportedConversion

Class Method Summary collapse

Class Method Details

.ptorDict(pDict) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/rupy/conversion.rb', line 154

def self.ptorDict(pDict)
    rb_hash = {}

    pos = FFI::MemoryPointer.new :ssize_t
    pos.write_int 0
    key = FFI::MemoryPointer.new :pointer
    val = FFI::MemoryPointer.new :pointer

    while Python.PyDict_Next(pDict, pos, key, val) != 0
        pKey = key.read_pointer
        pVal = val.read_pointer
        rKey = ptorObject(pKey)
        rVal = ptorObject(pVal)
        rb_hash[rKey] = rVal
    end

    rb_hash
end

.ptorFloat(pNum) ⇒ Object



143
144
145
# File 'lib/rupy/conversion.rb', line 143

def self.ptorFloat(pNum)
    Python.PyFloat_AsDouble(pNum)
end

.ptorInt(pNum) ⇒ Object



134
135
136
# File 'lib/rupy/conversion.rb', line 134

def self.ptorInt(pNum)
    Python.PyInt_AsLong pNum
end

.ptorList(pList) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/rupy/conversion.rb', line 120

def self.ptorList(pList)
    rb_array = []
    list_size = Python.PyList_Size(pList)

    list_size.times do |i|
        element = Python.PyList_GetItem(pList, i)
        Python.Py_IncRef element
        rObject = ptorObject(element)
        rb_array.push rObject
    end

    rb_array
end

.ptorLong(pNum) ⇒ Object



138
139
140
141
# File 'lib/rupy/conversion.rb', line 138

def self.ptorLong(pNum)
    Python.PyLong_AsLong(pNum)
    #TODO Overflow Checking
end

.ptorObject(pObj) ⇒ Object

Converts a pointer to a Python object into a native ruby type, if possible. Otherwise raises an error.

Parameters:

  • pObj (FFI::Pointer)

    a pointer to a Python object

Returns:

  • a native ruby object.

Raises:



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/rupy/conversion.rb', line 197

def self.ptorObject(pObj)
    if Macros.PyObject_TypeCheck(pObj, Python.PyString_Type.to_ptr) != 0
        ptorString pObj
    elsif Macros.PyObject_TypeCheck(pObj, Python.PyList_Type.to_ptr) != 0
        ptorList pObj
    elsif Macros.PyObject_TypeCheck(pObj, Python.PyInt_Type.to_ptr) != 0
        ptorInt pObj
    elsif Macros.PyObject_TypeCheck(pObj, Python.PyLong_Type.to_ptr) != 0
        ptorLong pObj
    elsif Macros.PyObject_TypeCheck(pObj, Python.PyFloat_Type.to_ptr) != 0
        ptorFloat pObj
    elsif Macros.PyObject_TypeCheck(pObj, Python.PyTuple_Type.to_ptr) != 0
        ptorTuple pObj
    elsif Macros.PyObject_TypeCheck(pObj, Python.PyDict_Type.to_ptr) != 0
        ptorDict pObj
    elsif pObj == Macros.Py_True
        true
    elsif pObj == Macros.Py_False
        false
    elsif pObj == Macros.Py_None
        nil
    else
        pObj
    end
end

.ptorString(pString) ⇒ Object



116
117
118
# File 'lib/rupy/conversion.rb', line 116

def self.ptorString(pString)
    Python.PyString_AsString(pString)
end

.ptorTuple(pTuple) ⇒ Object



147
148
149
150
151
152
# File 'lib/rupy/conversion.rb', line 147

def self.ptorTuple(pTuple)
    pList = Python.PySequence_List pTuple
    rArray = ptorList pList
    Python.Py_DecRef pList
    rArray
end

.rtopArrayToList(rArray) ⇒ Object



17
18
19
20
21
22
23
24
# File 'lib/rupy/conversion.rb', line 17

def self.rtopArrayToList(rArray)
    size = rArray.length
    pList = Python.PyList_New size
    rArray.each_with_index do |el, i|
        Python.PyList_SetItem pList, i, rtopObject(el)
    end
    pList
end

.rtopArrayToTuple(rArray) ⇒ Object



26
27
28
29
30
31
# File 'lib/rupy/conversion.rb', line 26

def self.rtopArrayToTuple(rArray)
    pList = rtopArrayToList(rArray)
    pTuple = Python.PySequence_Tuple(pList)
    Python.Py_DecRef(pList)
    pTuple
end

.rtopBigNum(rNum) ⇒ Object



45
46
47
# File 'lib/rupy/conversion.rb', line 45

def self.rtopBigNum(rNum)
    Python.PyLong_FromLong(rNum)
end

.rtopFalseObject



53
54
55
# File 'lib/rupy/conversion.rb', line 53

def self.rtopFalse
    Macros.Py_RETURN_FALSE
end

.rtopFixnum(rNum) ⇒ Object



41
42
43
# File 'lib/rupy/conversion.rb', line 41

def self.rtopFixnum(rNum)
    Python.PyInt_FromLong(rNum)
end

.rtopFloat(rNum) ⇒ Object



49
50
51
# File 'lib/rupy/conversion.rb', line 49

def self.rtopFloat(rNum)
    Python.PyFloat_FromDouble(rNum)
end

.rtopFunction(rObj) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/rupy/conversion.rb', line 173

def self.rtopFunction(rObj)
    proc = FFI::Function.new(:pointer, [:pointer, :pointer]) do |p_self, p_args|
        PyObject.new(rObj.call(*ptorTuple(p_args))).pointer
    end

    defn = Python::PyMethodDef.new
    defn[:ml_name] = FFI::MemoryPointer.from_string("Rupy::Proc::%s" % rObj.object_id)
    defn[:ml_meth] = proc
    defn[:ml_flags] = Python::METH_VARARGS
    defn[:ml_doc] = nil

    return Python.PyCFunction_New(defn, nil)
end

.rtopGenerator(rObj) ⇒ Object



187
188
189
# File 'lib/rupy/conversion.rb', line 187

def self.rtopGenerator(rObj)

end

.rtopHash(rHash) ⇒ Object



33
34
35
36
37
38
39
# File 'lib/rupy/conversion.rb', line 33

def self.rtopHash(rHash)
    pDict = Python.PyDict_New
    rHash.each do |k,v|
        Python.PyDict_SetItem pDict, rtopObject(k, key=true), rtopObject(v)
    end
    pDict
end

.rtopNoneObject



61
62
63
# File 'lib/rupy/conversion.rb', line 61

def self.rtopNone
    Macros.Py_RETURN_NONE
end

.rtopObject(rObj, is_key = false) ⇒ FFI::Pointer

If possible converts a ruby type to an equivalent python native type.

Parameters:

  • rObj

    a native ruby type

  • is_key (Boolean) (defaults to: false)

    whether this object will be used as a key in a python dict.

Returns:

  • (FFI::Pointer)

    a to a C PyObject*

Raises:



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rupy/conversion.rb', line 76

def self.rtopObject(rObj, is_key=false)
    case rObj
        when String
            rtopString rObj
        when Array
            # If this object is going to be used as a
            # hash key we should make it a tuple instead
            # of a list
            if is_key
                rtopArrayToTuple rObj
            else
                rtopArrayToList rObj
            end
        when Hash
            rtopHash rObj
        when Fixnum
            rtopFixnum rObj
        when Bignum
            rtopBignum rObj
        when Float
            rtopFloat rObj
        when true
            rtopTrue
        when false
            rtopFalse
        when Symbol
            rtopSymbol rObj
        when Proc
            rtopFunction rObj
        when Method
            rtopFunction rObj
        when nil
            rtopNone
        when PyObject
            rObj.pointer
        else
            raise UnsupportedConversion.new("Unsupported type for RTOP conversion." )
    end
end

.rtopString(rString) ⇒ Object



13
14
15
# File 'lib/rupy/conversion.rb', line 13

def self.rtopString(rString)
    Python.PyString_FromString(rString)
end

.rtopSymbol(rSymbol) ⇒ Object



65
66
67
# File 'lib/rupy/conversion.rb', line 65

def self.rtopSymbol(rSymbol)
    Python.PyString_FromString rSymbol.to_s
end

.rtopTrueObject



57
58
59
# File 'lib/rupy/conversion.rb', line 57

def self.rtopTrue
    Macros.Py_RETURN_TRUE
end