pycall 1.0.1-x64-mingw32
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 +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +41 -0
- data/CHANGES.md +39 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +91 -0
- data/Rakefile +29 -0
- data/appveyor.yml +138 -0
- data/bin/console +10 -0
- data/bin/guard +17 -0
- data/bin/rspec +17 -0
- data/bin/runner +6 -0
- data/bin/setup +8 -0
- data/config/Guardfile +30 -0
- data/docker/Dockerfile +191 -0
- data/docker/Gemfile +12 -0
- data/docker/README.md +22 -0
- data/examples/classifier_comparison.rb +135 -0
- data/examples/datascience_rb_20170519.ipynb +4836 -0
- data/examples/hist.rb +32 -0
- data/examples/notebooks/classifier_comparison.ipynb +226 -0
- data/examples/notebooks/forest_importances.ipynb +238 -0
- data/examples/notebooks/iruby_integration.ipynb +183 -0
- data/examples/notebooks/lorenz_attractor.ipynb +214 -0
- data/examples/notebooks/polar_axes.ipynb +209 -0
- data/examples/notebooks/sum_benchmarking.ipynb +374 -0
- data/examples/notebooks/xkcd_style.ipynb +149 -0
- data/examples/plot_forest_importances_faces.rb +46 -0
- data/examples/sum_benchmarking.rb +49 -0
- data/ext/pycall/extconf.rb +3 -0
- data/ext/pycall/gc.c +74 -0
- data/ext/pycall/libpython.c +217 -0
- data/ext/pycall/pycall.c +2184 -0
- data/ext/pycall/pycall_internal.h +700 -0
- data/ext/pycall/range.c +69 -0
- data/ext/pycall/ruby_wrapper.c +432 -0
- data/lib/pycall.rb +91 -0
- data/lib/pycall/conversion.rb +173 -0
- data/lib/pycall/dict.rb +48 -0
- data/lib/pycall/error.rb +10 -0
- data/lib/pycall/gc_guard.rb +84 -0
- data/lib/pycall/import.rb +120 -0
- data/lib/pycall/init.rb +55 -0
- data/lib/pycall/iruby_helper.rb +40 -0
- data/lib/pycall/libpython.rb +12 -0
- data/lib/pycall/libpython/finder.rb +170 -0
- data/lib/pycall/libpython/pyobject_struct.rb +30 -0
- data/lib/pycall/libpython/pytypeobject_struct.rb +273 -0
- data/lib/pycall/list.rb +45 -0
- data/lib/pycall/pretty_print.rb +9 -0
- data/lib/pycall/pyerror.rb +30 -0
- data/lib/pycall/pyobject_wrapper.rb +212 -0
- data/lib/pycall/python/PyCall/__init__.py +1 -0
- data/lib/pycall/python/PyCall/six.py +23 -0
- data/lib/pycall/python/investigator.py +7 -0
- data/lib/pycall/pytypeobject_wrapper.rb +90 -0
- data/lib/pycall/set.rb +19 -0
- data/lib/pycall/slice.rb +8 -0
- data/lib/pycall/tuple.rb +46 -0
- data/lib/pycall/version.rb +3 -0
- data/lib/pycall/wrapper_object_cache.rb +61 -0
- data/pycall.gemspec +40 -0
- data/tasks/docker.rake +21 -0
- data/tasks/pycall.rake +7 -0
- metadata +228 -0
data/lib/pycall/list.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module PyCall
|
2
|
+
List = builtins.list
|
3
|
+
class List
|
4
|
+
register_python_type_mapping
|
5
|
+
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def include?(item)
|
9
|
+
LibPython::Helpers.sequence_contains(__pyptr__, item)
|
10
|
+
end
|
11
|
+
|
12
|
+
def length
|
13
|
+
PyCall.len(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def each
|
17
|
+
return enum_for unless block_given?
|
18
|
+
LibPython::Helpers.sequence_each(__pyptr__, &proc)
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def <<(item)
|
23
|
+
append(item)
|
24
|
+
end
|
25
|
+
|
26
|
+
def push(*items)
|
27
|
+
items.each {|i| append(i) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def sort
|
31
|
+
dup.sort!
|
32
|
+
end
|
33
|
+
|
34
|
+
def sort!
|
35
|
+
LibPython::Helpers.getattr(__pyptr__, :sort).__call__
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_a
|
40
|
+
Array.new(length) {|i| self[i] }
|
41
|
+
end
|
42
|
+
|
43
|
+
alias to_ary to_a
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'pycall/error'
|
2
|
+
|
3
|
+
module PyCall
|
4
|
+
class PyError < Error
|
5
|
+
def initialize(type, value, traceback)
|
6
|
+
@type = type
|
7
|
+
@value = value
|
8
|
+
@traceback = traceback
|
9
|
+
super("Exception occurred in Python")
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :type, :value, :traceback
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"#{type}: #{value}".tap do |msg|
|
16
|
+
if (strs = format_traceback)
|
17
|
+
msg << "\n"
|
18
|
+
strs.each {|s| msg << s }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def format_traceback
|
26
|
+
return nil if traceback.nil?
|
27
|
+
::PyCall.import_module('traceback').format_tb(traceback)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'pycall/wrapper_object_cache'
|
2
|
+
|
3
|
+
module PyCall
|
4
|
+
module PyObjectWrapper
|
5
|
+
attr_reader :__pyptr__
|
6
|
+
|
7
|
+
def self.extend_object(obj)
|
8
|
+
pyptr = obj.instance_variable_get(:@__pyptr__)
|
9
|
+
unless pyptr.kind_of? PyPtr
|
10
|
+
raise TypeError, "@__pyptr__ should have PyCall::PyPtr object"
|
11
|
+
end
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
OPERATOR_METHOD_NAMES = {
|
16
|
+
:+ => :__add__,
|
17
|
+
:- => :__sub__,
|
18
|
+
:* => :__mul__,
|
19
|
+
:/ => :__truediv__,
|
20
|
+
:% => :__mod__,
|
21
|
+
:** => :__pow__,
|
22
|
+
:<< => :__lshift__,
|
23
|
+
:>> => :__rshift__,
|
24
|
+
:& => :__and__,
|
25
|
+
:^ => :__xor__,
|
26
|
+
:| => :__or__
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
def method_missing(name, *args)
|
30
|
+
name_str = name.to_s if name.kind_of?(Symbol)
|
31
|
+
name_str.chop! if name_str.end_with?('=')
|
32
|
+
case name
|
33
|
+
when *OPERATOR_METHOD_NAMES.keys
|
34
|
+
op_name = OPERATOR_METHOD_NAMES[name]
|
35
|
+
if LibPython::Helpers.hasattr?(__pyptr__, op_name)
|
36
|
+
LibPython::Helpers.define_wrapper_method(self, op_name)
|
37
|
+
singleton_class.__send__(:alias_method, name, op_name)
|
38
|
+
return self.__send__(name, *args)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
if LibPython::Helpers.hasattr?(__pyptr__, name_str)
|
42
|
+
LibPython::Helpers.define_wrapper_method(self, name)
|
43
|
+
return self.__send__(name, *args)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
super
|
47
|
+
end
|
48
|
+
|
49
|
+
def respond_to_missing?(name, include_private)
|
50
|
+
return true if LibPython::Helpers.hasattr?(__pyptr__, name)
|
51
|
+
super
|
52
|
+
end
|
53
|
+
|
54
|
+
def kind_of?(cls)
|
55
|
+
case cls
|
56
|
+
when PyTypeObjectWrapper
|
57
|
+
__pyptr__.kind_of?(cls.__pyptr__)
|
58
|
+
else
|
59
|
+
super
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
[:==, :!=, :<, :<=, :>, :>=].each do |op|
|
64
|
+
class_eval("#{<<-"begin;"}\n#{<<-"end;"}", __FILE__, __LINE__+1)
|
65
|
+
begin;
|
66
|
+
def #{op}(other)
|
67
|
+
case other
|
68
|
+
when PyObjectWrapper
|
69
|
+
LibPython::Helpers.compare(:#{op}, __pyptr__, other.__pyptr__)
|
70
|
+
else
|
71
|
+
other = Conversion.from_ruby(other)
|
72
|
+
LibPython::Helpers.compare(:#{op}, __pyptr__, other)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end;
|
76
|
+
end
|
77
|
+
|
78
|
+
def [](*key)
|
79
|
+
LibPython::Helpers.getitem(__pyptr__, key)
|
80
|
+
end
|
81
|
+
|
82
|
+
def []=(*key, value)
|
83
|
+
LibPython::Helpers.setitem(__pyptr__, key, value)
|
84
|
+
end
|
85
|
+
|
86
|
+
def call(*args)
|
87
|
+
LibPython::Helpers.call_object(__pyptr__, *args)
|
88
|
+
end
|
89
|
+
|
90
|
+
class SwappedOperationAdapter
|
91
|
+
def initialize(obj)
|
92
|
+
@obj = obj
|
93
|
+
end
|
94
|
+
|
95
|
+
attr_reader :obj
|
96
|
+
|
97
|
+
def +(other)
|
98
|
+
other.__radd__(self.obj)
|
99
|
+
end
|
100
|
+
|
101
|
+
def -(other)
|
102
|
+
other.__rsub__(self.obj)
|
103
|
+
end
|
104
|
+
|
105
|
+
def *(other)
|
106
|
+
other.__rmul__(self.obj)
|
107
|
+
end
|
108
|
+
|
109
|
+
def /(other)
|
110
|
+
other.__rtruediv__(self.obj)
|
111
|
+
end
|
112
|
+
|
113
|
+
def %(other)
|
114
|
+
other.__rmod__(self.obj)
|
115
|
+
end
|
116
|
+
|
117
|
+
def **(other)
|
118
|
+
other.__rpow__(self.obj)
|
119
|
+
end
|
120
|
+
|
121
|
+
def <<(other)
|
122
|
+
other.__rlshift__(self.obj)
|
123
|
+
end
|
124
|
+
|
125
|
+
def >>(other)
|
126
|
+
other.__rrshift__(self.obj)
|
127
|
+
end
|
128
|
+
|
129
|
+
def &(other)
|
130
|
+
other.__rand__(self.obj)
|
131
|
+
end
|
132
|
+
|
133
|
+
def ^(other)
|
134
|
+
other.__rxor__(self.obj)
|
135
|
+
end
|
136
|
+
|
137
|
+
def |(other)
|
138
|
+
other.__ror__(self.obj)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def coerce(other)
|
143
|
+
[SwappedOperationAdapter.new(other), self]
|
144
|
+
end
|
145
|
+
|
146
|
+
def dup
|
147
|
+
super.tap do |duped|
|
148
|
+
copied = PyCall.import_module('copy').copy(__pyptr__)
|
149
|
+
copied = copied.__pyptr__ if copied.kind_of? PyObjectWrapper
|
150
|
+
duped.instance_variable_set(:@__pyptr__, copied)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def inspect
|
155
|
+
PyCall.builtins.repr(__pyptr__)
|
156
|
+
end
|
157
|
+
|
158
|
+
def to_s
|
159
|
+
LibPython::Helpers.str(__pyptr__)
|
160
|
+
end
|
161
|
+
|
162
|
+
def to_i
|
163
|
+
LibPython::Helpers.call_object(PyCall::builtins.int.__pyptr__, __pyptr__)
|
164
|
+
end
|
165
|
+
|
166
|
+
def to_f
|
167
|
+
LibPython::Helpers.call_object(PyCall::builtins.float.__pyptr__, __pyptr__)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
module_function
|
172
|
+
|
173
|
+
class WrapperModuleCache < WrapperObjectCache
|
174
|
+
def initialize
|
175
|
+
super(LibPython::API::PyModule_Type)
|
176
|
+
end
|
177
|
+
|
178
|
+
def check_wrapper_object(wrapper_object)
|
179
|
+
unless wrapper_object.kind_of?(Module) && wrapper_object.kind_of?(PyObjectWrapper)
|
180
|
+
raise TypeError, "unexpected type #{wrapper_object.class} (expected Module extended by PyObjectWrapper)"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.instance
|
185
|
+
@instance ||= self.new
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
private_constant :WrapperModuleCache
|
190
|
+
|
191
|
+
def wrap_module(pymodptr)
|
192
|
+
check_ismodule(pymodptr)
|
193
|
+
WrapperModuleCache.instance.lookup(pymodptr) do
|
194
|
+
Module.new do |mod|
|
195
|
+
mod.instance_variable_set(:@__pyptr__, pymodptr)
|
196
|
+
mod.extend PyObjectWrapper
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def check_isclass(pyptr)
|
202
|
+
pyptr = pyptr.__pyptr__ if pyptr.kind_of? PyObjectWrapper
|
203
|
+
return if pyptr.kind_of? LibPython::API::PyType_Type
|
204
|
+
return defined?(LibPython::API::PyClass_Type) && pyptr.kind_of?(LibPython::API::PyClass_Type)
|
205
|
+
raise TypeError, "PyType object is required"
|
206
|
+
end
|
207
|
+
|
208
|
+
def check_ismodule(pyptr)
|
209
|
+
return if pyptr.kind_of? LibPython::API::PyModule_Type
|
210
|
+
raise TypeError, "PyModule object is required"
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import sys
|
2
|
+
|
3
|
+
PY3 = sys.version_info[0] == 3
|
4
|
+
|
5
|
+
if PY3:
|
6
|
+
import builtins
|
7
|
+
else:
|
8
|
+
import __builtin__ as builtins
|
9
|
+
|
10
|
+
if PY3:
|
11
|
+
exec_ = getattr(builtins, 'exec')
|
12
|
+
else:
|
13
|
+
def exec_(_code_, _globals_=None, _locals_=None):
|
14
|
+
"""Execute code in a namespace."""
|
15
|
+
if _globals_ is None:
|
16
|
+
frame = sys._getframe(1)
|
17
|
+
_globals_ = frame.f_globals
|
18
|
+
if _locals_ is None:
|
19
|
+
_locals_ = frame.f_locals
|
20
|
+
del frame
|
21
|
+
elif _locals_ is None:
|
22
|
+
_locals_ = _globals_
|
23
|
+
exec("""exec _code_ in _globals_, _locals_""")
|
@@ -0,0 +1,7 @@
|
|
1
|
+
from distutils.sysconfig import get_config_var
|
2
|
+
import sys
|
3
|
+
for var in ('executable', 'exec_prefix', 'prefix'):
|
4
|
+
print(var + ': ' + str(getattr(sys, var)))
|
5
|
+
print('multiarch: ' + str(getattr(getattr(sys, 'implementation', sys), '_multiarch', None)))
|
6
|
+
for var in ('VERSION', 'INSTSONAME', 'LIBRARY', 'LDLIBRARY', 'LIBDIR', 'PYTHONFRAMEWORKPREFIX', 'MULTIARCH'):
|
7
|
+
print(var + ': ' + str(get_config_var(var)))
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'pycall/pyobject_wrapper'
|
2
|
+
|
3
|
+
module PyCall
|
4
|
+
module PyTypeObjectWrapper
|
5
|
+
include PyObjectWrapper
|
6
|
+
|
7
|
+
def self.extend_object(cls)
|
8
|
+
unless cls.kind_of? Class
|
9
|
+
raise TypeError, "PyTypeObjectWrapper cannot extend non-class objects"
|
10
|
+
end
|
11
|
+
pyptr = cls.instance_variable_get(:@__pyptr__)
|
12
|
+
unless pyptr.kind_of? PyTypePtr
|
13
|
+
raise TypeError, "@__pyptr__ should have PyCall::PyTypePtr object"
|
14
|
+
end
|
15
|
+
super
|
16
|
+
cls.include PyObjectWrapper
|
17
|
+
end
|
18
|
+
|
19
|
+
def inherited(subclass)
|
20
|
+
subclass.instance_variable_set(:@__pyptr__, __pyptr__)
|
21
|
+
end
|
22
|
+
|
23
|
+
def new(*args)
|
24
|
+
wrap_pyptr(LibPython::Helpers.call_object(__pyptr__, *args))
|
25
|
+
end
|
26
|
+
|
27
|
+
def wrap_pyptr(pyptr)
|
28
|
+
return pyptr if pyptr.kind_of? self
|
29
|
+
pyptr = pyptr.__pyptr__ if pyptr.kind_of? PyObjectWrapper
|
30
|
+
unless pyptr.kind_of? PyPtr
|
31
|
+
raise TypeError, "unexpected argument type #{pyptr.class} (expected PyCall::PyPtr)"
|
32
|
+
end
|
33
|
+
unless pyptr.kind_of? __pyptr__
|
34
|
+
raise TypeError, "unexpected argument Python type #{pyptr.__ob_type__.__tp_name__} (expected #{__pyptr__.__tp_name__})"
|
35
|
+
end
|
36
|
+
allocate.tap do |obj|
|
37
|
+
obj.instance_variable_set(:@__pyptr__, pyptr)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def ===(other)
|
42
|
+
case other
|
43
|
+
when PyObjectWrapper
|
44
|
+
__pyptr__ === other.__pyptr__
|
45
|
+
when PyPtr
|
46
|
+
__pyptr__ === other
|
47
|
+
else
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def register_python_type_mapping
|
55
|
+
PyCall::Conversion.register_python_type_mapping(__pyptr__, self)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
module_function
|
60
|
+
|
61
|
+
class WrapperClassCache < WrapperObjectCache
|
62
|
+
def initialize
|
63
|
+
types = [LibPython::API::PyType_Type]
|
64
|
+
types << LibPython::API::PyClass_Type if defined? LibPython::API::PyClass_Type
|
65
|
+
super(*types)
|
66
|
+
end
|
67
|
+
|
68
|
+
def check_wrapper_object(wrapper_object)
|
69
|
+
unless wrapper_object.kind_of?(Class) && wrapper_object.kind_of?(PyTypeObjectWrapper)
|
70
|
+
raise TypeError, "unexpected type #{wrapper_object.class} (expected Class extended by PyTypeObjectWrapper)"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.instance
|
75
|
+
@instance ||= self.new
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private_constant :WrapperClassCache
|
80
|
+
|
81
|
+
def wrap_class(pytypeptr)
|
82
|
+
check_isclass(pytypeptr)
|
83
|
+
WrapperClassCache.instance.lookup(pytypeptr) do
|
84
|
+
Class.new do |cls|
|
85
|
+
cls.instance_variable_set(:@__pyptr__, pytypeptr)
|
86
|
+
cls.extend PyTypeObjectWrapper
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/pycall/set.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module PyCall
|
2
|
+
class Set
|
3
|
+
include PyObjectWrapper
|
4
|
+
|
5
|
+
def initialize(pyobj)
|
6
|
+
super(pyobj)
|
7
|
+
end
|
8
|
+
|
9
|
+
def size
|
10
|
+
LibPython.PySet_Size(__pyobj__)
|
11
|
+
end
|
12
|
+
|
13
|
+
alias length size
|
14
|
+
|
15
|
+
def include?(obj)
|
16
|
+
1 == LibPython.PySet_Contains(__pyobj__, Conversions.from_ruby(obj))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|