pycall 0.1.0.alpha.20170224b → 0.1.0.alpha.20170226
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/examples/classifier_comparison.rb +7 -2
- data/examples/hist.rb +5 -0
- data/examples/plot_forest_importances_faces.rb +5 -0
- data/examples/sum_benchmarking.rb +5 -0
- data/lib/pycall/conversion.rb +38 -2
- data/lib/pycall/dict.rb +4 -1
- data/lib/pycall/eval.rb +6 -1
- data/lib/pycall/iruby_helper.rb +40 -0
- data/lib/pycall/libpython.rb +7 -1
- data/lib/pycall/list.rb +23 -1
- data/lib/pycall/pyerror.rb +11 -1
- data/lib/pycall/pyobject.rb +11 -2
- data/lib/pycall/pyobject_wrapper.rb +4 -2
- data/lib/pycall/types.rb +2 -2
- data/lib/pycall/utils.rb +5 -0
- data/lib/pycall/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab504049d683e34fa1e325340601d6577a40cd5e
|
4
|
+
data.tar.gz: c477cf5937dd0499e50512a4829ad3688d8e34e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 041fda79cb71ccb7653e442c1831f97b489058adb48159cef581d49174182350047e736192eb5568c6d2c4b61d6e2691e917ccb28f578c2dd5b340d90dca41d3
|
7
|
+
data.tar.gz: eb6af8382a0531729aa8ac151d0880e1c7c613441550490fad77e924b26012723833b5ea1aaab75e6ef9a9f1d9d4e99e416ac4c244c155f7c5a2f7b42c4c5d3c
|
@@ -2,8 +2,6 @@ require 'pycall/import'
|
|
2
2
|
include PyCall::Import
|
3
3
|
|
4
4
|
pyimport 'numpy', as: :np
|
5
|
-
pyimport 'matplotlib.pyplot', as: :plt
|
6
|
-
pyimport 'matplotlib.colors', as: :mplc
|
7
5
|
pyfrom 'sklearn.cross_validation', import: :train_test_split
|
8
6
|
pyfrom 'sklearn.preprocessing', import: :StandardScaler
|
9
7
|
pyfrom 'sklearn.datasets', import: %i(make_moons make_circles make_classification)
|
@@ -14,6 +12,13 @@ pyfrom 'sklearn.ensemble', import: %i(RandomForestClassifier AdaBoostClassifier)
|
|
14
12
|
pyfrom 'sklearn.naive_bayes', import: :GaussianNB
|
15
13
|
pyfrom 'sklearn.discriminant_analysis', import: %i(LinearDiscriminantAnalysis QuadraticDiscriminantAnalysis)
|
16
14
|
|
15
|
+
# FIXME: MacOSX backend is not usable through pycall. I want to fix this issue but the reason is unclear.
|
16
|
+
pyimport 'matplotlib', as: :mp
|
17
|
+
mp.rcParams[:backend] = 'TkAgg' if mp.rcParams[:backend] == 'MacOSX'
|
18
|
+
|
19
|
+
pyimport 'matplotlib.pyplot', as: :plt
|
20
|
+
pyimport 'matplotlib.colors', as: :mplc
|
21
|
+
|
17
22
|
h = 0.02 # step size in the mesh
|
18
23
|
|
19
24
|
names = [
|
data/examples/hist.rb
CHANGED
@@ -2,6 +2,11 @@ require 'pycall/import'
|
|
2
2
|
include PyCall::Import
|
3
3
|
|
4
4
|
pyimport 'numpy', as: 'np'
|
5
|
+
|
6
|
+
# FIXME: MacOSX backend is not usable through pycall. I want to fix this issue but the reason is unclear.
|
7
|
+
pyimport 'matplotlib', as: :mp
|
8
|
+
mp.rcParams[:backend] = 'TkAgg' if mp.rcParams[:backend] == 'MacOSX'
|
9
|
+
|
5
10
|
pyimport 'matplotlib.mlab', as: 'mlab'
|
6
11
|
pyimport 'matplotlib.pyplot', as: 'plt'
|
7
12
|
|
@@ -3,6 +3,11 @@ require 'pycall/import'
|
|
3
3
|
include PyCall::Import
|
4
4
|
|
5
5
|
pyimport 'numpy', as: 'np'
|
6
|
+
|
7
|
+
# FIXME: MacOSX backend is not usable through pycall. I want to fix this issue but the reason is unclear.
|
8
|
+
pyimport 'matplotlib', as: :mp
|
9
|
+
mp.rcParams[:backend] = 'TkAgg' if mp.rcParams[:backend] == 'MacOSX'
|
10
|
+
|
6
11
|
pyimport 'matplotlib.pyplot', as: 'plt'
|
7
12
|
|
8
13
|
pyfrom 'sklearn.datasets', import: 'fetch_olivetti_faces'
|
@@ -3,6 +3,11 @@ include PyCall::Import
|
|
3
3
|
|
4
4
|
require 'benchmark'
|
5
5
|
pyimport :pandas, as: :pd
|
6
|
+
|
7
|
+
# FIXME: MacOSX backend is not usable through pycall. I want to fix this issue but the reason is unclear.
|
8
|
+
pyimport 'matplotlib', as: :mp
|
9
|
+
mp.rcParams[:backend] = 'TkAgg' if mp.rcParams[:backend] == 'MacOSX'
|
10
|
+
|
6
11
|
pyimport :seaborn, as: :sns
|
7
12
|
pyimport 'matplotlib.pyplot', as: :plt
|
8
13
|
|
data/lib/pycall/conversion.rb
CHANGED
@@ -1,5 +1,41 @@
|
|
1
1
|
module PyCall
|
2
2
|
module Conversions
|
3
|
+
@python_type_map = []
|
4
|
+
|
5
|
+
class TypePair < Struct.new(:pytype, :rbtype)
|
6
|
+
def to_a
|
7
|
+
[pytype, rbtype]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.python_type_mapping(pytype, rbtype)
|
12
|
+
@python_type_map.each_with_index do |type_pair, index|
|
13
|
+
next unless pytype == type_pair.pytype
|
14
|
+
type_pair.rbtype = rbtype
|
15
|
+
return
|
16
|
+
end
|
17
|
+
@python_type_map << TypePair.new(pytype, rbtype)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.to_ruby(pyobj)
|
21
|
+
unless pyobj.kind_of? PyObject
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
@python_type_map.each do |tp|
|
25
|
+
pytype, rbtype = tp.to_a
|
26
|
+
next unless pyobj.kind_of?(pytype)
|
27
|
+
case
|
28
|
+
when rbtype.kind_of?(Proc)
|
29
|
+
return rbtype.(pyobj)
|
30
|
+
when rbtype.respond_to?(:from_python)
|
31
|
+
return rbtype.from_python(pyobj)
|
32
|
+
else
|
33
|
+
return rbtype.new(pyobj)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
pyobj
|
37
|
+
end
|
38
|
+
|
3
39
|
def self.from_ruby(obj)
|
4
40
|
case obj
|
5
41
|
when PyObject
|
@@ -102,7 +138,7 @@ module PyCall
|
|
102
138
|
return Conversions.convert_to_string(py_str_ptr).force_encoding(Encoding::UTF_8)
|
103
139
|
|
104
140
|
when LibPython.PyList_Type
|
105
|
-
return
|
141
|
+
return PyCall::List.new(self)
|
106
142
|
|
107
143
|
when LibPython.PyTuple_Type
|
108
144
|
return Conversions.convert_to_tuple(self)
|
@@ -114,7 +150,7 @@ module PyCall
|
|
114
150
|
return PyCall::Set.new(self)
|
115
151
|
end
|
116
152
|
|
117
|
-
self
|
153
|
+
Conversions.to_ruby(self)
|
118
154
|
end
|
119
155
|
end
|
120
156
|
end
|
data/lib/pycall/dict.rb
CHANGED
@@ -68,7 +68,10 @@ module PyCall
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def has_key?(key)
|
71
|
-
|
71
|
+
key = Conversions.from_ruby(key)
|
72
|
+
value = LibPython.PyDict_Contains(__pyobj__, key)
|
73
|
+
raise PyError.fetch if value == -1
|
74
|
+
1 == value
|
72
75
|
end
|
73
76
|
|
74
77
|
def default=(val)
|
data/lib/pycall/eval.rb
CHANGED
@@ -7,6 +7,7 @@ module PyCall
|
|
7
7
|
locals_ptr = maindict_ptr
|
8
8
|
defer_sigint do
|
9
9
|
py_code_ptr = LibPython.Py_CompileString(str, filename, Py_eval_input)
|
10
|
+
raise PyError.fetch if py_code_ptr.null?
|
10
11
|
LibPython.PyEval_EvalCode(py_code_ptr, globals_ptr, locals_ptr)
|
11
12
|
end
|
12
13
|
end
|
@@ -14,8 +15,12 @@ module PyCall
|
|
14
15
|
class << self
|
15
16
|
private
|
16
17
|
|
18
|
+
def main_module
|
19
|
+
@main_module ||= PyCall.import_module("__main__")
|
20
|
+
end
|
21
|
+
|
17
22
|
def maindict_ptr
|
18
|
-
LibPython.PyModule_GetDict(
|
23
|
+
@maindict_ptr ||= LibPython.PyModule_GetDict(main_module)
|
19
24
|
end
|
20
25
|
|
21
26
|
def defer_sigint
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'pycall'
|
2
|
+
require 'iruby'
|
3
|
+
|
4
|
+
module PyCall
|
5
|
+
module IRubyHelper
|
6
|
+
private
|
7
|
+
|
8
|
+
def check_pyobject_respond_to_format_method(obj, method_name)
|
9
|
+
return false unless obj.kind_of? PyObject
|
10
|
+
return false unless PyCall.hasattr?(obj, method_name)
|
11
|
+
PyCall.getattr(obj, method_name).kind_of? PyCall::LibPython.PyMethod_Type
|
12
|
+
end
|
13
|
+
|
14
|
+
def register_pyobject_formatter(format_name, mime, priority_value=0)
|
15
|
+
method_name = :"_repr_#{format_name}_"
|
16
|
+
match do |obj|
|
17
|
+
check_pyobject_respond_to_format_method(obj, method_name)
|
18
|
+
end
|
19
|
+
priority priority_value
|
20
|
+
format mime do |obj|
|
21
|
+
PyCall.getattr(obj, method_name).()
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
::IRuby::Display::Registry.module_eval do
|
28
|
+
extend PyCall::IRubyHelper
|
29
|
+
|
30
|
+
register_pyobject_formatter :html, 'text/html'
|
31
|
+
register_pyobject_formatter :markdown, 'text/markdown'
|
32
|
+
register_pyobject_formatter :svg, 'image/svg+xml'
|
33
|
+
register_pyobject_formatter :png, 'image/png'
|
34
|
+
register_pyobject_formatter :jpeg, 'image/jpeg'
|
35
|
+
register_pyobject_formatter :latex, 'text/latex'
|
36
|
+
register_pyobject_formatter :json, 'application/json'
|
37
|
+
register_pyobject_formatter :javascript, 'application/javascript'
|
38
|
+
register_pyobject_formatter :pdf, 'application/pdf'
|
39
|
+
register_pyobject_formatter :pretty, 'text/plain', -1000
|
40
|
+
end
|
data/lib/pycall/libpython.rb
CHANGED
@@ -129,6 +129,7 @@ module PyCall
|
|
129
129
|
attach_variable :PySet_Type, PyTypeObject
|
130
130
|
|
131
131
|
attach_variable :PyFunction_Type, PyTypeObject
|
132
|
+
attach_variable :PyMethod_Type, PyTypeObject
|
132
133
|
|
133
134
|
# --- functions ---
|
134
135
|
|
@@ -146,8 +147,11 @@ module PyCall
|
|
146
147
|
attach_function :PyObject_SetItem, [PyObject.by_ref, PyObject.by_ref, PyObject.by_ref], :int
|
147
148
|
attach_function :PyObject_DelItem, [PyObject.by_ref, PyObject.by_ref], :int
|
148
149
|
attach_function :PyObject_Call, [PyObject.by_ref, PyObject.by_ref, PyObject.by_ref], PyObject.by_ref
|
149
|
-
attach_function :PyObject_IsInstance, [PyObject.by_ref,
|
150
|
+
attach_function :PyObject_IsInstance, [PyObject.by_ref, PyObject.by_ref], :int
|
150
151
|
attach_function :PyObject_Dir, [PyObject.by_ref], PyObject.by_ref
|
152
|
+
attach_function :PyObject_Repr, [PyObject.by_ref], PyObject.by_ref
|
153
|
+
attach_function :PyObject_Str, [PyObject.by_ref], PyObject.by_ref
|
154
|
+
attach_function :PyObject_Type, [PyObject.by_ref], PyTypeObject.by_ref
|
151
155
|
|
152
156
|
# Bool
|
153
157
|
|
@@ -237,6 +241,7 @@ module PyCall
|
|
237
241
|
|
238
242
|
attach_function :PySequence_Size, [PyObject.by_ref], :ssize_t
|
239
243
|
attach_function :PySequence_GetItem, [PyObject.by_ref, :ssize_t], PyObject.by_ref
|
244
|
+
attach_function :PySequence_Contains, [PyObject.by_ref, PyObject.by_ref], :int
|
240
245
|
|
241
246
|
# Dict
|
242
247
|
|
@@ -282,6 +287,7 @@ module PyCall
|
|
282
287
|
|
283
288
|
# Error
|
284
289
|
|
290
|
+
attach_function :PyErr_Clear, [], :void
|
285
291
|
attach_function :PyErr_Print, [], :void
|
286
292
|
attach_function :PyErr_Occurred, [], PyObject.by_ref
|
287
293
|
attach_function :PyErr_Fetch, [:pointer, :pointer, :pointer], :void
|
data/lib/pycall/list.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module PyCall
|
2
2
|
class List
|
3
3
|
include PyObjectWrapper
|
4
|
+
include Enumerable
|
4
5
|
|
5
6
|
def self.new(init=nil)
|
6
7
|
case init
|
@@ -47,7 +48,28 @@ module PyCall
|
|
47
48
|
|
48
49
|
def include?(value)
|
49
50
|
value = Conversions.from_ruby(value)
|
50
|
-
LibPython.
|
51
|
+
value = LibPython.PySequence_Contains(__pyobj__, value)
|
52
|
+
raise PyError.fetch if value == -1
|
53
|
+
1 == value
|
54
|
+
end
|
55
|
+
|
56
|
+
def ==(other)
|
57
|
+
case other
|
58
|
+
when Array
|
59
|
+
self.to_a == other
|
60
|
+
else
|
61
|
+
super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def each
|
66
|
+
return enum_for unless block_given?
|
67
|
+
i, n = 0, size
|
68
|
+
while i < n
|
69
|
+
yield self[i]
|
70
|
+
i += 1
|
71
|
+
end
|
72
|
+
self
|
51
73
|
end
|
52
74
|
|
53
75
|
def to_a
|
data/lib/pycall/pyerror.rb
CHANGED
@@ -17,9 +17,19 @@ module PyCall
|
|
17
17
|
@type = type
|
18
18
|
@value = value
|
19
19
|
@traceback = traceback
|
20
|
-
super("
|
20
|
+
super("Error occurred in Python")
|
21
21
|
end
|
22
22
|
|
23
23
|
attr_reader :type, :value, :traceback
|
24
|
+
|
25
|
+
def message
|
26
|
+
"#{PyObject.new(type.to_ptr)}: #{value}".tap do |msg|
|
27
|
+
unless traceback.null?
|
28
|
+
if (o = PyCall.format_traceback(traceback))
|
29
|
+
msg.concat("\n", *o)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
24
34
|
end
|
25
35
|
end
|
data/lib/pycall/pyobject.rb
CHANGED
@@ -39,7 +39,7 @@ module PyCall
|
|
39
39
|
|
40
40
|
def kind_of?(klass)
|
41
41
|
case klass
|
42
|
-
when PyTypeObject
|
42
|
+
when PyObject, PyTypeObject
|
43
43
|
Types.pyisinstance(self, klass)
|
44
44
|
else
|
45
45
|
super
|
@@ -122,7 +122,16 @@ module PyCall
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def to_s
|
125
|
-
|
125
|
+
s = LibPython.PyObject_Repr(self)
|
126
|
+
if s.null?
|
127
|
+
LibPython.PyErr_Clear()
|
128
|
+
s = LibPython.PyObject_Str(self)
|
129
|
+
if s.null?
|
130
|
+
LibPython.PyErr_Clear()
|
131
|
+
return super
|
132
|
+
end
|
133
|
+
end
|
134
|
+
s.to_ruby
|
126
135
|
end
|
127
136
|
|
128
137
|
alias inspect to_s
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module PyCall
|
2
2
|
module PyObjectWrapper
|
3
|
-
def initialize(pyobj, pytype)
|
3
|
+
def initialize(pyobj, pytype=nil)
|
4
4
|
check_type pyobj, pytype
|
5
|
+
pytype ||= LibPython.PyObject_Type(pyobj)
|
5
6
|
@__pyobj__ = pyobj
|
6
7
|
end
|
7
8
|
|
@@ -41,7 +42,8 @@ module PyCall
|
|
41
42
|
private
|
42
43
|
|
43
44
|
def check_type(pyobj, pytype)
|
44
|
-
return if pyobj.kind_of?(PyObject)
|
45
|
+
return if pyobj.kind_of?(PyObject)
|
46
|
+
return if pytype.nil? || pyobj.kind_of?(pytype)
|
45
47
|
raise TypeError, "the argument must be a PyObject of #{pytype}"
|
46
48
|
end
|
47
49
|
end
|
data/lib/pycall/types.rb
CHANGED
@@ -2,8 +2,8 @@ module PyCall
|
|
2
2
|
module Types
|
3
3
|
def self.pyisinstance(pyobj, pytype)
|
4
4
|
check_pyobject(pyobj)
|
5
|
-
|
6
|
-
LibPython.PyObject_IsInstance(
|
5
|
+
pytype = PyObject.new(pytype.to_ptr) if pytype.kind_of?(PyTypeObject)
|
6
|
+
LibPython.PyObject_IsInstance(pyobj, pytype) == 1
|
7
7
|
end
|
8
8
|
|
9
9
|
class << self
|
data/lib/pycall/utils.rb
CHANGED
data/lib/pycall/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pycall
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.alpha.
|
4
|
+
version: 0.1.0.alpha.20170226
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenta Murata
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- lib/pycall/eval.rb
|
97
97
|
- lib/pycall/import.rb
|
98
98
|
- lib/pycall/init.rb
|
99
|
+
- lib/pycall/iruby_helper.rb
|
99
100
|
- lib/pycall/libpython.rb
|
100
101
|
- lib/pycall/list.rb
|
101
102
|
- lib/pycall/pyerror.rb
|