pybind 0.1.0
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +25 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +132 -0
- data/Rakefile +5 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/examples/autocall_functions.rb +15 -0
- data/examples/hello_world.py +1 -0
- data/examples/hello_world.rb +14 -0
- data/examples/mnist.softmax.rb +53 -0
- data/examples/numpy.rb +9 -0
- data/lib/pybind.rb +14 -0
- data/lib/pybind/autocall.rb +14 -0
- data/lib/pybind/core_ext/basic.rb +66 -0
- data/lib/pybind/error.rb +38 -0
- data/lib/pybind/import.rb +51 -0
- data/lib/pybind/init.rb +23 -0
- data/lib/pybind/libpython.rb +371 -0
- data/lib/pybind/python/investigator.py +10 -0
- data/lib/pybind/struct.rb +36 -0
- data/lib/pybind/typecast.rb +28 -0
- data/lib/pybind/types.rb +21 -0
- data/lib/pybind/types/basic.rb +70 -0
- data/lib/pybind/types/dict.rb +94 -0
- data/lib/pybind/types/function.rb +26 -0
- data/lib/pybind/types/list.rb +39 -0
- data/lib/pybind/types/object.rb +9 -0
- data/lib/pybind/types/sequence.rb +26 -0
- data/lib/pybind/types/set.rb +19 -0
- data/lib/pybind/types/slice.rb +19 -0
- data/lib/pybind/types/tuple.rb +45 -0
- data/lib/pybind/utils.rb +81 -0
- data/lib/pybind/version.rb +3 -0
- data/lib/pybind/wrapper.rb +120 -0
- data/lib/pybind/wrapper/attr_accessor.rb +53 -0
- data/lib/pybind/wrapper/operator.rb +82 -0
- data/lib/pybind/wrapper/rich_comparer.rb +39 -0
- data/pybind.gemspec +40 -0
- metadata +157 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
class Object
|
2
|
+
def to_python_struct
|
3
|
+
raise TypeError, "can not convert #{inspect} to a PyObjectStruct"
|
4
|
+
end
|
5
|
+
alias_method :to_python, :to_python_struct
|
6
|
+
end
|
7
|
+
|
8
|
+
class NilClass
|
9
|
+
def to_python
|
10
|
+
PyBind::LibPython.Py_None
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class TrueClass
|
15
|
+
def to_python
|
16
|
+
PyBind::LibPython.Py_True
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class FalseClass
|
21
|
+
def to_python
|
22
|
+
PyBind::LibPython.Py_False
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Integer
|
27
|
+
def to_python
|
28
|
+
PyBind::LibPython.PyInt_FromSsize_t(self)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Float
|
33
|
+
def to_python
|
34
|
+
PyBind::LibPython.PyFloat_FromDouble(self)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class String
|
39
|
+
def to_python
|
40
|
+
case encoding
|
41
|
+
when Encoding::US_ASCII, Encoding::BINARY
|
42
|
+
PyBind::LibPython.PyString_FromStringAndSize(self, bytesize)
|
43
|
+
else
|
44
|
+
utf8_str = encode(Encoding::UTF_8)
|
45
|
+
PyBind::LibPython.PyUnicode_DecodeUTF8(utf8_str, utf8_str.bytesize, nil)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Symbol
|
51
|
+
def to_python
|
52
|
+
to_s.to_python
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Hash
|
57
|
+
def to_python
|
58
|
+
PyBind::PyDict.new(self).to_python_struct
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Array
|
63
|
+
def to_python
|
64
|
+
PyBind::PyList.new(self).to_python_struct
|
65
|
+
end
|
66
|
+
end
|
data/lib/pybind/error.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module PyBind
|
2
|
+
class PyError < StandardError
|
3
|
+
def self.fetch
|
4
|
+
ptrs = FFI::MemoryPointer.new(:pointer, 3)
|
5
|
+
ptype = ptrs + 0 * ptrs.type_size
|
6
|
+
pvalue = ptrs + 1 * ptrs.type_size
|
7
|
+
ptraceback = ptrs + 2 * ptrs.type_size
|
8
|
+
LibPython.PyErr_Fetch(ptype, pvalue, ptraceback)
|
9
|
+
LibPython.PyErr_NormalizeException(ptype, pvalue, ptraceback)
|
10
|
+
type = TypeCast.from_python(PyObjectStruct.new(ptype.read(:pointer)))
|
11
|
+
value = TypeCast.from_python(PyObjectStruct.new(pvalue.read(:pointer)))
|
12
|
+
traceback = TypeCast.from_python(PyObjectStruct.new(ptraceback.read(:pointer)))
|
13
|
+
new(type, value, traceback)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(type, value, traceback)
|
17
|
+
@type = type
|
18
|
+
@value = value
|
19
|
+
@traceback = traceback
|
20
|
+
super("#{type}: #{value}")
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :type, :value, :traceback
|
24
|
+
|
25
|
+
def message
|
26
|
+
baseline = super
|
27
|
+
lines = [baseline] + PyBind.parse_traceback(traceback)
|
28
|
+
lines.join("\n")
|
29
|
+
rescue
|
30
|
+
baseline
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.parse_traceback(traceback)
|
35
|
+
format_tb_func = PyBind.traceback.get_attribute('format_tb')
|
36
|
+
format_tb_func.call(traceback).to_a
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module PyBind
|
2
|
+
module Import
|
3
|
+
def pyimport(mod_name, as: mod_name)
|
4
|
+
if as.to_s.include?('.')
|
5
|
+
raise ArgumentError, "#{as.inspect} is not a valid module variable name, use pyimport #{mod_name.inspect}, as: <name>"
|
6
|
+
end
|
7
|
+
|
8
|
+
mod = PyBind.import(mod_name)
|
9
|
+
raise PyError.fetch unless mod
|
10
|
+
|
11
|
+
define_singleton_method(as) { mod }
|
12
|
+
end
|
13
|
+
|
14
|
+
def pyfrom(mod_name, import: nil)
|
15
|
+
raise ArgumentError, "missing identifiers to be imported" unless import
|
16
|
+
|
17
|
+
mod = PyBind.import(mod_name)
|
18
|
+
raise PyError.fetch unless mod
|
19
|
+
|
20
|
+
case import
|
21
|
+
when Hash
|
22
|
+
import.each do |attr, as|
|
23
|
+
val = mod.get_attribute(attr)
|
24
|
+
define_singleton_method(as) { val }
|
25
|
+
end
|
26
|
+
when Array
|
27
|
+
import.each do |attr|
|
28
|
+
val = mod.get_attribute(attr)
|
29
|
+
define_singleton_method(attr) { val }
|
30
|
+
end
|
31
|
+
when Symbol, String
|
32
|
+
val = mod.get_attribute(import)
|
33
|
+
define_singleton_method(import) { val }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.import(name)
|
39
|
+
name = name.to_s if name.is_a? Symbol
|
40
|
+
raise TypeError, 'name must be a String' unless name.is_a? String
|
41
|
+
value = LibPython.PyImport_ImportModule(name)
|
42
|
+
raise PyError.fetch if value.null?
|
43
|
+
value = value.to_ruby
|
44
|
+
return value unless block_given?
|
45
|
+
begin
|
46
|
+
yield value
|
47
|
+
ensure
|
48
|
+
PyBind.decref(value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/pybind/init.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module PyBind
|
2
|
+
private_class_method
|
3
|
+
|
4
|
+
class << self
|
5
|
+
attr_reader :builtin
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.__initialize_pybind__
|
9
|
+
initialized = (0 != LibPython.Py_IsInitialized())
|
10
|
+
return if initialized
|
11
|
+
|
12
|
+
LibPython.Py_InitializeEx(0)
|
13
|
+
|
14
|
+
FFI::MemoryPointer.new(:pointer, 1) do |argv|
|
15
|
+
argv.write_pointer(FFI::MemoryPointer.from_string(''))
|
16
|
+
LibPython.PySys_SetArgvEx(0, argv, 0)
|
17
|
+
end
|
18
|
+
|
19
|
+
@builtin = LibPython.PyImport_ImportModule(PYTHON_VERSION < '3.0.0' ? '__builtin__' : 'builtins').to_ruby
|
20
|
+
end
|
21
|
+
|
22
|
+
__initialize_pybind__
|
23
|
+
end
|
@@ -0,0 +1,371 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module PyBind
|
4
|
+
module LibPython
|
5
|
+
extend FFI::Library
|
6
|
+
|
7
|
+
def self.find_libpython(python = nil)
|
8
|
+
python ||= ENV['PYTHON'] || 'python'
|
9
|
+
python_config = investigate_python_config(python)
|
10
|
+
|
11
|
+
version = python_config[:VERSION]
|
12
|
+
libprefix = FFI::Platform::LIBPREFIX
|
13
|
+
libs = []
|
14
|
+
%i(INSTSONAME LDLIBRARY).each do |key|
|
15
|
+
lib = python_config[key]
|
16
|
+
libs << lib << File.basename(lib) if lib
|
17
|
+
end
|
18
|
+
if (lib = python_config[:LIBRARY])
|
19
|
+
libs << File.basename(lib, File.extname(lib))
|
20
|
+
end
|
21
|
+
libs << "#{libprefix}python#{version}" << "#{libprefix}python"
|
22
|
+
libs.uniq!
|
23
|
+
|
24
|
+
executable = python_config[:EXECUTABLE]
|
25
|
+
libpaths = [ python_config[:LIBDIR] ]
|
26
|
+
if FFI::Platform.windows?
|
27
|
+
libpaths << File.dirname(executable)
|
28
|
+
else
|
29
|
+
libpaths << File.expand_path('../../lib', executable)
|
30
|
+
end
|
31
|
+
libpaths << python_config[:PYTHONFRAMEWORKPREFIX] if FFI::Platform.mac?
|
32
|
+
exec_prefix = python_config[:EXECPREFIX]
|
33
|
+
libpaths << exec_prefix << File.join(exec_prefix, 'lib')
|
34
|
+
libpaths.compact!
|
35
|
+
|
36
|
+
unless ENV['PYTHONHOME']
|
37
|
+
# PYTHONHOME tells python where to look for both pure python and binary modules.
|
38
|
+
# When it is set, it replaces both `prefix` and `exec_prefix`
|
39
|
+
# and we thus need to set it to both in case they differ.
|
40
|
+
# This is also what the documentation recommends.
|
41
|
+
# However, they are documented to always be the same on Windows,
|
42
|
+
# where it causes problems if we try to include both.
|
43
|
+
if FFI::Platform.windows?
|
44
|
+
ENV['PYTHONHOME'] = exec_prefix
|
45
|
+
else
|
46
|
+
ENV['PYTHONHOME'] = [python_config[:PREFIX], exec_prefix].join(':')
|
47
|
+
end
|
48
|
+
|
49
|
+
# Unfortunately, setting PYTHONHOME screws up Canopy's Python distribution?
|
50
|
+
unless system(python, '-c', 'import site', out: File::NULL, err: File::NULL)
|
51
|
+
ENV['PYTHONHOME'] = nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Try LIBPYTHON environment variable first.
|
56
|
+
if ENV['LIBPYTHON']
|
57
|
+
if File.file?(ENV['LIBPYTHON'])
|
58
|
+
begin
|
59
|
+
libs = ffi_lib(ENV['LIBPYTHON'])
|
60
|
+
return libs.first
|
61
|
+
rescue LoadError
|
62
|
+
end
|
63
|
+
end
|
64
|
+
$stderr.puts '[WARN] Ignore the wrong libpython location specified in LIBPYTHON environment variable.'
|
65
|
+
end
|
66
|
+
|
67
|
+
# Find libpython (we hope):
|
68
|
+
libsuffix = FFI::Platform::LIBSUFFIX
|
69
|
+
multiarch = python_config[:MULTIARCH] || python_config[:IMPLEMENTATIONMULTIARCH]
|
70
|
+
dir_sep = File::ALT_SEPARATOR || File::SEPARATOR
|
71
|
+
libs.each do |lib|
|
72
|
+
libpaths.each do |libpath|
|
73
|
+
# NOTE: File.join doesn't use File::ALT_SEPARATOR
|
74
|
+
libpath_libs = [ [libpath, lib].join(dir_sep) ]
|
75
|
+
libpath_libs << [libpath, multiarch, lib].join(dir_sep) if multiarch
|
76
|
+
libpath_libs.each do |libpath_lib|
|
77
|
+
[
|
78
|
+
libpath_lib,
|
79
|
+
"#{libpath_lib}.#{libsuffix}"
|
80
|
+
].each do |fullname|
|
81
|
+
next unless File.file?(fullname)
|
82
|
+
begin
|
83
|
+
libs = ffi_lib(fullname)
|
84
|
+
return libs.first
|
85
|
+
rescue LoadError
|
86
|
+
# skip load error
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.investigate_python_config(python)
|
95
|
+
python_env = { 'PYTHONIOENCODING' => 'UTF-8' }
|
96
|
+
IO.popen(python_env, [python, python_investigator_py], 'r') do |io|
|
97
|
+
{}.tap do |config|
|
98
|
+
io.each_line do |line|
|
99
|
+
key, value = line.chomp.split(': ', 2)
|
100
|
+
config[key.to_sym] = value if value != 'None'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.python_investigator_py
|
107
|
+
File.expand_path('../python/investigator.py', __FILE__)
|
108
|
+
end
|
109
|
+
|
110
|
+
ffi_lib_flags :lazy, :global
|
111
|
+
libpython = find_libpython ENV['PYTHON']
|
112
|
+
|
113
|
+
# --- global variables ---
|
114
|
+
|
115
|
+
attach_variable :_Py_NoneStruct, PyObjectStruct
|
116
|
+
|
117
|
+
def self.Py_None
|
118
|
+
_Py_NoneStruct
|
119
|
+
end
|
120
|
+
|
121
|
+
attach_variable :PyType_Type, PyObjectStruct
|
122
|
+
|
123
|
+
if libpython.find_variable('PyInt_Type')
|
124
|
+
has_PyInt_Type = true
|
125
|
+
attach_variable :PyInt_Type, PyObjectStruct
|
126
|
+
else
|
127
|
+
has_PyInt_Type = false
|
128
|
+
attach_variable :PyInt_Type, :PyLong_Type, PyObjectStruct
|
129
|
+
end
|
130
|
+
|
131
|
+
attach_variable :PyLong_Type, PyObjectStruct
|
132
|
+
attach_variable :PyBool_Type, PyObjectStruct
|
133
|
+
attach_variable :PyFloat_Type, PyObjectStruct
|
134
|
+
attach_variable :PyComplex_Type, PyObjectStruct
|
135
|
+
attach_variable :PyUnicode_Type, PyObjectStruct
|
136
|
+
|
137
|
+
if libpython.find_symbol('PyString_FromStringAndSize')
|
138
|
+
string_as_bytes = false
|
139
|
+
attach_variable :PyString_Type, PyObjectStruct
|
140
|
+
else
|
141
|
+
string_as_bytes = true
|
142
|
+
attach_variable :PyString_Type, :PyBytes_Type, PyObjectStruct
|
143
|
+
end
|
144
|
+
|
145
|
+
attach_variable :PyTuple_Type, PyObjectStruct
|
146
|
+
attach_variable :PySlice_Type, PyObjectStruct
|
147
|
+
attach_variable :PyList_Type, PyObjectStruct
|
148
|
+
attach_variable :PyDict_Type, PyObjectStruct
|
149
|
+
attach_variable :PySet_Type, PyObjectStruct
|
150
|
+
|
151
|
+
attach_variable :PyFunction_Type, PyObjectStruct
|
152
|
+
attach_variable :PyMethod_Type, PyObjectStruct
|
153
|
+
|
154
|
+
# --- functions ---
|
155
|
+
|
156
|
+
attach_function :Py_GetVersion, [], :string
|
157
|
+
attach_function :Py_InitializeEx, [:int], :void
|
158
|
+
attach_function :Py_IsInitialized, [], :int
|
159
|
+
attach_function :PySys_SetArgvEx, [:int, :pointer, :int], :void
|
160
|
+
|
161
|
+
# Reference count
|
162
|
+
|
163
|
+
attach_function :Py_IncRef, [PyObjectStruct.by_ref], :void
|
164
|
+
attach_function :Py_DecRef, [PyObjectStruct.by_ref], :void
|
165
|
+
|
166
|
+
# Object
|
167
|
+
|
168
|
+
attach_function :PyObject_RichCompare, [PyObjectStruct.by_ref, PyObjectStruct.by_ref, :int], PyObjectStruct.by_ref
|
169
|
+
attach_function :PyObject_RichCompareBool, [PyObjectStruct.by_ref, PyObjectStruct.by_ref, :int], :int
|
170
|
+
attach_function :PyObject_GetAttrString, [PyObjectStruct.by_ref, :string], PyObjectStruct.by_ref
|
171
|
+
attach_function :PyObject_SetAttrString, [PyObjectStruct.by_ref, :string, PyObjectStruct.by_ref], :int
|
172
|
+
attach_function :PyObject_HasAttrString, [PyObjectStruct.by_ref, :string], :int
|
173
|
+
attach_function :PyObject_GetItem, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
174
|
+
attach_function :PyObject_SetItem, [PyObjectStruct.by_ref, PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
175
|
+
attach_function :PyObject_DelItem, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
176
|
+
attach_function :PyObject_Call, [PyObjectStruct.by_ref, PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
177
|
+
attach_function :PyObject_IsInstance, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
178
|
+
attach_function :PyObject_IsSubclass, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
179
|
+
attach_function :PyObject_Dir, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
180
|
+
attach_function :PyObject_Repr, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
181
|
+
attach_function :PyObject_Str, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
182
|
+
attach_function :PyObject_Type, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
183
|
+
attach_function :PyCallable_Check, [PyObjectStruct.by_ref], :int
|
184
|
+
|
185
|
+
# PyObject_DelAttrString only avaliable in Python 3.x
|
186
|
+
if libpython.find_symbol('PyObject_DelAttrString')
|
187
|
+
attach_function :PyObject_DelAttrString, [PyObjectStruct.by_ref, :string], :int
|
188
|
+
end
|
189
|
+
|
190
|
+
# PyObject_Compare only avaliable in Python 2.x
|
191
|
+
if libpython.find_symbol('PyObject_Compare')
|
192
|
+
attach_function :PyObject_Compare, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
193
|
+
end
|
194
|
+
|
195
|
+
# Bool
|
196
|
+
|
197
|
+
attach_function :PyBool_FromLong, [:long], PyObjectStruct.by_ref
|
198
|
+
attach_variable :_Py_TrueStruct, PyObjectStruct
|
199
|
+
|
200
|
+
def self.Py_True
|
201
|
+
_Py_TrueStruct
|
202
|
+
end
|
203
|
+
|
204
|
+
# _Py_ZeroStruct only avaliable in Python 2.x, use _Py_FalseStruct in Python 3.x
|
205
|
+
if libpython.find_symbol('PyObject_Compare')
|
206
|
+
attach_variable :_Py_ZeroStruct, PyObjectStruct
|
207
|
+
|
208
|
+
def self.Py_False
|
209
|
+
_Py_ZeroStruct
|
210
|
+
end
|
211
|
+
else
|
212
|
+
attach_variable :_Py_FalseStruct, PyObjectStruct
|
213
|
+
|
214
|
+
def self.Py_False
|
215
|
+
_Py_FalseStruct
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# Integer
|
220
|
+
|
221
|
+
if has_PyInt_Type
|
222
|
+
attach_function :PyInt_AsSsize_t, [PyObjectStruct.by_ref], :ssize_t
|
223
|
+
else
|
224
|
+
attach_function :PyInt_AsSsize_t, :PyLong_AsSsize_t, [PyObjectStruct.by_ref], :ssize_t
|
225
|
+
end
|
226
|
+
|
227
|
+
if has_PyInt_Type
|
228
|
+
attach_function :PyInt_FromSsize_t, [:ssize_t], PyObjectStruct.by_ref
|
229
|
+
else
|
230
|
+
attach_function :PyInt_FromSsize_t, :PyLong_FromSsize_t, [:ssize_t], PyObjectStruct.by_ref
|
231
|
+
end
|
232
|
+
|
233
|
+
# Float
|
234
|
+
|
235
|
+
attach_function :PyFloat_FromDouble, [:double], PyObjectStruct.by_ref
|
236
|
+
attach_function :PyFloat_AsDouble, [PyObjectStruct.by_ref], :double
|
237
|
+
|
238
|
+
# Complex
|
239
|
+
|
240
|
+
attach_function :PyComplex_RealAsDouble, [PyObjectStruct.by_ref], :double
|
241
|
+
attach_function :PyComplex_ImagAsDouble, [PyObjectStruct.by_ref], :double
|
242
|
+
|
243
|
+
# String
|
244
|
+
|
245
|
+
if string_as_bytes
|
246
|
+
attach_function :PyString_FromStringAndSize, :PyBytes_FromStringAndSize, [:string, :ssize_t], PyObjectStruct.by_ref
|
247
|
+
else
|
248
|
+
attach_function :PyString_FromStringAndSize, [:string, :ssize_t], PyObjectStruct.by_ref
|
249
|
+
end
|
250
|
+
|
251
|
+
# PyString_AsStringAndSize :: (PyPtr, char**, int*) -> int
|
252
|
+
if string_as_bytes
|
253
|
+
attach_function :PyString_AsStringAndSize, :PyBytes_AsStringAndSize, [PyObjectStruct.by_ref, :pointer, :pointer], :int
|
254
|
+
else
|
255
|
+
attach_function :PyString_AsStringAndSize, [PyObjectStruct.by_ref, :pointer, :pointer], :int
|
256
|
+
end
|
257
|
+
|
258
|
+
# Unicode
|
259
|
+
|
260
|
+
# PyUnicode_DecodeUTF8
|
261
|
+
case
|
262
|
+
when libpython.find_symbol('PyUnicode_DecodeUTF8')
|
263
|
+
attach_function :PyUnicode_DecodeUTF8, [:string, :ssize_t, :string], PyObjectStruct.by_ref
|
264
|
+
when libpython.find_symbol('PyUnicodeUCS4_DecodeUTF8')
|
265
|
+
attach_function :PyUnicode_DecodeUTF8, :PyUnicodeUCS4_DecodeUTF8, [:string, :ssize_t, :string], PyObjectStruct.by_ref
|
266
|
+
when libpython.find_symbol('PyUnicodeUCS2_DecodeUTF8')
|
267
|
+
attach_function :PyUnicode_DecodeUTF8, :PyUnicodeUCS2_DecodeUTF8, [:string, :ssize_t, :string], PyObjectStruct.by_ref
|
268
|
+
end
|
269
|
+
|
270
|
+
# PyUnicode_AsUTF8String
|
271
|
+
case
|
272
|
+
when libpython.find_symbol('PyUnicode_AsUTF8String')
|
273
|
+
attach_function :PyUnicode_AsUTF8String, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
274
|
+
when libpython.find_symbol('PyUnicodeUCS4_AsUTF8String')
|
275
|
+
attach_function :PyUnicode_AsUTF8String, :PyUnicodeUCS4_AsUTF8String, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
276
|
+
when libpython.find_symbol('PyUnicodeUCS2_AsUTF8String')
|
277
|
+
attach_function :PyUnicode_AsUTF8String, :PyUnicodeUCS2_AsUTF8String, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
278
|
+
end
|
279
|
+
|
280
|
+
# Tuple
|
281
|
+
|
282
|
+
attach_function :PyTuple_New, [:ssize_t], PyObjectStruct.by_ref
|
283
|
+
attach_function :PyTuple_GetItem, [PyObjectStruct.by_ref, :ssize_t], PyObjectStruct.by_ref
|
284
|
+
attach_function :PyTuple_SetItem, [PyObjectStruct.by_ref, :ssize_t, PyObjectStruct.by_ref], :int
|
285
|
+
attach_function :PyTuple_Size, [PyObjectStruct.by_ref], :ssize_t
|
286
|
+
|
287
|
+
# Slice
|
288
|
+
|
289
|
+
attach_function :PySlice_New, [PyObjectStruct.by_ref, PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
290
|
+
|
291
|
+
# List
|
292
|
+
|
293
|
+
attach_function :PyList_New, [:ssize_t], PyObjectStruct.by_ref
|
294
|
+
attach_function :PyList_Size, [PyObjectStruct.by_ref], :ssize_t
|
295
|
+
attach_function :PyList_GetItem, [PyObjectStruct.by_ref, :ssize_t], PyObjectStruct.by_ref
|
296
|
+
attach_function :PyList_SetItem, [PyObjectStruct.by_ref, :ssize_t, PyObjectStruct.by_ref], :int
|
297
|
+
attach_function :PyList_Append, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
298
|
+
|
299
|
+
# Sequence
|
300
|
+
|
301
|
+
attach_function :PySequence_Size, [PyObjectStruct.by_ref], :ssize_t
|
302
|
+
attach_function :PySequence_GetItem, [PyObjectStruct.by_ref, :ssize_t], PyObjectStruct.by_ref
|
303
|
+
attach_function :PySequence_Contains, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
304
|
+
|
305
|
+
# Dict
|
306
|
+
|
307
|
+
attach_function :PyDict_New, [], PyObjectStruct.by_ref
|
308
|
+
attach_function :PyDict_GetItem, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
309
|
+
attach_function :PyDict_GetItemString, [PyObjectStruct.by_ref, :string], PyObjectStruct.by_ref
|
310
|
+
attach_function :PyDict_SetItem, [PyObjectStruct.by_ref, PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
311
|
+
attach_function :PyDict_SetItemString, [PyObjectStruct.by_ref, :string, PyObjectStruct.by_ref], :int
|
312
|
+
attach_function :PyDict_DelItem, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
313
|
+
attach_function :PyDict_DelItem, [PyObjectStruct.by_ref, :string], :int
|
314
|
+
attach_function :PyDict_Size, [PyObjectStruct.by_ref], :ssize_t
|
315
|
+
attach_function :PyDict_Keys, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
316
|
+
attach_function :PyDict_Values, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
317
|
+
attach_function :PyDict_Items, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
318
|
+
attach_function :PyDict_Contains, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
319
|
+
|
320
|
+
# Set
|
321
|
+
|
322
|
+
attach_function :PySet_Size, [PyObjectStruct.by_ref], :ssize_t
|
323
|
+
attach_function :PySet_Contains, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
324
|
+
attach_function :PySet_Add, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
325
|
+
attach_function :PySet_Discard, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], :int
|
326
|
+
|
327
|
+
# Module
|
328
|
+
|
329
|
+
attach_function :PyModule_GetDict, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
330
|
+
|
331
|
+
# Import
|
332
|
+
|
333
|
+
attach_function :PyImport_ImportModule, [:string], PyObjectStruct.by_ref
|
334
|
+
|
335
|
+
# Operators
|
336
|
+
|
337
|
+
attach_function :PyNumber_Add, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
338
|
+
attach_function :PyNumber_Subtract, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
339
|
+
attach_function :PyNumber_Multiply, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
340
|
+
attach_function :PyNumber_TrueDivide, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
341
|
+
attach_function :PyNumber_Remainder, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
342
|
+
attach_function :PyNumber_Power, [PyObjectStruct.by_ref, PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
343
|
+
attach_function :PyNumber_Lshift, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
344
|
+
attach_function :PyNumber_Rshift, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
345
|
+
attach_function :PyNumber_And, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
346
|
+
attach_function :PyNumber_Xor, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
347
|
+
attach_function :PyNumber_Or, [PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
348
|
+
attach_function :PyNumber_Positive, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
349
|
+
attach_function :PyNumber_Negative, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
350
|
+
attach_function :PyNumber_Invert, [PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
351
|
+
attach_function :PyObject_Not, [PyObjectStruct.by_ref], :int
|
352
|
+
|
353
|
+
# Compiler
|
354
|
+
|
355
|
+
attach_function :Py_CompileString, [:string, :string, :int], PyObjectStruct.by_ref
|
356
|
+
attach_function :PyEval_EvalCode, [PyObjectStruct.by_ref, PyObjectStruct.by_ref, PyObjectStruct.by_ref], PyObjectStruct.by_ref
|
357
|
+
|
358
|
+
# Error
|
359
|
+
|
360
|
+
attach_function :PyErr_Clear, [], :void
|
361
|
+
attach_function :PyErr_Print, [], :void
|
362
|
+
attach_function :PyErr_Occurred, [], PyObjectStruct.by_ref
|
363
|
+
attach_function :PyErr_Fetch, [:pointer, :pointer, :pointer], :void
|
364
|
+
attach_function :PyErr_NormalizeException, [:pointer, :pointer, :pointer], :void
|
365
|
+
|
366
|
+
public_class_method
|
367
|
+
end
|
368
|
+
|
369
|
+
PYTHON_DESCRIPTION = LibPython.Py_GetVersion().freeze
|
370
|
+
PYTHON_VERSION = PYTHON_DESCRIPTION.split(' ', 2)[0].freeze
|
371
|
+
end
|