pycall 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b2526ea3050985dc6d864e979804fb4ebaa9c36d8239b48809a9cd31dd01de5
4
- data.tar.gz: 68df5fcac7fd5c574009ebbc33f0d9c1724ff8d5057d4dfaa69832b8509e4a92
3
+ metadata.gz: 7b2f11d56347f0f7a8977916c73468aa165a23350ed271e7cdb064341211aabb
4
+ data.tar.gz: 0d4c68470567e1a2d58d2512f8ca883dfaca1329f4d89a255d0917f3b2c85f7b
5
5
  SHA512:
6
- metadata.gz: c52cd3ac7b709238a1b3ec95ed7eb45bcfaa5ef8a40b74f8de15cec928350152769c915250f27290e1b7f2bfb84032faa3a39837d0598c2927a114f6989f11dc
7
- data.tar.gz: 6c45f609e09251815588b0a02095af9d221e2c715d4e614d16888326fc46c6158a631b6cc514d9b3e673468abf2834e003074a5e77f27b46098c5ab698328459
6
+ metadata.gz: dd61f72199c6986c9bbe5260a7f43c92a6e8ef2036a4fb94c2d3ff14a74c1b21a306f601e6ccee73dd709fb76cc48b24af1002a3b95cbe18ecc7604015f8e028
7
+ data.tar.gz: 4040cec7aa67bb7edf1a8f07896e6c7b62b971b7e15a78171d8424465087dff5b25e8bedd0971f9c2060944712f1b14905605e9261933f480162a87f2bbd925b
@@ -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@v2
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@v2
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
- - macos-latest
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@v2
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@v2
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,18 @@
1
1
  # The change history of PyCall
2
2
 
3
+ ## 1.5.0
4
+
5
+ * Fix to prevent distutils deprecation warning (#159)
6
+
7
+ *Christopher Dilks*
8
+
9
+ * Drop Python 2.7 support
10
+
11
+ * Fix memory leak of Python objects. (#129)
12
+ This should fixes #128 and maybe also fixes #164.
13
+
14
+ *mknkmyza*
15
+
3
16
  ## 1.4.2
4
17
 
5
18
  * 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 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.
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 (and classobj
148
- in 2.7) objects, and `PyCall::PyRubyPtr` is for the objects that wraps pointers
149
- of Ruby objects.
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. Alternative [buildpacks](https://devcenter.heroku.com/articles/buildpacks) are available,
166
- including these that have been reported to work with PyCall:
167
-
168
- https://github.com/richgong/heroku-buildpack-python
169
- https://github.com/dsounded/heroku-buildpack-python
170
- https://github.com/ReforgeHQ/heroku-buildpack-python
171
-
172
- These community-developed buildpacks are not supported by Heroku, so it's
173
- worth examining the source to make sure the buildpack you use suits your
174
- needs. For instance, 'ReforgeHQ' works well with Python 3.8.1, but has not
175
- been configured to work with other versions and may not be as generally
176
- useful as the 'dsounded' or 'richgong' buildpacks.
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
@@ -966,10 +966,10 @@ pycall_extract_kwargs_from_ruby_hash(VALUE key, VALUE value, VALUE arg)
966
966
  key_cstr = StringValueCStr(key);
967
967
  pyvalue = pycall_pyobject_from_ruby(value);
968
968
 
969
- if (Py_API(PyDict_SetItemString)(kwargs, key_cstr, pyvalue) < 0) {
970
- return ST_STOP;
971
- }
972
- return ST_CONTINUE;
969
+ int res = Py_API(PyDict_SetItemString)(kwargs, key_cstr, pyvalue);
970
+ pycall_Py_DecRef(pyvalue);
971
+
972
+ return (res < 0) ? ST_STOP : ST_CONTINUE;
973
973
  }
974
974
 
975
975
  static void
@@ -1061,6 +1061,10 @@ pycall_call_python_callable(PyObject *pycallable, int argc, VALUE *argv)
1061
1061
  }
1062
1062
 
1063
1063
  res = pyobject_call(pycallable, args, kwargs); /* New reference */
1064
+ pycall_Py_DecRef(args);
1065
+ if (kwargs) {
1066
+ pycall_Py_DecRef(kwargs);
1067
+ }
1064
1068
  if (!res) {
1065
1069
  pycall_pyerror_fetch_and_raise("PyObject_Call in pycall_call_python_callable");
1066
1070
  }
@@ -1099,9 +1103,9 @@ pycall_pyobject_wrapper_wrapper_method(int argc, VALUE *argv, VALUE wrapper)
1099
1103
 
1100
1104
  name_cstr[RSTRING_LEN(name) - 1] = '\0';
1101
1105
  res = Py_API(PyObject_SetAttrString)(pyobj, name_cstr, attr);
1106
+ pycall_Py_DecRef(attr);
1102
1107
  name_cstr[RSTRING_LEN(name) - 1] = '=';
1103
1108
  if (res == -1) {
1104
- pycall_Py_DecRef(attr);
1105
1109
  pycall_pyerror_fetch_and_raise("PyObject_SetAttrString in pycall_pyobject_wrapper_wrapper_method");
1106
1110
  }
1107
1111
 
@@ -1119,7 +1123,9 @@ pycall_pyobject_wrapper_wrapper_method(int argc, VALUE *argv, VALUE wrapper)
1119
1123
  if (PyType_Check(attr) || PyClass_Check(attr))
1120
1124
  return pycall_pyobject_to_ruby(attr);
1121
1125
 
1122
- return pycall_call_python_callable(attr, argc, argv);
1126
+ VALUE obj = pycall_call_python_callable(attr, argc, argv);
1127
+ pycall_Py_DecRef(attr);
1128
+ return obj;
1123
1129
  }
1124
1130
 
1125
1131
  static VALUE
@@ -1203,6 +1209,7 @@ pycall_libpython_helpers_m_getitem(VALUE mod, VALUE pyptr, VALUE key)
1203
1209
  pyobj_key = pycall_convert_index(key);
1204
1210
 
1205
1211
  pyobj_v = Py_API(PyObject_GetItem)(pyobj, pyobj_key);
1212
+ pycall_Py_DecRef(pyobj_key);
1206
1213
  if (!pyobj_v) {
1207
1214
  pycall_pyerror_fetch_and_raise("PyObject_GetItem in pycall_libpython_helpers_m_getitem");
1208
1215
  }
@@ -1223,11 +1230,11 @@ pycall_libpython_helpers_m_setitem(VALUE mod, VALUE pyptr, VALUE key, VALUE v)
1223
1230
  pyobj_value = pycall_pyobject_from_ruby(v);
1224
1231
 
1225
1232
  res = Py_API(PyObject_SetItem)(pyobj, pyobj_key, pyobj_value);
1233
+ pycall_Py_DecRef(pyobj_key);
1234
+ pycall_Py_DecRef(pyobj_value);
1226
1235
  if (res == -1) {
1227
1236
  pycall_pyerror_fetch_and_raise("PyObject_SetItem in pycall_libpython_helpers_m_setitem");
1228
1237
  }
1229
- Py_API(Py_DecRef(pyobj_key));
1230
- Py_API(Py_DecRef(pyobj_value));
1231
1238
 
1232
1239
  return v;
1233
1240
  }
@@ -1242,6 +1249,7 @@ pycall_libpython_helpers_m_delitem(VALUE mod, VALUE pyptr, VALUE key)
1242
1249
  pyobj_key = pycall_convert_index(key);
1243
1250
 
1244
1251
  res = Py_API(PyObject_DelItem)(pyobj, pyobj_key);
1252
+ pycall_Py_DecRef(pyobj_key);
1245
1253
  if (res == -1) {
1246
1254
  pycall_pyerror_fetch_and_raise("PyObject_DelItem");
1247
1255
  }
@@ -1273,6 +1281,7 @@ pycall_libpython_helpers_m_dict_contains(VALUE mod, VALUE pyptr, VALUE key)
1273
1281
  pyobj = check_get_pyobj_ptr(pyptr, Py_API(PyDict_Type));
1274
1282
  pyobj_key = pycall_pyobject_from_ruby(key);
1275
1283
  res = Py_API(PyDict_Contains)(pyobj, pyobj_key);
1284
+ pycall_Py_DecRef(pyobj_key);
1276
1285
  if (res == -1) {
1277
1286
  pycall_pyerror_fetch_and_raise("PyDict_Contains");
1278
1287
  }
@@ -1311,6 +1320,7 @@ pycall_libpython_helpers_m_sequence_contains(VALUE mod, VALUE pyptr, VALUE key)
1311
1320
 
1312
1321
  pyobj_key = pycall_pyobject_from_ruby(key);
1313
1322
  res = Py_API(PySequence_Contains)(pyobj, pyobj_key);
1323
+ pycall_Py_DecRef(pyobj_key);
1314
1324
  if (res == -1) {
1315
1325
  pycall_pyerror_fetch_and_raise("PySequence_Contains");
1316
1326
  }
@@ -1708,6 +1718,7 @@ pycall_pytuple_to_a(PyObject *pyobj)
1708
1718
  PyObject *pytem = Py_API(PyTuple_GetItem)(pyobj, i);
1709
1719
  Py_API(Py_IncRef)(pytem);
1710
1720
  rb_ary_push(ary, pycall_pyobject_to_ruby(pytem));
1721
+ pycall_Py_DecRef(pytem);
1711
1722
  }
1712
1723
 
1713
1724
  return ary;
@@ -1726,6 +1737,7 @@ pycall_pysequence_to_a(PyObject *pyobj)
1726
1737
  for (i = 0; i < n; ++i) {
1727
1738
  PyObject *pytem = Py_API(PySequence_GetItem)(pyobj, i);
1728
1739
  rb_ary_push(ary, pycall_pyobject_to_ruby(pytem));
1740
+ pycall_Py_DecRef(pytem);
1729
1741
  }
1730
1742
 
1731
1743
  return ary;
@@ -1938,12 +1950,10 @@ pycall_pydict_from_ruby_iter(VALUE key, VALUE value, VALUE arg)
1938
1950
  pyobj_key = pycall_pyobject_from_ruby(key);
1939
1951
  pyobj_value = pycall_pyobject_from_ruby(value);
1940
1952
  res = Py_API(PyObject_SetItem)(pydictobj, pyobj_key, pyobj_value);
1941
- if (res == -1) {
1942
- return ST_STOP;
1943
- }
1944
- Py_API(Py_DecRef)(pyobj_key);
1945
- Py_API(Py_DecRef)(pyobj_value);
1946
- return ST_CONTINUE;
1953
+ pycall_Py_DecRef(pyobj_key);
1954
+ pycall_Py_DecRef(pyobj_value);
1955
+
1956
+ return (res == -1) ? ST_STOP : ST_CONTINUE;
1947
1957
  }
1948
1958
 
1949
1959
  PyObject *
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
 
3
3
  import ctypes.util
4
- from distutils.sysconfig import get_config_var, get_python_version
4
+ from sysconfig import get_config_var, get_python_version
5
5
  import os
6
6
  import sys
7
7
 
@@ -1,5 +1,5 @@
1
1
  module PyCall
2
- VERSION = "1.4.2"
2
+ VERSION = "1.5.0"
3
3
 
4
4
  module Version
5
5
  numbers, TAG = VERSION.split("-")
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.2
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-08 00:00:00.000000000 Z
11
+ date: 2023-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler