pycall 1.4.2 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +3 -16
- data/.github/workflows/windows.yml +2 -3
- data/CHANGES.md +19 -0
- data/README.md +31 -18
- data/ext/pycall/pycall.c +27 -16
- data/lib/pycall/python/investigator.py +1 -1
- data/lib/pycall/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 381593af8570fc0a96f4df77aad616cf93cf86afa336b0be1618ac39c68fdd73
|
4
|
+
data.tar.gz: b1c8075e157dd32d4699ea6ae581d148c4ae537b77f60437a31a1940e31bf8fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a4d26affe26f179752eba471971dfbee4a3336faf7337696dd0cc6cc8b4462e6e8dc27a7bb8d53495178fe2b09fa95c11a6f1da3366a645ac9106248ba5b376
|
7
|
+
data.tar.gz: c72271ccdb5a50f47ced48619468114666e7767ff697ff385968e61e721f7f8449c79d86f218607f1a0fb67ec31ec88f843aeb5cab491fbd481025e3917b9df6
|
data/.github/workflows/ci.yml
CHANGED
@@ -41,14 +41,6 @@ jobs:
|
|
41
41
|
- { os: ubuntu-20.04 , ruby: 2.5 , python: "3.x" , python_architecture: x64 , venv: "" }
|
42
42
|
- { os: ubuntu-20.04 , ruby: 2.4 , python: "3.x" , python_architecture: x64 , venv: "" }
|
43
43
|
|
44
|
-
# The latest Python 2
|
45
|
-
- { os: ubuntu-20.04 , ruby: 3.1 , python: "2.x" , python_architecture: x64 , venv: "" }
|
46
|
-
- { os: ubuntu-20.04 , ruby: 3.0 , python: "2.x" , python_architecture: x64 , venv: "" }
|
47
|
-
- { os: ubuntu-20.04 , ruby: 2.7 , python: "2.x" , python_architecture: x64 , venv: "" }
|
48
|
-
- { os: ubuntu-20.04 , ruby: 2.6 , python: "2.x" , python_architecture: x64 , venv: "" }
|
49
|
-
- { os: ubuntu-20.04 , ruby: 2.5 , python: "2.x" , python_architecture: x64 , venv: "" }
|
50
|
-
- { os: ubuntu-20.04 , ruby: 2.4 , python: "2.x" , python_architecture: x64 , venv: "" }
|
51
|
-
|
52
44
|
# Ruby 2.7 with Each Python 3.x
|
53
45
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.11" , python_architecture: x64 , venv: "" }
|
54
46
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.10" , python_architecture: x64 , venv: "" }
|
@@ -56,17 +48,12 @@ jobs:
|
|
56
48
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.8" , python_architecture: x64 , venv: "" }
|
57
49
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.7" , python_architecture: x64 , venv: "" }
|
58
50
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.6" , python_architecture: x64 , venv: "" }
|
59
|
-
- { os: ubuntu-18.04 , ruby: 2.7 , python: "3.8" , python_architecture: x64 , venv: "" }
|
60
51
|
|
61
52
|
# Ruby-debug with the latest Python 3
|
62
53
|
- { os: ubuntu-20.04 , ruby: debug , python: "3.x" , python_architecture: x64 , venv: "" }
|
63
54
|
|
64
55
|
# Ruby 3.1 with the latest Python 3 with venv
|
65
56
|
- { os: ubuntu-20.04 , ruby: "3.1" , python: "3.x" , python_architecture: x64 , venv: "venv:" }
|
66
|
-
- { os: ubuntu-18.04 , ruby: "3.1" , python: "3.x" , python_architecture: x64 , venv: "venv:" }
|
67
|
-
|
68
|
-
# Ubuntu 18.04 with venv
|
69
|
-
- { os: ubuntu-18.04 , ruby: "3.1" , python: "3.8" , python_architecture: x64 , venv: "venv:" }
|
70
57
|
|
71
58
|
# macOS with venv
|
72
59
|
- { os: macos-latest , ruby: "3.1" , python: "3.x" , python_architecture: x64 , venv: "venv:" }
|
@@ -75,7 +62,7 @@ jobs:
|
|
75
62
|
#- { os: macos-latest , ruby: debug , python: "3.x" , python_architecture: x64 , venv: "" }
|
76
63
|
|
77
64
|
steps:
|
78
|
-
- uses: actions/checkout@
|
65
|
+
- uses: actions/checkout@v3
|
79
66
|
with:
|
80
67
|
fetch-depth: 1
|
81
68
|
|
@@ -84,7 +71,7 @@ jobs:
|
|
84
71
|
with:
|
85
72
|
ruby-version: ${{ matrix.ruby }}
|
86
73
|
|
87
|
-
- uses: actions/setup-python@
|
74
|
+
- uses: actions/setup-python@v4
|
88
75
|
with:
|
89
76
|
python-version: ${{ matrix.python }}
|
90
77
|
architecture: ${{ matrix.python_architecture }}
|
@@ -119,7 +106,7 @@ jobs:
|
|
119
106
|
matrix:
|
120
107
|
os:
|
121
108
|
- ubuntu-20.04
|
122
|
-
|
109
|
+
#- macos-latest
|
123
110
|
ruby:
|
124
111
|
- "3.1"
|
125
112
|
python:
|
@@ -26,7 +26,6 @@ jobs:
|
|
26
26
|
- 2.6
|
27
27
|
python:
|
28
28
|
- 3.x
|
29
|
-
- 2.x
|
30
29
|
python_architecture:
|
31
30
|
- x64
|
32
31
|
include:
|
@@ -34,7 +33,7 @@ jobs:
|
|
34
33
|
#- { os: windows-latest , ruby: mswin , python: 3.x , python_architecture: x64 }
|
35
34
|
|
36
35
|
steps:
|
37
|
-
- uses: actions/checkout@
|
36
|
+
- uses: actions/checkout@v3
|
38
37
|
with:
|
39
38
|
fetch-depth: 1
|
40
39
|
|
@@ -43,7 +42,7 @@ jobs:
|
|
43
42
|
with:
|
44
43
|
ruby-version: ${{ matrix.ruby }}
|
45
44
|
|
46
|
-
- uses: actions/setup-python@
|
45
|
+
- uses: actions/setup-python@v4
|
47
46
|
with:
|
48
47
|
python-version: ${{ matrix.python }}
|
49
48
|
architecture: ${{ matrix.python_architecture }}
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
# The change history of PyCall
|
2
2
|
|
3
|
+
## 1.5.1
|
4
|
+
|
5
|
+
* Fix memory leak in rich compare methods (#167, #168).
|
6
|
+
|
7
|
+
*mknkmyza*
|
8
|
+
|
9
|
+
## 1.5.0
|
10
|
+
|
11
|
+
* Fix to prevent distutils deprecation warning (#159)
|
12
|
+
|
13
|
+
*Christopher Dilks*
|
14
|
+
|
15
|
+
* Drop Python 2.7 support
|
16
|
+
|
17
|
+
* Fix memory leak of Python objects. (#129)
|
18
|
+
This should fixes #128 and maybe also fixes #164.
|
19
|
+
|
20
|
+
*mknkmyza*
|
21
|
+
|
3
22
|
## 1.4.2
|
4
23
|
|
5
24
|
* Add supports of unary operators: `+@`, `-@`, `~`
|
data/README.md
CHANGED
@@ -19,9 +19,7 @@ pycall.rb supports Ruby version 2.4 or higher.
|
|
19
19
|
|
20
20
|
## Supported Python versions
|
21
21
|
|
22
|
-
pycall.rb supports Python version
|
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.
|
22
|
+
pycall.rb supports Python version 3.7 or higher.
|
25
23
|
|
26
24
|
## Note for pyenv users
|
27
25
|
|
@@ -144,9 +142,9 @@ Use [mrkn/pandas.rb](https://github.com/mrkn/pandas.rb) instead of just importin
|
|
144
142
|
|
145
143
|
PyCall wraps pointers of Python objects in `PyCall::PyPtr` objects.
|
146
144
|
`PyCall::PyPtr` class has two subclasses, `PyCall::PyTypePtr` and
|
147
|
-
`PyCall::PyRubyPtr`. `PyCall::PyTypePtr` is specialized for type
|
148
|
-
|
149
|
-
|
145
|
+
`PyCall::PyRubyPtr`. `PyCall::PyTypePtr` is specialized for type objects,
|
146
|
+
and `PyCall::PyRubyPtr` is for the objects that wraps pointers of
|
147
|
+
Ruby objects.
|
150
148
|
|
151
149
|
These `PyCall::PyPtr` objects are used mainly in PyCall infrastructure.
|
152
150
|
Instead, we usually treats the instances of `Object`, `Class`, `Module`, or
|
@@ -162,18 +160,33 @@ translates Ruby's coerce system into Python's swapped operation protocol.
|
|
162
160
|
## Deploying on Heroku
|
163
161
|
|
164
162
|
Heroku's default version of Python is not compiled with the `--enabled-shared`
|
165
|
-
option and can't be accessed by PyCall.
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
163
|
+
option and can't be accessed by PyCall.
|
164
|
+
|
165
|
+
There are many ways to make our heroku use Python that is compiled with the `--enabled-shared` option:
|
166
|
+
|
167
|
+
- use Heroku's official Python buildpacks `post_compile` hooks to recompile the python if the `--enabled-shared` option is not enabled.
|
168
|
+
example script of `post_compile` in ruby on rails app `bin/post_compile`.
|
169
|
+
|
170
|
+
set -e
|
171
|
+
buildpack_url=https://github.com/heroku/heroku-buildpack-python
|
172
|
+
buildpack_vsn=v197 # adjust version accordingly https://github.com/heroku/heroku-buildpack-python/tags
|
173
|
+
|
174
|
+
# rebuild python if it's missing enable-shared
|
175
|
+
if ! python3 -msysconfig | grep enable-shared \
|
176
|
+
> /dev/null; then
|
177
|
+
PYTHON_VERSION="$(< runtime.txt)"
|
178
|
+
git clone -b "$buildpack_vsn" "$buildpack_url" _buildpack
|
179
|
+
export WORKSPACE_DIR="$PWD/_buildpack/builds"
|
180
|
+
rm -f .heroku/python/bin/python # prevent failing ln after build
|
181
|
+
sed -i 's!figure --pre!figure --enable-shared --pre!' \
|
182
|
+
"$WORKSPACE_DIR"/runtimes/python3
|
183
|
+
"$WORKSPACE_DIR/runtimes/$PYTHON_VERSION" /app/.heroku/python/
|
184
|
+
rm -fr _buildpack
|
185
|
+
fi
|
186
|
+
|
187
|
+
- use your own precompiled python with `--enabled-shared` options then fork the official heroku [python buildspacks](https://github.com/heroku/heroku-buildpack-python) and change the `BUILDPACK_S3_BASE_URL` with your own uploaded precompiled python in Amazon's S3.
|
188
|
+
- use 3rd party buildpacks from the [markets](https://elements.heroku.com/buildpacks) that have python with `--enabled-shared` option.
|
189
|
+
|
177
190
|
|
178
191
|
The buildpack will expect to find both a `runtime.txt` and a `requirements.txt`
|
179
192
|
file in the root of your project. You will need to add these to specify the
|
data/ext/pycall/pycall.c
CHANGED
@@ -792,8 +792,9 @@ pycall_libpython_helpers_m_compare(VALUE mod, VALUE op, VALUE pyptr_a, VALUE pyp
|
|
792
792
|
if (!res) {
|
793
793
|
pycall_pyerror_fetch_and_raise("PyObject_RichCompare in pycall_libpython_helpers_m_compare");
|
794
794
|
}
|
795
|
-
|
796
|
-
|
795
|
+
VALUE obj = pycall_pyobject_to_ruby(res);
|
796
|
+
pycall_Py_DecRef(res);
|
797
|
+
return obj;
|
797
798
|
}
|
798
799
|
|
799
800
|
static int is_pyobject_wrapper(VALUE obj);
|
@@ -966,10 +967,10 @@ pycall_extract_kwargs_from_ruby_hash(VALUE key, VALUE value, VALUE arg)
|
|
966
967
|
key_cstr = StringValueCStr(key);
|
967
968
|
pyvalue = pycall_pyobject_from_ruby(value);
|
968
969
|
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
return ST_CONTINUE;
|
970
|
+
int res = Py_API(PyDict_SetItemString)(kwargs, key_cstr, pyvalue);
|
971
|
+
pycall_Py_DecRef(pyvalue);
|
972
|
+
|
973
|
+
return (res < 0) ? ST_STOP : ST_CONTINUE;
|
973
974
|
}
|
974
975
|
|
975
976
|
static void
|
@@ -1061,6 +1062,10 @@ pycall_call_python_callable(PyObject *pycallable, int argc, VALUE *argv)
|
|
1061
1062
|
}
|
1062
1063
|
|
1063
1064
|
res = pyobject_call(pycallable, args, kwargs); /* New reference */
|
1065
|
+
pycall_Py_DecRef(args);
|
1066
|
+
if (kwargs) {
|
1067
|
+
pycall_Py_DecRef(kwargs);
|
1068
|
+
}
|
1064
1069
|
if (!res) {
|
1065
1070
|
pycall_pyerror_fetch_and_raise("PyObject_Call in pycall_call_python_callable");
|
1066
1071
|
}
|
@@ -1099,9 +1104,9 @@ pycall_pyobject_wrapper_wrapper_method(int argc, VALUE *argv, VALUE wrapper)
|
|
1099
1104
|
|
1100
1105
|
name_cstr[RSTRING_LEN(name) - 1] = '\0';
|
1101
1106
|
res = Py_API(PyObject_SetAttrString)(pyobj, name_cstr, attr);
|
1107
|
+
pycall_Py_DecRef(attr);
|
1102
1108
|
name_cstr[RSTRING_LEN(name) - 1] = '=';
|
1103
1109
|
if (res == -1) {
|
1104
|
-
pycall_Py_DecRef(attr);
|
1105
1110
|
pycall_pyerror_fetch_and_raise("PyObject_SetAttrString in pycall_pyobject_wrapper_wrapper_method");
|
1106
1111
|
}
|
1107
1112
|
|
@@ -1119,7 +1124,9 @@ pycall_pyobject_wrapper_wrapper_method(int argc, VALUE *argv, VALUE wrapper)
|
|
1119
1124
|
if (PyType_Check(attr) || PyClass_Check(attr))
|
1120
1125
|
return pycall_pyobject_to_ruby(attr);
|
1121
1126
|
|
1122
|
-
|
1127
|
+
VALUE obj = pycall_call_python_callable(attr, argc, argv);
|
1128
|
+
pycall_Py_DecRef(attr);
|
1129
|
+
return obj;
|
1123
1130
|
}
|
1124
1131
|
|
1125
1132
|
static VALUE
|
@@ -1203,6 +1210,7 @@ pycall_libpython_helpers_m_getitem(VALUE mod, VALUE pyptr, VALUE key)
|
|
1203
1210
|
pyobj_key = pycall_convert_index(key);
|
1204
1211
|
|
1205
1212
|
pyobj_v = Py_API(PyObject_GetItem)(pyobj, pyobj_key);
|
1213
|
+
pycall_Py_DecRef(pyobj_key);
|
1206
1214
|
if (!pyobj_v) {
|
1207
1215
|
pycall_pyerror_fetch_and_raise("PyObject_GetItem in pycall_libpython_helpers_m_getitem");
|
1208
1216
|
}
|
@@ -1223,11 +1231,11 @@ pycall_libpython_helpers_m_setitem(VALUE mod, VALUE pyptr, VALUE key, VALUE v)
|
|
1223
1231
|
pyobj_value = pycall_pyobject_from_ruby(v);
|
1224
1232
|
|
1225
1233
|
res = Py_API(PyObject_SetItem)(pyobj, pyobj_key, pyobj_value);
|
1234
|
+
pycall_Py_DecRef(pyobj_key);
|
1235
|
+
pycall_Py_DecRef(pyobj_value);
|
1226
1236
|
if (res == -1) {
|
1227
1237
|
pycall_pyerror_fetch_and_raise("PyObject_SetItem in pycall_libpython_helpers_m_setitem");
|
1228
1238
|
}
|
1229
|
-
Py_API(Py_DecRef(pyobj_key));
|
1230
|
-
Py_API(Py_DecRef(pyobj_value));
|
1231
1239
|
|
1232
1240
|
return v;
|
1233
1241
|
}
|
@@ -1242,6 +1250,7 @@ pycall_libpython_helpers_m_delitem(VALUE mod, VALUE pyptr, VALUE key)
|
|
1242
1250
|
pyobj_key = pycall_convert_index(key);
|
1243
1251
|
|
1244
1252
|
res = Py_API(PyObject_DelItem)(pyobj, pyobj_key);
|
1253
|
+
pycall_Py_DecRef(pyobj_key);
|
1245
1254
|
if (res == -1) {
|
1246
1255
|
pycall_pyerror_fetch_and_raise("PyObject_DelItem");
|
1247
1256
|
}
|
@@ -1273,6 +1282,7 @@ pycall_libpython_helpers_m_dict_contains(VALUE mod, VALUE pyptr, VALUE key)
|
|
1273
1282
|
pyobj = check_get_pyobj_ptr(pyptr, Py_API(PyDict_Type));
|
1274
1283
|
pyobj_key = pycall_pyobject_from_ruby(key);
|
1275
1284
|
res = Py_API(PyDict_Contains)(pyobj, pyobj_key);
|
1285
|
+
pycall_Py_DecRef(pyobj_key);
|
1276
1286
|
if (res == -1) {
|
1277
1287
|
pycall_pyerror_fetch_and_raise("PyDict_Contains");
|
1278
1288
|
}
|
@@ -1311,6 +1321,7 @@ pycall_libpython_helpers_m_sequence_contains(VALUE mod, VALUE pyptr, VALUE key)
|
|
1311
1321
|
|
1312
1322
|
pyobj_key = pycall_pyobject_from_ruby(key);
|
1313
1323
|
res = Py_API(PySequence_Contains)(pyobj, pyobj_key);
|
1324
|
+
pycall_Py_DecRef(pyobj_key);
|
1314
1325
|
if (res == -1) {
|
1315
1326
|
pycall_pyerror_fetch_and_raise("PySequence_Contains");
|
1316
1327
|
}
|
@@ -1708,6 +1719,7 @@ pycall_pytuple_to_a(PyObject *pyobj)
|
|
1708
1719
|
PyObject *pytem = Py_API(PyTuple_GetItem)(pyobj, i);
|
1709
1720
|
Py_API(Py_IncRef)(pytem);
|
1710
1721
|
rb_ary_push(ary, pycall_pyobject_to_ruby(pytem));
|
1722
|
+
pycall_Py_DecRef(pytem);
|
1711
1723
|
}
|
1712
1724
|
|
1713
1725
|
return ary;
|
@@ -1726,6 +1738,7 @@ pycall_pysequence_to_a(PyObject *pyobj)
|
|
1726
1738
|
for (i = 0; i < n; ++i) {
|
1727
1739
|
PyObject *pytem = Py_API(PySequence_GetItem)(pyobj, i);
|
1728
1740
|
rb_ary_push(ary, pycall_pyobject_to_ruby(pytem));
|
1741
|
+
pycall_Py_DecRef(pytem);
|
1729
1742
|
}
|
1730
1743
|
|
1731
1744
|
return ary;
|
@@ -1938,12 +1951,10 @@ pycall_pydict_from_ruby_iter(VALUE key, VALUE value, VALUE arg)
|
|
1938
1951
|
pyobj_key = pycall_pyobject_from_ruby(key);
|
1939
1952
|
pyobj_value = pycall_pyobject_from_ruby(value);
|
1940
1953
|
res = Py_API(PyObject_SetItem)(pydictobj, pyobj_key, pyobj_value);
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
Py_API(Py_DecRef)(pyobj_value);
|
1946
|
-
return ST_CONTINUE;
|
1954
|
+
pycall_Py_DecRef(pyobj_key);
|
1955
|
+
pycall_Py_DecRef(pyobj_value);
|
1956
|
+
|
1957
|
+
return (res == -1) ? ST_STOP : ST_CONTINUE;
|
1947
1958
|
}
|
1948
1959
|
|
1949
1960
|
PyObject *
|
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.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenta Murata
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -221,7 +221,7 @@ homepage: https://github.com/mrkn/pycall
|
|
221
221
|
licenses:
|
222
222
|
- MIT
|
223
223
|
metadata: {}
|
224
|
-
post_install_message:
|
224
|
+
post_install_message:
|
225
225
|
rdoc_options: []
|
226
226
|
require_paths:
|
227
227
|
- lib
|
@@ -236,8 +236,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
236
|
- !ruby/object:Gem::Version
|
237
237
|
version: '0'
|
238
238
|
requirements: []
|
239
|
-
rubygems_version: 3.3.
|
240
|
-
signing_key:
|
239
|
+
rubygems_version: 3.3.7
|
240
|
+
signing_key:
|
241
241
|
specification_version: 4
|
242
242
|
summary: pycall
|
243
243
|
test_files: []
|