pycall 0.1.0.alpha → 0.1.0.alpha.20170224
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +15 -1
- data/Gemfile +5 -0
- data/Guardfile +1 -0
- data/README.md +4 -2
- data/bin/guard +17 -0
- data/bin/rspec +17 -0
- data/config/Guardfile +30 -0
- data/examples/classifier_comparison.rb +130 -0
- data/examples/hist.rb +27 -0
- data/examples/plot_forest_importances_faces.rb +41 -0
- data/examples/sum_benchmarking.rb +48 -0
- data/lib/pycall.rb +14 -4
- data/lib/pycall/conversion.rb +120 -0
- data/lib/pycall/dict.rb +90 -0
- data/lib/pycall/eval.rb +39 -0
- data/lib/pycall/import.rb +74 -0
- data/lib/pycall/init.rb +16 -0
- data/lib/pycall/libpython.rb +331 -0
- data/lib/pycall/list.rb +65 -0
- data/lib/pycall/pyerror.rb +25 -0
- data/lib/pycall/pyobject.rb +185 -0
- data/lib/pycall/pyobject_wrapper.rb +48 -0
- data/lib/pycall/python/investigator.py +6 -0
- data/lib/pycall/set.rb +17 -0
- data/lib/pycall/slice.rb +27 -0
- data/lib/pycall/tuple.rb +54 -0
- data/lib/pycall/types.rb +15 -0
- data/lib/pycall/utils.rb +33 -0
- data/lib/pycall/version.rb +2 -2
- data/pycall.gemspec +3 -1
- metadata +41 -3
data/lib/pycall/dict.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
module PyCall
|
2
|
+
class Dict
|
3
|
+
include PyObjectWrapper
|
4
|
+
|
5
|
+
def self.new(init=nil)
|
6
|
+
case init
|
7
|
+
when PyObject
|
8
|
+
super
|
9
|
+
when nil
|
10
|
+
new(LibPython.PyDict_New())
|
11
|
+
when Hash
|
12
|
+
new.tap do |dict|
|
13
|
+
init.each do |key, value|
|
14
|
+
dict[key] = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
else
|
18
|
+
raise TypeError, "the argument must be a PyObject or a Hash"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(pyobj)
|
23
|
+
super(pyobj, LibPython.PyDict_Type)
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](key)
|
27
|
+
key = key.to_s if key.is_a? Symbol
|
28
|
+
if key.is_a? String
|
29
|
+
LibPython.PyDict_GetItemString(__pyobj__, key).to_ruby
|
30
|
+
else
|
31
|
+
LibPython.PyDict_GetItem(__pyobj__, key).to_ruby
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def []=(key, value)
|
36
|
+
key = key.to_s if key.is_a? Symbol
|
37
|
+
value = Conversions.from_ruby(value)
|
38
|
+
if key.is_a? String
|
39
|
+
LibPython.PyDict_SetItemString(__pyobj__, key, value)
|
40
|
+
else
|
41
|
+
LibPython.PyDict_SetItem(__pyobj__, key, value)
|
42
|
+
end
|
43
|
+
value
|
44
|
+
end
|
45
|
+
|
46
|
+
def delete(key)
|
47
|
+
key = key.to_s if key.is_a? Symbol
|
48
|
+
if key.is_a? String
|
49
|
+
value = LibPython.PyDict_GetItemString(__pyobj__, key).to_ruby
|
50
|
+
LibPython.PyDict_DelItemString(__pyobj__, key)
|
51
|
+
else
|
52
|
+
value = LibPython.PyDict_GetItem(__pyobj__, key).to_ruby
|
53
|
+
LibPython.PyDict_DelItem(__pyobj__, key)
|
54
|
+
end
|
55
|
+
value
|
56
|
+
end
|
57
|
+
|
58
|
+
def size
|
59
|
+
LibPython.PyDict_Size(__pyobj__)
|
60
|
+
end
|
61
|
+
|
62
|
+
def keys
|
63
|
+
LibPython.PyDict_Keys(__pyobj__).to_ruby
|
64
|
+
end
|
65
|
+
|
66
|
+
def values
|
67
|
+
LibPython.PyDict_Values(__pyobj__).to_ruby
|
68
|
+
end
|
69
|
+
|
70
|
+
def has_key?(key)
|
71
|
+
1 == LibPython.PyDict_Contains(__pyobj__, key).to_ruby
|
72
|
+
end
|
73
|
+
|
74
|
+
def default=(val)
|
75
|
+
# TODO: PYDict_SetDefault
|
76
|
+
end
|
77
|
+
|
78
|
+
def dup
|
79
|
+
# TODO: PyDict_Copy
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_a
|
83
|
+
LibPython.PyDict_Items(__pyobj__).to_ruby
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_hash
|
87
|
+
# TODO: PyDict_Next
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/pycall/eval.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module PyCall
|
2
|
+
module Eval
|
3
|
+
Py_eval_input = 258
|
4
|
+
|
5
|
+
def self.eval(str, filename: "pycall")
|
6
|
+
globals_ptr = maindict_ptr
|
7
|
+
locals_ptr = maindict_ptr
|
8
|
+
defer_sigint do
|
9
|
+
py_code_ptr = LibPython.Py_CompileString(str, filename, Py_eval_input)
|
10
|
+
LibPython.PyEval_EvalCode(py_code_ptr, globals_ptr, locals_ptr)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
private
|
16
|
+
|
17
|
+
def maindict_ptr
|
18
|
+
LibPython.PyModule_GetDict(PyCall.import_module("__main__"))
|
19
|
+
end
|
20
|
+
|
21
|
+
def defer_sigint
|
22
|
+
# TODO: should be implemented
|
23
|
+
yield
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.import_module(name)
|
29
|
+
name = name.to_s if name.kind_of? Symbol
|
30
|
+
raise TypeError, "name must be a String" unless name.kind_of? String
|
31
|
+
value = LibPython.PyImport_ImportModule(name)
|
32
|
+
return value.to_ruby unless value.null?
|
33
|
+
raise PyError.fetch
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.eval(str)
|
37
|
+
Eval.eval(str).to_ruby
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'pycall'
|
2
|
+
|
3
|
+
module PyCall
|
4
|
+
module Import
|
5
|
+
def self.main_object
|
6
|
+
@main_object
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
main_object = self
|
12
|
+
PyCall::Import.class_eval { @main_object = main_object }
|
13
|
+
|
14
|
+
module PyCall
|
15
|
+
module Import
|
16
|
+
def pyimport(mod_name, as: nil)
|
17
|
+
case as
|
18
|
+
when nil
|
19
|
+
as = mod_name
|
20
|
+
end
|
21
|
+
|
22
|
+
check_valid_module_variable_name(mod_name, as)
|
23
|
+
|
24
|
+
mod = PyCall.import_module(mod_name)
|
25
|
+
define_singleton_method(as) { mod }
|
26
|
+
end
|
27
|
+
|
28
|
+
def pyfrom(mod_name, import: nil)
|
29
|
+
raise ArgumentError, "missing identifiers to be imported" unless import
|
30
|
+
|
31
|
+
mod = PyCall.import_module(mod_name)
|
32
|
+
raise "Unable to import module #{mod_name}" unless mod # TODO: PyError
|
33
|
+
|
34
|
+
case import
|
35
|
+
when Hash
|
36
|
+
import.each do |attr, as|
|
37
|
+
val = PyCall.getattr(mod, attr)
|
38
|
+
define_name(as, val)
|
39
|
+
end
|
40
|
+
when Array
|
41
|
+
import.each do |attr|
|
42
|
+
val = PyCall.getattr(mod, attr)
|
43
|
+
define_name(attr, val)
|
44
|
+
end
|
45
|
+
when Symbol, String
|
46
|
+
val = PyCall.getattr(mod, import)
|
47
|
+
define_name(import, val)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def define_name(name, pyobj)
|
54
|
+
if constant_name?(name)
|
55
|
+
context = self
|
56
|
+
context = (self == PyCall::Import.main_object) ? Object : self
|
57
|
+
context.module_eval { const_set(name, pyobj) }
|
58
|
+
else
|
59
|
+
define_singleton_method(name) { pyobj }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def constant_name?(name)
|
64
|
+
name =~ /\A[A-Z]/
|
65
|
+
end
|
66
|
+
|
67
|
+
def check_valid_module_variable_name(mod_name, var_name)
|
68
|
+
var_name = var_name.to_s if var_name.kind_of? Symbol
|
69
|
+
if var_name.include?('.')
|
70
|
+
raise ArgumentError, "#{var_name} is not a valid module variable name, use pyimport #{mod_name}, as: <name>"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/pycall/init.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module PyCall
|
2
|
+
private_class_method def self.__initialize_pycall__
|
3
|
+
initialized = (0 != PyCall::LibPython.Py_IsInitialized())
|
4
|
+
return if initialized
|
5
|
+
|
6
|
+
PyCall::LibPython.Py_InitializeEx(0)
|
7
|
+
|
8
|
+
@builtin = LibPython.PyImport_ImportModule(PYTHON_VERSION < '3.0.0' ? '__builtin__' : 'builtins')
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_reader :builtin
|
13
|
+
end
|
14
|
+
|
15
|
+
__initialize_pycall__
|
16
|
+
end
|
@@ -0,0 +1,331 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module PyCall
|
4
|
+
class PyObject < FFI::Struct
|
5
|
+
layout ob_refcnt: :ssize_t,
|
6
|
+
ob_type: :pointer
|
7
|
+
end
|
8
|
+
|
9
|
+
class PyTypeObject < FFI::Struct
|
10
|
+
layout ob_base: PyObject,
|
11
|
+
ob_size: :ssize_t,
|
12
|
+
tp_name: :string
|
13
|
+
end
|
14
|
+
|
15
|
+
module LibPython
|
16
|
+
extend FFI::Library
|
17
|
+
|
18
|
+
private_class_method
|
19
|
+
|
20
|
+
def self.find_libpython(python = nil)
|
21
|
+
python ||= 'python'
|
22
|
+
python_config = investigate_python_config(python)
|
23
|
+
|
24
|
+
v = python_config[:VERSION]
|
25
|
+
libprefix = FFI::Platform::LIBPREFIX
|
26
|
+
libs = [ "#{libprefix}python#{v}", "#{libprefix}python" ]
|
27
|
+
lib = python_config[:LIBRARY]
|
28
|
+
libs.unshift(File.basename(lib, File.extname(lib))) if lib
|
29
|
+
lib = python_config[:LDLIBRARY]
|
30
|
+
libs.unshift(lib, File.basename(lib)) if lib
|
31
|
+
libs.uniq!
|
32
|
+
|
33
|
+
executable = python_config[:executable]
|
34
|
+
libpaths = [ python_config[:LIBDIR] ]
|
35
|
+
if FFI::Platform.windows?
|
36
|
+
libpaths << dirname(executable)
|
37
|
+
else
|
38
|
+
libpaths << File.expand_path('../../lib', executable)
|
39
|
+
end
|
40
|
+
libpaths << python_config[:PYTHONFRAMEWORKPREFIX] if FFI::Platform.mac?
|
41
|
+
|
42
|
+
exec_prefix = python_config[:exec_prefix]
|
43
|
+
libpaths << exec_prefix << File.join(exec_prefix, 'lib')
|
44
|
+
|
45
|
+
unless ENV['PYTHONHOME']
|
46
|
+
# PYTHONHOME tells python where to look for both pure python and binary modules.
|
47
|
+
# When it is set, it replaces both `prefix` and `exec_prefix`
|
48
|
+
# and we thus need to set it to both in case they differ.
|
49
|
+
# This is also what the documentation recommends.
|
50
|
+
# However, they are documented to always be the same on Windows,
|
51
|
+
# where it causes problems if we try to include both.
|
52
|
+
if FFI::Platform.windows?
|
53
|
+
ENV['PYTHONHOME'] = exec_prefix
|
54
|
+
else
|
55
|
+
ENV['PYTHONHOME'] = [python_config[:prefix], exec_prefix].join(':')
|
56
|
+
end
|
57
|
+
|
58
|
+
# Unfortunately, setting PYTHONHOME screws up Canopy's Python distribution?
|
59
|
+
unless system(python, '-c', 'import site', out: File::NULL, err: File::NULL)
|
60
|
+
ENV['PYTHONHOME'] = nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Find libpython (we hope):
|
65
|
+
libsuffix = FFI::Platform::LIBSUFFIX
|
66
|
+
libs.each do |lib|
|
67
|
+
libpaths.each do |libpath|
|
68
|
+
libpath_lib = File.join(libpath, lib)
|
69
|
+
if File.file?("#{libpath_lib}.#{libsuffix}")
|
70
|
+
libs = ffi_lib("#{libpath_lib}.#{libsuffix}")
|
71
|
+
return libs.first
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.investigate_python_config(python)
|
78
|
+
python_env = { 'PYTHONIOENCODING' => 'UTF-8' }
|
79
|
+
IO.popen(python_env, [python, python_investigator_py], 'r') do |io|
|
80
|
+
{}.tap do |config|
|
81
|
+
io.each_line do |line|
|
82
|
+
key, value = line.chomp.split(': ', 2)
|
83
|
+
config[key.to_sym] = value
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.python_investigator_py
|
90
|
+
File.expand_path('../python/investigator.py', __FILE__)
|
91
|
+
end
|
92
|
+
|
93
|
+
ffi_lib_flags :lazy, :global
|
94
|
+
libpython = find_libpython ENV['PYTHON']
|
95
|
+
|
96
|
+
# --- global variables ---
|
97
|
+
|
98
|
+
attach_variable :_Py_NoneStruct, PyObject
|
99
|
+
|
100
|
+
def self.Py_None
|
101
|
+
_Py_NoneStruct
|
102
|
+
end
|
103
|
+
|
104
|
+
if libpython.find_variable('PyInt_Type')
|
105
|
+
has_PyInt_Type = true
|
106
|
+
attach_variable :PyInt_Type, PyTypeObject
|
107
|
+
else
|
108
|
+
has_PyInt_Type = false
|
109
|
+
attach_variable :PyInt_Type, :PyLong_Type, PyTypeObject
|
110
|
+
end
|
111
|
+
|
112
|
+
attach_variable :PyLong_Type, PyTypeObject
|
113
|
+
attach_variable :PyBool_Type, PyTypeObject
|
114
|
+
attach_variable :PyFloat_Type, PyTypeObject
|
115
|
+
attach_variable :PyComplex_Type, PyTypeObject
|
116
|
+
attach_variable :PyUnicode_Type, PyTypeObject
|
117
|
+
|
118
|
+
if libpython.find_symbol('PyString_FromStringAndSize')
|
119
|
+
string_as_bytes = false
|
120
|
+
attach_variable :PyString_Type, PyTypeObject
|
121
|
+
else
|
122
|
+
string_as_bytes = true
|
123
|
+
attach_variable :PyString_Type, :PyBytes_Type, PyTypeObject
|
124
|
+
end
|
125
|
+
|
126
|
+
attach_variable :PyList_Type, PyTypeObject
|
127
|
+
attach_variable :PyTuple_Type, PyTypeObject
|
128
|
+
attach_variable :PyDict_Type, PyTypeObject
|
129
|
+
attach_variable :PySet_Type, PyTypeObject
|
130
|
+
|
131
|
+
# --- functions ---
|
132
|
+
|
133
|
+
attach_function :Py_GetVersion, [], :string
|
134
|
+
|
135
|
+
# Py_InitializeEx :: (int) -> void
|
136
|
+
attach_function :Py_InitializeEx, [:int], :void
|
137
|
+
|
138
|
+
# Py_IsInitialized :: () -> int
|
139
|
+
attach_function :Py_IsInitialized, [], :int
|
140
|
+
|
141
|
+
# Comparing two objects
|
142
|
+
attach_function :PyObject_RichCompare, [PyObject.by_ref, PyObject.by_ref, :int], PyObject.by_ref
|
143
|
+
|
144
|
+
# Accessing Object's attributes
|
145
|
+
attach_function :PyObject_GetAttrString, [PyObject.by_ref, :string], PyObject.by_ref
|
146
|
+
attach_function :PyObject_SetAttrString, [PyObject.by_ref, :string, PyObject.by_ref], :int
|
147
|
+
attach_function :PyObject_HasAttrString, [PyObject.by_ref, :string], :int
|
148
|
+
|
149
|
+
# Accessing Object's items
|
150
|
+
attach_function :PyObject_GetItem, [PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
151
|
+
attach_function :PyObject_SetItem, [PyObject.by_ref, PyObject.by_ref, PyObject.by_ref], :int
|
152
|
+
attach_function :PyObject_DelItem, [PyObject.by_ref, PyObject.by_ref], :int
|
153
|
+
|
154
|
+
# Calling a object as a function
|
155
|
+
attach_function :PyObject_Call, [PyObject.by_ref, PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
156
|
+
|
157
|
+
# PyObject_IsInstane :: (PyPtr, PyPtr) -> int
|
158
|
+
attach_function :PyObject_IsInstance, [PyObject.by_ref, PyTypeObject.by_ref], :int
|
159
|
+
|
160
|
+
# PyBool_FromLong :: (long) -> PyPtr
|
161
|
+
attach_function :PyBool_FromLong, [:long], PyObject.by_ref
|
162
|
+
|
163
|
+
# PyInt_AsSsize_t :: (PyPtr) -> ssize_t
|
164
|
+
if has_PyInt_Type
|
165
|
+
attach_function :PyInt_AsSsize_t, [PyObject.by_ref], :ssize_t
|
166
|
+
else
|
167
|
+
attach_function :PyInt_AsSsize_t, :PyLong_AsSsize_t, [PyObject.by_ref], :ssize_t
|
168
|
+
end
|
169
|
+
|
170
|
+
# PyInt_FromSsize_t :: (ssize_t) -> PyPtr
|
171
|
+
if has_PyInt_Type
|
172
|
+
attach_function :PyInt_FromSsize_t, [:ssize_t], PyObject.by_ref
|
173
|
+
else
|
174
|
+
attach_function :PyInt_FromSsize_t, :PyLong_FromSsize_t, [:ssize_t], PyObject.by_ref
|
175
|
+
end
|
176
|
+
|
177
|
+
# PyFloat_FromDouble :: (double) -> PyPtr
|
178
|
+
attach_function :PyFloat_FromDouble, [:double], PyObject.by_ref
|
179
|
+
|
180
|
+
# PyFloat_AsDouble :: (PyPtr) -> double
|
181
|
+
attach_function :PyFloat_AsDouble, [PyObject.by_ref], :double
|
182
|
+
|
183
|
+
# PyComplex_RealAsDouble :: (PyPtr) -> double
|
184
|
+
attach_function :PyComplex_RealAsDouble, [PyObject.by_ref], :double
|
185
|
+
|
186
|
+
# PyComplex_ImagAsDouble :: (PyPtr) -> double
|
187
|
+
attach_function :PyComplex_ImagAsDouble, [PyObject.by_ref], :double
|
188
|
+
|
189
|
+
# String
|
190
|
+
|
191
|
+
if string_as_bytes
|
192
|
+
attach_function :PyString_FromStringAndSize, :PyBytes_FromStringAndSize, [:string, :ssize_t], PyObject.by_ref
|
193
|
+
else
|
194
|
+
attach_function :PyString_FromStringAndSize, [:string, :ssize_t], PyObject.by_ref
|
195
|
+
end
|
196
|
+
|
197
|
+
# PyString_AsStringAndSize :: (PyPtr, char**, int*) -> int
|
198
|
+
if string_as_bytes
|
199
|
+
attach_function :PyString_AsStringAndSize, :PyBytes_AsStringAndSize, [PyObject.by_ref, :pointer, :pointer], :int
|
200
|
+
else
|
201
|
+
attach_function :PyString_AsStringAndSize, [PyObject.by_ref, :pointer, :pointer], :int
|
202
|
+
end
|
203
|
+
|
204
|
+
# Unicode
|
205
|
+
|
206
|
+
# PyUnicode_DecodeUTF8
|
207
|
+
case
|
208
|
+
when libpython.find_symbol('PyUnicode_DecodeUTF8')
|
209
|
+
attach_function :PyUnicode_DecodeUTF8, [:string, :ssize_t, :string], PyObject.by_ref
|
210
|
+
when libpython.find_symbol('PyUnicodeUCS4_DecodeUTF8')
|
211
|
+
attach_function :PyUnicodeUCS4_DecodeUTF8, [:string, :ssize_t, :string], PyObject.by_ref
|
212
|
+
when libpython.find_symbol('PyUnicodeUCS2_DecodeUTF8')
|
213
|
+
attach_function :PyUnicodeUCS2_DecodeUTF8, [:string, :ssize_t, :string], PyObject.by_ref
|
214
|
+
end
|
215
|
+
|
216
|
+
# PyUnicode_AsUTF8String :: (PyPtr) -> PyPtr
|
217
|
+
case
|
218
|
+
when libpython.find_symbol('PyUnicode_AsUTF8String')
|
219
|
+
attach_function :PyUnicode_AsUTF8String, [PyObject.by_ref], PyObject.by_ref
|
220
|
+
when libpython.find_symbol('PyUnicodeUCS4_AsUTF8String')
|
221
|
+
attach_function :PyUnicode_AsUTF8String, :PyUnicodeUCS4_AsUTF8String, [PyObject.by_ref], PyObject.by_ref
|
222
|
+
when libpython.find_symbol('PyUnicodeUCS2_AsUTF8String')
|
223
|
+
attach_function :PyUnicode_AsUTF8String, :PyUnicodeUCS2_AsUTF8String, [PyObject.by_ref], PyObject.by_ref
|
224
|
+
end
|
225
|
+
|
226
|
+
# Tuple
|
227
|
+
|
228
|
+
attach_function :PyTuple_New, [:ssize_t], PyObject.by_ref
|
229
|
+
attach_function :PyTuple_GetItem, [PyObject.by_ref, :ssize_t], PyObject.by_ref
|
230
|
+
attach_function :PyTuple_SetItem, [PyObject.by_ref, :ssize_t, PyObject.by_ref], :int
|
231
|
+
attach_function :PyTuple_Size, [PyObject.by_ref], :ssize_t
|
232
|
+
|
233
|
+
# Slice
|
234
|
+
|
235
|
+
attach_function :PySlice_New, [PyObject.by_ref, PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
236
|
+
|
237
|
+
# List
|
238
|
+
|
239
|
+
attach_function :PyList_New, [:ssize_t], PyObject.by_ref
|
240
|
+
attach_function :PyList_Size, [PyObject.by_ref], :ssize_t
|
241
|
+
attach_function :PyList_GetItem, [PyObject.by_ref, :ssize_t], PyObject.by_ref
|
242
|
+
attach_function :PyList_SetItem, [PyObject.by_ref, :ssize_t, PyObject.by_ref], :int
|
243
|
+
attach_function :PyList_Append, [PyObject.by_ref, PyObject.by_ref], :int
|
244
|
+
|
245
|
+
# PySequence_Size :: (PyPtr) -> ssize_t
|
246
|
+
attach_function :PySequence_Size, [PyObject.by_ref], :ssize_t
|
247
|
+
|
248
|
+
# PySequence_GetItem :: (PyPtr, ssize_t) -> PyPtr
|
249
|
+
attach_function :PySequence_GetItem, [PyObject.by_ref, :ssize_t], PyObject.by_ref
|
250
|
+
|
251
|
+
# Dict
|
252
|
+
|
253
|
+
attach_function :PyDict_New, [], PyObject.by_ref
|
254
|
+
|
255
|
+
# PyDict_GetItem :: (PyPtr, PyPtr) -> PyPtr
|
256
|
+
attach_function :PyDict_GetItem, [PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
257
|
+
|
258
|
+
# PyDict_GetItemString :: (PyPtr, char const*) -> PyPtr
|
259
|
+
attach_function :PyDict_GetItemString, [PyObject.by_ref, :string], PyObject.by_ref
|
260
|
+
|
261
|
+
# PyDict_SetItem :: (PyPtr, PyPtr, PyPtr) -> int
|
262
|
+
attach_function :PyDict_SetItem, [PyObject.by_ref, PyObject.by_ref, PyObject.by_ref], :int
|
263
|
+
|
264
|
+
# PyDict_SetItemString :: (PyPtr, char const*, PyPtr) -> int
|
265
|
+
attach_function :PyDict_SetItemString, [PyObject.by_ref, :string, PyObject.by_ref], :int
|
266
|
+
|
267
|
+
# PyDict_DelItem :: (PyPtr, PyPtr) -> int
|
268
|
+
attach_function :PyDict_DelItem, [PyObject.by_ref, PyObject.by_ref], :int
|
269
|
+
|
270
|
+
# PyDict_DelItemString :: (PyPtr, char const*) -> int
|
271
|
+
attach_function :PyDict_DelItem, [PyObject.by_ref, :string], :int
|
272
|
+
|
273
|
+
# PyDict_Size :: (PyPtr) -> ssize_t
|
274
|
+
attach_function :PyDict_Size, [PyObject.by_ref], :ssize_t
|
275
|
+
|
276
|
+
# PyDict_Keys :: (PyPtr) -> PyPtr
|
277
|
+
attach_function :PyDict_Keys, [PyObject.by_ref], PyObject.by_ref
|
278
|
+
|
279
|
+
# PyDict_Values :: (PyPtr) -> PyPtr
|
280
|
+
attach_function :PyDict_Values, [PyObject.by_ref], PyObject.by_ref
|
281
|
+
|
282
|
+
# PyDict_Items :: (PyPtr) -> PyPtr
|
283
|
+
attach_function :PyDict_Items, [PyObject.by_ref], PyObject.by_ref
|
284
|
+
|
285
|
+
# PyDict_Contains :: (PyPtr, PyPtr) -> int
|
286
|
+
attach_function :PyDict_Contains, [PyObject.by_ref, PyObject.by_ref], :int
|
287
|
+
|
288
|
+
# PySet_Size :: (PyPtr) -> ssize_t
|
289
|
+
attach_function :PySet_Size, [PyObject.by_ref], :ssize_t
|
290
|
+
|
291
|
+
# PySet_Contains :: (PyPtr, PyPtr) -> int
|
292
|
+
attach_function :PySet_Contains, [PyObject.by_ref, PyObject.by_ref], :int
|
293
|
+
|
294
|
+
# PySet_Add :: (PyPtr, PyPtr) -> int
|
295
|
+
attach_function :PySet_Add, [PyObject.by_ref, PyObject.by_ref], :int
|
296
|
+
|
297
|
+
# PySet_Discard :: (PyPtr, PyPtr) -> int
|
298
|
+
attach_function :PySet_Discard, [PyObject.by_ref, PyObject.by_ref], :int
|
299
|
+
|
300
|
+
# PyModule_GetDict :: (PyPtr) -> PyPtr
|
301
|
+
attach_function :PyModule_GetDict, [PyObject.by_ref], PyObject.by_ref
|
302
|
+
|
303
|
+
# PyImport_ImportModule :: (char const*) -> PyPtr
|
304
|
+
attach_function :PyImport_ImportModule, [:string], PyObject.by_ref
|
305
|
+
|
306
|
+
# Operators
|
307
|
+
|
308
|
+
attach_function :PyNumber_Add, [PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
309
|
+
attach_function :PyNumber_Subtract, [PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
310
|
+
attach_function :PyNumber_Multiply, [PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
311
|
+
attach_function :PyNumber_TrueDivide, [PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
312
|
+
|
313
|
+
# Py_CompileString :: (char const*, char const*, int) -> PyPtr
|
314
|
+
attach_function :Py_CompileString, [:string, :string, :int], PyObject.by_ref
|
315
|
+
|
316
|
+
# PyEval_EvalCode :: (PyPtr, PyPtr, PyPtr) -> PyPtr
|
317
|
+
attach_function :PyEval_EvalCode, [PyObject.by_ref, PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
318
|
+
|
319
|
+
# Error
|
320
|
+
|
321
|
+
attach_function :PyErr_Print, [], :void
|
322
|
+
attach_function :PyErr_Occurred, [], PyObject.by_ref
|
323
|
+
attach_function :PyErr_Fetch, [:pointer, :pointer, :pointer], :void
|
324
|
+
attach_function :PyErr_NormalizeException, [:pointer, :pointer, :pointer], :void
|
325
|
+
|
326
|
+
public_class_method
|
327
|
+
end
|
328
|
+
|
329
|
+
PYTHON_DESCRIPTION = LibPython.Py_GetVersion().freeze
|
330
|
+
PYTHON_VERSION = PYTHON_DESCRIPTION.split(' ', 2)[0].freeze
|
331
|
+
end
|