pybind 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ from distutils.sysconfig import get_config_var
2
+ import sys
3
+
4
+ print('EXECUTABLE: ' + str(sys.executable))
5
+ print('EXECPREFIX: ' + str(sys.exec_prefix))
6
+ print('PREFIX: ' + str(sys.prefix))
7
+ if sys.version_info >= (3, 3):
8
+ print('IMPLEMENTATIONMULTIARCH: ' + str(sys.implementation._multiarch))
9
+ for var in ('VERSION', 'INSTSONAME', 'LIBRARY', 'LDLIBRARY', 'LIBDIR', 'PYTHONFRAMEWORKPREFIX', 'MULTIARCH'):
10
+ print(var + ': ' + str(get_config_var(var)))
@@ -0,0 +1,36 @@
1
+ require 'ffi'
2
+
3
+ module PyBind
4
+ class PyObjectStruct < FFI::Struct
5
+ layout ob_refcnt: :ssize_t,
6
+ ob_type: PyObjectStruct.by_ref
7
+
8
+ def self.null
9
+ new(FFI::Pointer::NULL)
10
+ end
11
+
12
+ def none?
13
+ PyBind.None.to_ptr == to_ptr
14
+ end
15
+
16
+ def kind_of?(klass)
17
+ case klass
18
+ when PyBind::PyObjectStruct
19
+ value = LibPython.PyObject_IsInstance(self, klass)
20
+ raise PyError.fetch if value == -1
21
+ value == 1
22
+ else
23
+ super
24
+ end
25
+ end
26
+
27
+ def to_ruby_object
28
+ PyObject.new(self)
29
+ end
30
+
31
+ def to_python_struct
32
+ self
33
+ end
34
+ alias_method :to_python, :to_python_struct
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ module PyBind
2
+ module TypeCast
3
+ def self.from_python(pyobj)
4
+ pystruct = pyobj.to_python_struct
5
+ return nil if pystruct.null? || pystruct.none?
6
+
7
+ Types.pytypes.each do |pytype|
8
+ return pytype.from_python(pystruct) if pytype.python_instance?(pystruct)
9
+ end
10
+ PyObject.from_python(pystruct)
11
+ end
12
+
13
+ def self.to_python_arguments(indices)
14
+ if indices.length == 1
15
+ indices = indices[0]
16
+ else
17
+ indices = PyTuple.new(indices)
18
+ end
19
+ indices.to_python
20
+ end
21
+ end
22
+
23
+ class PyObjectStruct
24
+ def to_ruby
25
+ TypeCast.from_python(self)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ module PyBind
2
+ module Types
3
+ class << self
4
+ attr_reader :pytypes
5
+ end
6
+
7
+ @pytypes ||= []
8
+ def self.register_type(pytype)
9
+ @pytypes.unshift(pytype)
10
+ end
11
+ end
12
+ end
13
+
14
+ require 'pybind/core_ext/basic'
15
+ require 'pybind/types/basic'
16
+ require 'pybind/types/object'
17
+ require 'pybind/types/tuple'
18
+ require 'pybind/types/slice'
19
+ require 'pybind/types/list'
20
+ require 'pybind/types/dict'
21
+ require 'pybind/types/set'
@@ -0,0 +1,70 @@
1
+ module PyBind
2
+ class PyType
3
+ include PyObjectWrapper
4
+ pybind_type LibPython.PyType_Type
5
+
6
+ def to_s
7
+ return super unless has_attribute?('__name__')
8
+ get_attribute('__name__')
9
+ end
10
+ end
11
+
12
+ class PyString
13
+ include PyObjectWrapper
14
+
15
+ pybind_type LibPython.PyString_Type do |pystruct|
16
+ FFI::MemoryPointer.new(:string) do |str_ptr|
17
+ FFI::MemoryPointer.new(:int) do |len_ptr|
18
+ res = LibPython.PyString_AsStringAndSize(pystruct, str_ptr, len_ptr)
19
+ return nil if res == -1 # FIXME: error
20
+
21
+ len = len_ptr.get(:int, 0)
22
+ return str_ptr.get_pointer(0).read_string(len)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ class PyUnicode
29
+ include PyObjectWrapper
30
+
31
+ pybind_type LibPython.PyUnicode_Type do |pystruct|
32
+ pystruct = LibPython.PyUnicode_AsUTF8String(pystruct)
33
+ PyString.from_python(pystruct).force_encoding(Encoding::UTF_8)
34
+ end
35
+ end
36
+
37
+ class PyInt
38
+ include PyObjectWrapper
39
+
40
+ pybind_type LibPython.PyInt_Type do |pystruct|
41
+ LibPython.PyInt_AsSsize_t(pystruct)
42
+ end
43
+ end
44
+
45
+ class PyBool
46
+ include PyObjectWrapper
47
+
48
+ pybind_type LibPython.PyBool_Type do |pystruct|
49
+ LibPython.PyInt_AsSsize_t(pystruct) != 0
50
+ end
51
+ end
52
+
53
+ class PyFloat
54
+ include PyObjectWrapper
55
+
56
+ pybind_type LibPython.PyFloat_Type do |pystruct|
57
+ LibPython.PyFloat_AsDouble(pystruct)
58
+ end
59
+ end
60
+
61
+ class PyComplex
62
+ include PyObjectWrapper
63
+
64
+ pybind_type LibPython.PyComplex_Type do |pystruct|
65
+ real = LibPython.PyComplex_RealAsDouble(pystruct)
66
+ imag = LibPython.PyComplex_ImagAsDouble(pystruct)
67
+ Complex(real, imag)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,94 @@
1
+ module PyBind
2
+ class PyDict
3
+ include Enumerable
4
+ include PyObjectWrapper
5
+ pybind_type LibPython.PyDict_Type
6
+
7
+ def self.new(init = nil)
8
+ case init
9
+ when PyObjectStruct
10
+ super
11
+ when nil
12
+ new(LibPython.PyDict_New())
13
+ when Hash
14
+ new.tap do |dict|
15
+ init.each do |key, value|
16
+ dict[key] = value
17
+ end
18
+ end
19
+ else
20
+ raise TypeError, "the argument must be a PyObjectStruct or a Hash"
21
+ end
22
+ end
23
+
24
+ def [](key)
25
+ case key
26
+ when String, Symbol
27
+ LibPython.PyDict_GetItemString(@pystruct, key.to_s).to_ruby
28
+ else
29
+ key = key.to_python
30
+ LibPython.PyDict_GetItem(@pystruct, key).to_ruby
31
+ end
32
+ end
33
+
34
+ def []=(key, value)
35
+ value = value.to_python
36
+ case key
37
+ when String, Symbol
38
+ LibPython.PyDict_SetItemString(@pystruct, key.to_s, value)
39
+ else
40
+ key = key.to_python
41
+ LibPython.PyDict_SetItem(@pystruct, key, value)
42
+ end
43
+ value
44
+ end
45
+
46
+ def delete(key)
47
+ case key
48
+ when String, Symbol
49
+ value = LibPython.PyDict_GetItemString(@pystruct, key).to_ruby
50
+ LibPython.PyDict_DelItemString(@pystruct, key.to_s)
51
+ else
52
+ key = key.to_python
53
+ value = LibPython.PyDict_GetItem(@pystruct, key).to_ruby
54
+ LibPython.PyDict_DelItem(@pystruct, key)
55
+ end
56
+ value
57
+ end
58
+
59
+ def size
60
+ LibPython.PyDict_Size(@pystruct)
61
+ end
62
+
63
+ def keys
64
+ LibPython.PyDict_Keys(@pystruct).to_ruby
65
+ end
66
+
67
+ def values
68
+ LibPython.PyDict_Values(@pystruct).to_ruby
69
+ end
70
+
71
+ def has_key?(key)
72
+ key = key.to_python
73
+ value = LibPython.PyDict_Contains(@pystruct, key)
74
+ raise PyError.fetch if value == -1
75
+ value == 1
76
+ end
77
+
78
+ def to_a
79
+ LibPython.PyDict_Items(@pystruct).to_ruby
80
+ end
81
+
82
+ def to_hash
83
+ Hash[to_a]
84
+ end
85
+
86
+ def each
87
+ return enum_for unless block_given?
88
+ keys.each do |key|
89
+ yield key, self[key]
90
+ end
91
+ self
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,26 @@
1
+ module PyBind
2
+ module PyCallable
3
+ end
4
+
5
+ class PyFunction
6
+ include PyCallable
7
+ include PyObjectWrapper
8
+ pybind_type PyBind.types.FunctionType
9
+ end
10
+
11
+ class PyMethod
12
+ include PyCallable
13
+ include PyObjectWrapper
14
+ pybind_type PyBind.types.MethodType
15
+ end
16
+
17
+ class PyBuiltinFunction
18
+ include PyCallable
19
+ include PyObjectWrapper
20
+ pybind_type PyBind.types.BuiltinFunctionType
21
+ end
22
+
23
+ class PyType
24
+ include PyCallable
25
+ end
26
+ end
@@ -0,0 +1,39 @@
1
+ require 'pybind/types/sequence'
2
+
3
+ module PyBind
4
+ class PyList
5
+ include PyObjectWrapper
6
+ pybind_type LibPython.PyList_Type
7
+
8
+ include PySequence
9
+
10
+ def self.new(init = nil)
11
+ case init
12
+ when PyObjectStruct
13
+ super
14
+ when nil
15
+ new(0)
16
+ when Integer
17
+ new(LibPython.PyList_New(init))
18
+ when Array
19
+ new.tap do |list|
20
+ init.each do |item|
21
+ list << item
22
+ end
23
+ end
24
+ else
25
+ raise TypeError, "the argument must be an Integer, a PyObjectStruct or a Array"
26
+ end
27
+ end
28
+
29
+ def <<(value)
30
+ value = value.to_python
31
+ LibPython.PyList_Append(@pystruct, value)
32
+ self
33
+ end
34
+
35
+ def size
36
+ LibPython.PyList_Size(@pystruct)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ module PyBind
2
+ class PyObject
3
+ include PyObjectWrapper
4
+
5
+ def self.null
6
+ new(PyObjectStruct.null)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ module PyBind
2
+ module PySequence
3
+ include Enumerable
4
+
5
+ def include?(value)
6
+ value = value.to_python
7
+ value = LibPython.PySequence_Contains(@pystruct, value)
8
+ raise PyError.fetch if value == -1
9
+ value == 1
10
+ end
11
+
12
+ def each
13
+ return enum_for unless block_given?
14
+ size.times do |i|
15
+ yield self[i]
16
+ end
17
+ self
18
+ end
19
+
20
+ def to_a
21
+ each.to_a
22
+ end
23
+
24
+ alias_method :to_ary, :to_a
25
+ end
26
+ end
@@ -0,0 +1,19 @@
1
+ module PyBind
2
+ class PySet
3
+ include PyObjectWrapper
4
+ pybind_type LibPython.PySet_Type
5
+
6
+ def initialize(init)
7
+ super
8
+ end
9
+
10
+ def size
11
+ LibPython.PySet_Size(@pystruct)
12
+ end
13
+
14
+ def include?(obj)
15
+ obj = obj.to_python
16
+ LibPython.PySet_Contains(@pystruct, obj) == 1
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module PyBind
2
+ class PySlice
3
+ include PyObjectWrapper
4
+ pybind_type LibPython.PySlice_Type
5
+
6
+ def self.new(start, stop = nil, step = nil)
7
+ if stop.nil? && step.nil?
8
+ start, stop = nil, start
9
+ return super(stop) if stop.kind_of?(PyObjectStruct)
10
+ end
11
+ start = start ? start.to_python : PyObjectStruct.null
12
+ stop = stop ? stop.to_python : PyObjectStruct.null
13
+ step = step ? step.to_python : PyObjectStruct.null
14
+ pyobj = LibPython.PySlice_New(start, stop, step)
15
+ raise PyError.fetch if pyobj.null?
16
+ pyobj.to_ruby
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,45 @@
1
+ require 'pybind/types/sequence'
2
+
3
+ module PyBind
4
+ class PyTuple
5
+ include PyObjectWrapper
6
+ pybind_type LibPython.PyTuple_Type
7
+
8
+ include PySequence
9
+
10
+ def self.new(init)
11
+ case init
12
+ when PyObjectStruct
13
+ super
14
+ when Integer
15
+ super(LibPython.PyTuple_New(init))
16
+ when Array
17
+ tuple = new(init.size)
18
+ init.each_with_index do |obj, index|
19
+ tuple[index] = obj
20
+ end
21
+ tuple
22
+ else
23
+ raise TypeError, "the argument must be an Integer, a PyObjectStruct or a Array"
24
+ end
25
+ end
26
+
27
+ # Make tuple from array
28
+ def self.[](*ary)
29
+ new(ary)
30
+ end
31
+
32
+ def size
33
+ LibPython.PyTuple_Size(@pystruct)
34
+ end
35
+
36
+ def [](index)
37
+ LibPython.PyTuple_GetItem(@pystruct, index).to_ruby
38
+ end
39
+
40
+ def []=(index, value)
41
+ value = value.to_python
42
+ LibPython.PyTuple_SetItem(@pystruct, index, value)
43
+ end
44
+ end
45
+ end