pycall 1.1.0.rc1 → 1.2.0.beta1
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 +0 -4
- data/CHANGES.md +10 -0
- data/README.md +15 -0
- data/ext/pycall/libpython.c +1 -0
- data/ext/pycall/pycall.c +45 -2
- data/ext/pycall/pycall_internal.h +1 -0
- data/ext/pycall/ruby_wrapper.c +1 -0
- data/images/pycallrb_logo.png +0 -0
- data/images/pycallrb_logo_200.png +0 -0
- data/lib/pycall/libpython/finder.rb +19 -17
- data/lib/pycall/pytypeobject_wrapper.rb +9 -0
- data/lib/pycall/version.rb +1 -1
- metadata +5 -5
- data/lib/pycall/conversion.rb +0 -173
- data/lib/pycall/tuple.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz: '
|
3
|
+
metadata.gz: 4ee819add9bcf3e4c3a3fb4f4fdc7b94abe6ccf1a969a8aabe9bd7edf9aa6701
|
4
|
+
data.tar.gz: '03839cbba19832eca0cf90ee7e85cf4cd953f2f5bba2dd12bcc9005097393482'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d22a8905b5d7c9f9f2793fd8bb0ed003fa418ab35f8048faced61145d577502571ab0d0bbfb187bb689ee59f8e99539b3de9789d4905584340041e801e951c0f
|
7
|
+
data.tar.gz: d382691fcdd3995347d126ff70fa0dfc1e877b9136bfce4ca6ac6d783aa7802da544250b03601ae9d335ae4fd9c72af15ab412450e14c2d20a05a29b16b58763
|
data/.travis.yml
CHANGED
@@ -10,8 +10,6 @@ rvm:
|
|
10
10
|
- 2.5.0
|
11
11
|
- 2.4.3
|
12
12
|
- 2.3.5
|
13
|
-
- 2.2.9
|
14
|
-
- 2.1.10
|
15
13
|
|
16
14
|
env:
|
17
15
|
global:
|
@@ -42,8 +40,6 @@ matrix:
|
|
42
40
|
env: PYENV_VERSION=miniconda3-4.3.11
|
43
41
|
allow_failures:
|
44
42
|
- os: osx
|
45
|
-
- rvm: 2.2.9
|
46
|
-
- rvm: 2.1.10
|
47
43
|
|
48
44
|
before_install:
|
49
45
|
- gem update --system
|
data/CHANGES.md
CHANGED
@@ -22,6 +22,16 @@
|
|
22
22
|
|
23
23
|
*Kouhei Sutou*
|
24
24
|
|
25
|
+
* Support multiple candidates of Python command in `PyCall.init`
|
26
|
+
|
27
|
+
* Now, `PyCall.init` tries `python3` command before `python` in default
|
28
|
+
|
29
|
+
* Drop Ruby 2.2 and 2.1 supports
|
30
|
+
|
31
|
+
* Add `PyCall::PyTypeObjectWrapper#<` as `Class#<`
|
32
|
+
|
33
|
+
* Support class inheritance in python type mapping
|
34
|
+
|
25
35
|
## 1.0.3
|
26
36
|
|
27
37
|
* Fix anaconda support to define the environment variable `PYTHONHOME`.
|
data/README.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
<a name="logo"/>
|
2
|
+
<div align="center">
|
3
|
+
<img src="./images/pycallrb_logo_200.png" alt="pycall.rb logo" width="200" height="200"></img>
|
4
|
+
</div>
|
5
|
+
|
1
6
|
# PyCall: Calling Python functions from the Ruby language
|
2
7
|
|
3
8
|
[](https://travis-ci.org/mrkn/pycall.rb)
|
@@ -8,6 +13,16 @@ with Python from the Ruby language. You can import arbitrary Python modules
|
|
8
13
|
into Ruby modules, call Python functions with automatic type conversion from
|
9
14
|
Ruby to Python.
|
10
15
|
|
16
|
+
## Supported Ruby versions
|
17
|
+
|
18
|
+
pycall.rb supports Ruby version 2.3 or higher.
|
19
|
+
|
20
|
+
## Supported Python versions
|
21
|
+
|
22
|
+
pycall.rb supports Python version 2.7 or higher.
|
23
|
+
|
24
|
+
Note that in Python 2.7 old-style class, that is defined without a super class, is not fully supported in pycall.rb.
|
25
|
+
|
11
26
|
## Installation
|
12
27
|
|
13
28
|
Add this line to your application's Gemfile:
|
data/ext/pycall/libpython.c
CHANGED
@@ -94,6 +94,7 @@ pycall_init_libpython_api_table(VALUE libpython_handle)
|
|
94
94
|
INIT_API_TABLE_ENTRY(_PyObject_New, required);
|
95
95
|
INIT_API_TABLE_ENTRY(PyCallable_Check, required);
|
96
96
|
INIT_API_TABLE_ENTRY(PyObject_IsInstance, required);
|
97
|
+
INIT_API_TABLE_ENTRY(PyObject_IsSubclass, required);
|
97
98
|
INIT_API_TABLE_ENTRY2(PyObject_Hash._hash_t, PyObject_Hash, required);
|
98
99
|
INIT_API_TABLE_ENTRY(PyObject_RichCompare, required);
|
99
100
|
INIT_API_TABLE_ENTRY(PyObject_Call, required);
|
data/ext/pycall/pycall.c
CHANGED
@@ -452,7 +452,7 @@ get_pytypeobj_ptr(VALUE obj)
|
|
452
452
|
static inline PyTypeObject*
|
453
453
|
try_get_pytypeobj_ptr(VALUE obj)
|
454
454
|
{
|
455
|
-
if (is_pycall_pytypeptr(obj)) return NULL;
|
455
|
+
if (!is_pycall_pytypeptr(obj)) return NULL;
|
456
456
|
return (PyTypeObject*)DATA_PTR(obj);
|
457
457
|
}
|
458
458
|
|
@@ -541,6 +541,20 @@ pycall_pytypeptr_eqq(VALUE obj, VALUE other)
|
|
541
541
|
return Qfalse;
|
542
542
|
}
|
543
543
|
|
544
|
+
static VALUE
|
545
|
+
pycall_pytypeptr_subclass_p(VALUE obj, VALUE other)
|
546
|
+
{
|
547
|
+
PyTypeObject* pytype = get_pytypeobj_ptr(obj);
|
548
|
+
if (is_pycall_pyptr(other)) {
|
549
|
+
PyTypeObject* pytype_other = try_get_pytypeobj_ptr(other);
|
550
|
+
if (pytype_other) {
|
551
|
+
int res = Py_API(PyObject_IsSubclass)((PyObject *)pytype, (PyObject *)pytype_other);
|
552
|
+
return res ? Qtrue : Qfalse;
|
553
|
+
}
|
554
|
+
}
|
555
|
+
return Qfalse;
|
556
|
+
}
|
557
|
+
|
544
558
|
/* ==== PyCall::LibPython::API ==== */
|
545
559
|
|
546
560
|
static VALUE
|
@@ -1277,11 +1291,39 @@ pycall_pyobject_wrapper_check_get_pyobj_ptr(VALUE obj, PyTypeObject *pytypeobj)
|
|
1277
1291
|
|
1278
1292
|
/* ==== PyCall::Conversion ==== */
|
1279
1293
|
|
1294
|
+
static int
|
1295
|
+
get_mapped_ancestor_class_iter(VALUE key, VALUE value, VALUE arg)
|
1296
|
+
{
|
1297
|
+
VALUE *args = (VALUE *)arg;
|
1298
|
+
if (RTEST(pycall_pytypeptr_subclass_p(args[0], key))) {
|
1299
|
+
args[1] = value;
|
1300
|
+
return ST_STOP;
|
1301
|
+
}
|
1302
|
+
return ST_CONTINUE;
|
1303
|
+
}
|
1304
|
+
|
1305
|
+
static VALUE
|
1306
|
+
pycall_python_type_mapping_get_mapped_ancestor_class(VALUE pytypeptr)
|
1307
|
+
{
|
1308
|
+
VALUE args[2];
|
1309
|
+
args[0] = pytypeptr;
|
1310
|
+
args[1] = Qnil;
|
1311
|
+
|
1312
|
+
rb_hash_foreach(python_type_mapping, get_mapped_ancestor_class_iter, (VALUE)args);
|
1313
|
+
|
1314
|
+
return args[1];
|
1315
|
+
}
|
1316
|
+
|
1280
1317
|
static VALUE
|
1281
1318
|
pycall_python_type_mapping_get_mapped_class(VALUE pytypeptr)
|
1282
1319
|
{
|
1320
|
+
VALUE mapped;
|
1283
1321
|
(void)check_get_pytypeobj_ptr(pytypeptr);
|
1284
|
-
|
1322
|
+
mapped = rb_hash_lookup(python_type_mapping, pytypeptr);
|
1323
|
+
if (NIL_P(mapped)) {
|
1324
|
+
mapped = pycall_python_type_mapping_get_mapped_ancestor_class(pytypeptr);
|
1325
|
+
}
|
1326
|
+
return mapped;
|
1285
1327
|
}
|
1286
1328
|
|
1287
1329
|
static int
|
@@ -2179,6 +2221,7 @@ Init_pycall(void)
|
|
2179
2221
|
rb_define_method(cPyTypePtr, "__tp_basicsize__", pycall_pytypeptr_get_tp_basicsize, 0);
|
2180
2222
|
rb_define_method(cPyTypePtr, "__tp_flags__", pycall_pytypeptr_get_tp_flags, 0);
|
2181
2223
|
rb_define_method(cPyTypePtr, "===", pycall_pytypeptr_eqq, 1);
|
2224
|
+
rb_define_method(cPyTypePtr, "<", pycall_pytypeptr_subclass_p, 1);
|
2182
2225
|
|
2183
2226
|
/* PyCall::LibPython::API */
|
2184
2227
|
|
@@ -529,6 +529,7 @@ typedef struct {
|
|
529
529
|
PyObject * (* _PyObject_New)(PyTypeObject *);
|
530
530
|
int (* PyCallable_Check)(PyObject *);
|
531
531
|
int (* PyObject_IsInstance)(PyObject *, PyObject *);
|
532
|
+
int (* PyObject_IsSubclass)(PyObject *, PyObject *);
|
532
533
|
union {
|
533
534
|
long (* _long)(PyObject *);
|
534
535
|
Py_hash_t (* _hash_t)(PyObject *);
|
data/ext/pycall/ruby_wrapper.c
CHANGED
Binary file
|
Binary file
|
@@ -19,25 +19,26 @@ module PyCall
|
|
19
19
|
LIBSUFFIX = libsuffix || 'so'
|
20
20
|
|
21
21
|
class << self
|
22
|
+
DEFAULT_PYTHON = [
|
23
|
+
-'python3',
|
24
|
+
-'python',
|
25
|
+
].freeze
|
26
|
+
|
27
|
+
def find_python_config(python = nil)
|
28
|
+
python ||= DEFAULT_PYTHON
|
29
|
+
Array(python).each do |python_cmd|
|
30
|
+
python_config = investigate_python_config(python_cmd)
|
31
|
+
return [python_cmd, python_config] unless python_config.empty?
|
32
|
+
end
|
33
|
+
rescue
|
34
|
+
raise ::PyCall::PythonNotFound
|
35
|
+
else
|
36
|
+
raise ::PyCall::PythonNotFound
|
37
|
+
end
|
38
|
+
|
22
39
|
def find_libpython(python = nil)
|
23
40
|
debug_report("find_libpython(#{python.inspect})")
|
24
|
-
|
25
|
-
begin
|
26
|
-
python_config = investigate_python_config(python)
|
27
|
-
rescue
|
28
|
-
raise ::PyCall::PythonNotFound
|
29
|
-
end
|
30
|
-
else
|
31
|
-
%w[python python3].each do |python_cmd|
|
32
|
-
begin
|
33
|
-
python_config = investigate_python_config(python_cmd)
|
34
|
-
python = python_cmd
|
35
|
-
break
|
36
|
-
rescue
|
37
|
-
raise ::PyCall::PythonNotFound
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
+
python, python_config = find_python_config(python)
|
41
42
|
|
42
43
|
set_PYTHONHOME(python_config)
|
43
44
|
libs = make_libs(python_config)
|
@@ -101,6 +102,7 @@ module PyCall
|
|
101
102
|
IO.popen(python_env, [python, python_investigator_py], 'r') do |io|
|
102
103
|
{}.tap do |config|
|
103
104
|
io.each_line do |line|
|
105
|
+
next unless line =~ /: /
|
104
106
|
key, value = line.chomp.split(': ', 2)
|
105
107
|
case value
|
106
108
|
when 'True', 'true', 'False', 'false'
|
@@ -49,6 +49,15 @@ module PyCall
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
def <(other)
|
53
|
+
case other
|
54
|
+
when PyTypeObjectWrapper
|
55
|
+
__pyptr__ < other.__pyptr__
|
56
|
+
else
|
57
|
+
raise TypeError, "compared with non class/module"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
52
61
|
private
|
53
62
|
|
54
63
|
def register_python_type_mapping
|
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: 1.
|
4
|
+
version: 1.2.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenta Murata
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -171,8 +171,9 @@ files:
|
|
171
171
|
- ext/pycall/pycall_internal.h
|
172
172
|
- ext/pycall/range.c
|
173
173
|
- ext/pycall/ruby_wrapper.c
|
174
|
+
- images/pycallrb_logo.png
|
175
|
+
- images/pycallrb_logo_200.png
|
174
176
|
- lib/pycall.rb
|
175
|
-
- lib/pycall/conversion.rb
|
176
177
|
- lib/pycall/dict.rb
|
177
178
|
- lib/pycall/error.rb
|
178
179
|
- lib/pycall/gc_guard.rb
|
@@ -193,7 +194,6 @@ files:
|
|
193
194
|
- lib/pycall/pytypeobject_wrapper.rb
|
194
195
|
- lib/pycall/set.rb
|
195
196
|
- lib/pycall/slice.rb
|
196
|
-
- lib/pycall/tuple.rb
|
197
197
|
- lib/pycall/version.rb
|
198
198
|
- lib/pycall/wrapper_object_cache.rb
|
199
199
|
- pycall.gemspec
|
@@ -219,7 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
219
219
|
version: 1.3.1
|
220
220
|
requirements: []
|
221
221
|
rubyforge_project:
|
222
|
-
rubygems_version: 2.7.
|
222
|
+
rubygems_version: 2.7.6
|
223
223
|
signing_key:
|
224
224
|
specification_version: 4
|
225
225
|
summary: pycall
|
data/lib/pycall/conversion.rb
DELETED
@@ -1,173 +0,0 @@
|
|
1
|
-
module PyCall
|
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.each_type_pair
|
12
|
-
i, n = 1, @python_type_map.length
|
13
|
-
while i <= n
|
14
|
-
yield @python_type_map[n - i]
|
15
|
-
i += 1
|
16
|
-
end
|
17
|
-
self
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.python_type_mapping(pytype, rbtype)
|
21
|
-
each_type_pair do |type_pair|
|
22
|
-
next unless pytype == type_pair.pytype
|
23
|
-
type_pair.rbtype = rbtype
|
24
|
-
return
|
25
|
-
end
|
26
|
-
@python_type_map << TypePair.new(pytype, rbtype)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Convert a PyCall::PyObjectStruct object to a Ruby object
|
30
|
-
#
|
31
|
-
# @param [PyCall::PyObjectStruct] pyptr a PyObjectStruct object.
|
32
|
-
#
|
33
|
-
# @return a Ruby object converted from `pyptr`.
|
34
|
-
def self.to_ruby(pyptr)
|
35
|
-
return nil if pyptr.null? || pyptr.none?
|
36
|
-
|
37
|
-
case
|
38
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyType_Type)
|
39
|
-
return TypeObject.new(pyptr)
|
40
|
-
|
41
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyBool_Type)
|
42
|
-
return Conversions.convert_to_boolean(pyptr)
|
43
|
-
|
44
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyInt_Type)
|
45
|
-
return Conversions.convert_to_integer(pyptr)
|
46
|
-
|
47
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyLong_Type)
|
48
|
-
# TODO: should make Bignum
|
49
|
-
|
50
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyFloat_Type)
|
51
|
-
return Conversions.convert_to_float(pyptr)
|
52
|
-
|
53
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyComplex_Type)
|
54
|
-
return Conversions.convert_to_complex(pyptr)
|
55
|
-
|
56
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyString_Type)
|
57
|
-
return Conversions.convert_to_string(pyptr)
|
58
|
-
|
59
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyUnicode_Type)
|
60
|
-
py_str_ptr = LibPython.PyUnicode_AsUTF8String(pyptr)
|
61
|
-
return Conversions.convert_to_string(py_str_ptr).force_encoding(Encoding::UTF_8)
|
62
|
-
|
63
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyList_Type)
|
64
|
-
return PyCall::List.new(pyptr)
|
65
|
-
|
66
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyTuple_Type)
|
67
|
-
return Conversions.convert_to_tuple(pyptr)
|
68
|
-
|
69
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PyDict_Type)
|
70
|
-
return PyCall::Dict.new(pyptr)
|
71
|
-
|
72
|
-
when PyCall::Types.pyisinstance(pyptr, LibPython.PySet_Type)
|
73
|
-
return PyCall::Set.new(pyptr)
|
74
|
-
end
|
75
|
-
|
76
|
-
pyobj = PyObject.new(pyptr)
|
77
|
-
each_type_pair do |tp|
|
78
|
-
pytype, rbtype = tp.to_a
|
79
|
-
next unless pyobj.kind_of?(pytype)
|
80
|
-
case
|
81
|
-
when rbtype.kind_of?(Proc)
|
82
|
-
return rbtype.(pyobj)
|
83
|
-
when rbtype.respond_to?(:from_python)
|
84
|
-
return rbtype.from_python(pyobj)
|
85
|
-
else
|
86
|
-
return rbtype.new(pyobj)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
pyobj
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.from_ruby(obj)
|
93
|
-
case obj
|
94
|
-
when LibPython::PyObjectStruct
|
95
|
-
obj
|
96
|
-
when PyObject, PyObjectWrapper
|
97
|
-
obj.__pyobj__
|
98
|
-
when TrueClass, FalseClass
|
99
|
-
LibPython.PyBool_FromLong(obj ? 1 : 0)
|
100
|
-
when Integer
|
101
|
-
LibPython.PyInt_FromSsize_t(obj)
|
102
|
-
when Float
|
103
|
-
LibPython.PyFloat_FromDouble(obj)
|
104
|
-
when String
|
105
|
-
if obj.encoding != Encoding::BINARY && (PyCall.unicode_literals? || !obj.ascii_only?)
|
106
|
-
obj = obj.encode(Encoding::UTF_8) if obj.encoding != Encoding::UTF_8
|
107
|
-
return LibPython.PyUnicode_DecodeUTF8(obj, obj.bytesize, nil)
|
108
|
-
end
|
109
|
-
LibPython.PyString_FromStringAndSize(obj, obj.bytesize)
|
110
|
-
when Symbol
|
111
|
-
from_ruby(obj.to_s)
|
112
|
-
when Array
|
113
|
-
PyCall::List.new(obj).__pyobj__
|
114
|
-
when Hash
|
115
|
-
PyCall::Dict.new(obj).__pyobj__
|
116
|
-
when Proc
|
117
|
-
PyCall.wrap_ruby_callable(obj)
|
118
|
-
else
|
119
|
-
PyCall.None
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def self.convert_to_boolean(py_obj)
|
124
|
-
0 != LibPython.PyInt_AsSsize_t(py_obj)
|
125
|
-
end
|
126
|
-
|
127
|
-
def self.convert_to_integer(py_obj)
|
128
|
-
LibPython.PyInt_AsSsize_t(py_obj)
|
129
|
-
end
|
130
|
-
|
131
|
-
def self.convert_to_float(py_obj)
|
132
|
-
LibPython.PyFloat_AsDouble(py_obj)
|
133
|
-
end
|
134
|
-
|
135
|
-
def self.convert_to_complex(py_obj)
|
136
|
-
real = LibPython.PyComplex_RealAsDouble(py_obj)
|
137
|
-
imag = LibPython.PyComplex_ImagAsDouble(py_obj)
|
138
|
-
Complex(real, imag)
|
139
|
-
end
|
140
|
-
|
141
|
-
def self.convert_to_string(py_obj)
|
142
|
-
FFI::MemoryPointer.new(:string) do |str_ptr|
|
143
|
-
FFI::MemoryPointer.new(:int) do |len_ptr|
|
144
|
-
res = LibPython.PyString_AsStringAndSize(py_obj, str_ptr, len_ptr)
|
145
|
-
return nil if res == -1 # FIXME: error
|
146
|
-
|
147
|
-
len = len_ptr.get(:int, 0)
|
148
|
-
return str_ptr.get_pointer(0).read_string(len)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def self.convert_to_array(py_obj, force_list: true, array_class: Array)
|
154
|
-
case
|
155
|
-
when force_list || py_obj.kind_of?(LibPython.PyList_Type)
|
156
|
-
len = LibPython.PySequence_Size(py_obj)
|
157
|
-
array_class.new(len) do |i|
|
158
|
-
LibPython.PySequence_GetItem(py_obj, i).to_ruby
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
def self.convert_to_tuple(py_obj)
|
164
|
-
PyCall::Tuple.new(py_obj)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
class LibPython::PyObjectStruct
|
169
|
-
def to_ruby
|
170
|
-
Conversions.to_ruby(self)
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
data/lib/pycall/tuple.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
module PyCall
|
2
|
-
class Tuple
|
3
|
-
include PyObjectWrapper
|
4
|
-
|
5
|
-
def self.new(init)
|
6
|
-
case init
|
7
|
-
when Integer
|
8
|
-
super(LibPython.PyTuple_New(init))
|
9
|
-
when Array
|
10
|
-
tuple = new(init.length)
|
11
|
-
init.each_with_index do |obj, index|
|
12
|
-
tuple[index] = obj
|
13
|
-
end
|
14
|
-
tuple
|
15
|
-
when LibPython::PyObjectStruct
|
16
|
-
super(init)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# Make tuple from array
|
21
|
-
def self.[](*ary)
|
22
|
-
new(ary)
|
23
|
-
end
|
24
|
-
|
25
|
-
def size
|
26
|
-
LibPython.PyTuple_Size(__pyobj__)
|
27
|
-
end
|
28
|
-
|
29
|
-
alias length size
|
30
|
-
|
31
|
-
def [](index)
|
32
|
-
LibPython.PyTuple_GetItem(__pyobj__, index).to_ruby
|
33
|
-
end
|
34
|
-
|
35
|
-
def []=(index, value)
|
36
|
-
value = Conversions.from_ruby(value)
|
37
|
-
LibPython.PyTuple_SetItem(__pyobj__, index, value)
|
38
|
-
end
|
39
|
-
|
40
|
-
def to_a
|
41
|
-
Array.new(length) {|i| self[i] }
|
42
|
-
end
|
43
|
-
|
44
|
-
alias to_ary to_a
|
45
|
-
end
|
46
|
-
end
|