pycall 1.0.3 → 1.3.1
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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +67 -0
- data/.travis.yml +46 -21
- data/CHANGES.md +62 -0
- data/README.md +66 -2
- data/Rakefile +2 -0
- data/appveyor.yml +8 -54
- data/ci/travis_install.sh +30 -9
- data/examples/classifier_comparison.rb +1 -1
- data/examples/hist.rb +1 -1
- data/examples/notebooks/classifier_comparison.ipynb +1 -1
- data/ext/pycall/libpython.c +12 -1
- data/ext/pycall/pycall.c +149 -5
- data/ext/pycall/pycall.h +23 -0
- data/ext/pycall/pycall_internal.h +35 -1
- data/ext/pycall/ruby_wrapper.c +171 -79
- data/ext/pycall/thread.c +36 -0
- data/images/pycallrb_logo.png +0 -0
- data/images/pycallrb_logo_200.png +0 -0
- data/lib/pycall.rb +10 -0
- data/lib/pycall/dict.rb +2 -2
- data/lib/pycall/iruby_helper.rb +1 -1
- data/lib/pycall/libpython/finder.rb +23 -22
- data/lib/pycall/list.rb +2 -2
- data/lib/pycall/pymodule_wrapper.rb +46 -0
- data/lib/pycall/pyobject_wrapper.rb +4 -32
- data/lib/pycall/python/investigator.py +0 -4
- data/lib/pycall/pytypeobject_wrapper.rb +19 -0
- data/lib/pycall/version.rb +7 -1
- data/pycall.gemspec +11 -4
- metadata +21 -18
- data/lib/pycall/conversion.rb +0 -173
- data/lib/pycall/tuple.rb +0 -46
data/lib/pycall/conversion.rb
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
module PyCall
|
|
2
|
-
module Conversions
|
|
3
|
-
@python_type_map = []
|
|
4
|
-
|
|
5
|
-
class TypePair < Struct.new(:pytype, :rbtype)
|
|
6
|
-
def to_a
|
|
7
|
-
[pytype, rbtype]
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def self.each_type_pair
|
|
12
|
-
i, n = 1, @python_type_map.length
|
|
13
|
-
while i <= n
|
|
14
|
-
yield @python_type_map[n - i]
|
|
15
|
-
i += 1
|
|
16
|
-
end
|
|
17
|
-
self
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def self.python_type_mapping(pytype, rbtype)
|
|
21
|
-
each_type_pair do |type_pair|
|
|
22
|
-
next unless pytype == type_pair.pytype
|
|
23
|
-
type_pair.rbtype = rbtype
|
|
24
|
-
return
|
|
25
|
-
end
|
|
26
|
-
@python_type_map << TypePair.new(pytype, rbtype)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Convert a PyCall::PyObjectStruct object to a Ruby object
|
|
30
|
-
#
|
|
31
|
-
# @param [PyCall::PyObjectStruct] pyptr a PyObjectStruct object.
|
|
32
|
-
#
|
|
33
|
-
# @return a Ruby object converted from `pyptr`.
|
|
34
|
-
def self.to_ruby(pyptr)
|
|
35
|
-
return nil if pyptr.null? || PyCall.none?(pyptr)
|
|
36
|
-
|
|
37
|
-
case
|
|
38
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyType_Type)
|
|
39
|
-
return TypeObject.new(pyptr)
|
|
40
|
-
|
|
41
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyBool_Type)
|
|
42
|
-
return Conversions.convert_to_boolean(pyptr)
|
|
43
|
-
|
|
44
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyInt_Type)
|
|
45
|
-
return Conversions.convert_to_integer(pyptr)
|
|
46
|
-
|
|
47
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyLong_Type)
|
|
48
|
-
# TODO: should make Bignum
|
|
49
|
-
|
|
50
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyFloat_Type)
|
|
51
|
-
return Conversions.convert_to_float(pyptr)
|
|
52
|
-
|
|
53
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyComplex_Type)
|
|
54
|
-
return Conversions.convert_to_complex(pyptr)
|
|
55
|
-
|
|
56
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyString_Type)
|
|
57
|
-
return Conversions.convert_to_string(pyptr)
|
|
58
|
-
|
|
59
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyUnicode_Type)
|
|
60
|
-
py_str_ptr = LibPython.PyUnicode_AsUTF8String(pyptr)
|
|
61
|
-
return Conversions.convert_to_string(py_str_ptr).force_encoding(Encoding::UTF_8)
|
|
62
|
-
|
|
63
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyList_Type)
|
|
64
|
-
return PyCall::List.new(pyptr)
|
|
65
|
-
|
|
66
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyTuple_Type)
|
|
67
|
-
return Conversions.convert_to_tuple(pyptr)
|
|
68
|
-
|
|
69
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyDict_Type)
|
|
70
|
-
return PyCall::Dict.new(pyptr)
|
|
71
|
-
|
|
72
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PySet_Type)
|
|
73
|
-
return PyCall::Set.new(pyptr)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
pyobj = PyObject.new(pyptr)
|
|
77
|
-
each_type_pair do |tp|
|
|
78
|
-
pytype, rbtype = tp.to_a
|
|
79
|
-
next unless pyobj.kind_of?(pytype)
|
|
80
|
-
case
|
|
81
|
-
when rbtype.kind_of?(Proc)
|
|
82
|
-
return rbtype.(pyobj)
|
|
83
|
-
when rbtype.respond_to?(:from_python)
|
|
84
|
-
return rbtype.from_python(pyobj)
|
|
85
|
-
else
|
|
86
|
-
return rbtype.new(pyobj)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
pyobj
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def self.from_ruby(obj)
|
|
93
|
-
case obj
|
|
94
|
-
when LibPython::PyObjectStruct
|
|
95
|
-
obj
|
|
96
|
-
when PyObject, PyObjectWrapper
|
|
97
|
-
obj.__pyobj__
|
|
98
|
-
when TrueClass, FalseClass
|
|
99
|
-
LibPython.PyBool_FromLong(obj ? 1 : 0)
|
|
100
|
-
when Integer
|
|
101
|
-
LibPython.PyInt_FromSsize_t(obj)
|
|
102
|
-
when Float
|
|
103
|
-
LibPython.PyFloat_FromDouble(obj)
|
|
104
|
-
when String
|
|
105
|
-
if obj.encoding != Encoding::BINARY && (PyCall.unicode_literals? || !obj.ascii_only?)
|
|
106
|
-
obj = obj.encode(Encoding::UTF_8) if obj.encoding != Encoding::UTF_8
|
|
107
|
-
return LibPython.PyUnicode_DecodeUTF8(obj, obj.bytesize, nil)
|
|
108
|
-
end
|
|
109
|
-
LibPython.PyString_FromStringAndSize(obj, obj.bytesize)
|
|
110
|
-
when Symbol
|
|
111
|
-
from_ruby(obj.to_s)
|
|
112
|
-
when Array
|
|
113
|
-
PyCall::List.new(obj).__pyobj__
|
|
114
|
-
when Hash
|
|
115
|
-
PyCall::Dict.new(obj).__pyobj__
|
|
116
|
-
when Proc
|
|
117
|
-
PyCall.wrap_ruby_callable(obj)
|
|
118
|
-
else
|
|
119
|
-
PyCall.None
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def self.convert_to_boolean(py_obj)
|
|
124
|
-
0 != LibPython.PyInt_AsSsize_t(py_obj)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def self.convert_to_integer(py_obj)
|
|
128
|
-
LibPython.PyInt_AsSsize_t(py_obj)
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def self.convert_to_float(py_obj)
|
|
132
|
-
LibPython.PyFloat_AsDouble(py_obj)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def self.convert_to_complex(py_obj)
|
|
136
|
-
real = LibPython.PyComplex_RealAsDouble(py_obj)
|
|
137
|
-
imag = LibPython.PyComplex_ImagAsDouble(py_obj)
|
|
138
|
-
Complex(real, imag)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def self.convert_to_string(py_obj)
|
|
142
|
-
FFI::MemoryPointer.new(:string) do |str_ptr|
|
|
143
|
-
FFI::MemoryPointer.new(:int) do |len_ptr|
|
|
144
|
-
res = LibPython.PyString_AsStringAndSize(py_obj, str_ptr, len_ptr)
|
|
145
|
-
return nil if res == -1 # FIXME: error
|
|
146
|
-
|
|
147
|
-
len = len_ptr.get(:int, 0)
|
|
148
|
-
return str_ptr.get_pointer(0).read_string(len)
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def self.convert_to_array(py_obj, force_list: true, array_class: Array)
|
|
154
|
-
case
|
|
155
|
-
when force_list || py_obj.kind_of?(LibPython.PyList_Type)
|
|
156
|
-
len = LibPython.PySequence_Size(py_obj)
|
|
157
|
-
array_class.new(len) do |i|
|
|
158
|
-
LibPython.PySequence_GetItem(py_obj, i).to_ruby
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def self.convert_to_tuple(py_obj)
|
|
164
|
-
PyCall::Tuple.new(py_obj)
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
class LibPython::PyObjectStruct
|
|
169
|
-
def to_ruby
|
|
170
|
-
Conversions.to_ruby(self)
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
end
|
data/lib/pycall/tuple.rb
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
module PyCall
|
|
2
|
-
class Tuple
|
|
3
|
-
include PyObjectWrapper
|
|
4
|
-
|
|
5
|
-
def self.new(init)
|
|
6
|
-
case init
|
|
7
|
-
when Integer
|
|
8
|
-
super(LibPython.PyTuple_New(init))
|
|
9
|
-
when Array
|
|
10
|
-
tuple = new(init.length)
|
|
11
|
-
init.each_with_index do |obj, index|
|
|
12
|
-
tuple[index] = obj
|
|
13
|
-
end
|
|
14
|
-
tuple
|
|
15
|
-
when LibPython::PyObjectStruct
|
|
16
|
-
super(init)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Make tuple from array
|
|
21
|
-
def self.[](*ary)
|
|
22
|
-
new(ary)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def size
|
|
26
|
-
LibPython.PyTuple_Size(__pyobj__)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
alias length size
|
|
30
|
-
|
|
31
|
-
def [](index)
|
|
32
|
-
LibPython.PyTuple_GetItem(__pyobj__, index).to_ruby
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def []=(index, value)
|
|
36
|
-
value = Conversions.from_ruby(value)
|
|
37
|
-
LibPython.PyTuple_SetItem(__pyobj__, index, value)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def to_a
|
|
41
|
-
Array.new(length) {|i| self[i] }
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
alias to_ary to_a
|
|
45
|
-
end
|
|
46
|
-
end
|