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.
@@ -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
@@ -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
@@ -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