pycall 1.1.0.rc1 → 1.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/mrkn/pycall.rb.svg?branch=master)](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
|