pycall 0.1.0.alpha → 0.1.0.alpha.20170224
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 +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
|