pycall 1.4.2 → 1.5.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b2526ea3050985dc6d864e979804fb4ebaa9c36d8239b48809a9cd31dd01de5
4
- data.tar.gz: 68df5fcac7fd5c574009ebbc33f0d9c1724ff8d5057d4dfaa69832b8509e4a92
3
+ metadata.gz: 381593af8570fc0a96f4df77aad616cf93cf86afa336b0be1618ac39c68fdd73
4
+ data.tar.gz: b1c8075e157dd32d4699ea6ae581d148c4ae537b77f60437a31a1940e31bf8fe
5
5
  SHA512:
6
- metadata.gz: c52cd3ac7b709238a1b3ec95ed7eb45bcfaa5ef8a40b74f8de15cec928350152769c915250f27290e1b7f2bfb84032faa3a39837d0598c2927a114f6989f11dc
7
- data.tar.gz: 6c45f609e09251815588b0a02095af9d221e2c715d4e614d16888326fc46c6158a631b6cc514d9b3e673468abf2834e003074a5e77f27b46098c5ab698328459
6
+ metadata.gz: 5a4d26affe26f179752eba471971dfbee4a3336faf7337696dd0cc6cc8b4462e6e8dc27a7bb8d53495178fe2b09fa95c11a6f1da3366a645ac9106248ba5b376
7
+ data.tar.gz: c72271ccdb5a50f47ced48619468114666e7767ff697ff385968e61e721f7f8449c79d86f218607f1a0fb67ec31ec88f843aeb5cab491fbd481025e3917b9df6
@@ -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,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 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
@@ -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
- return pycall_pyobject_to_ruby(res);
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
- if (Py_API(PyDict_SetItemString)(kwargs, key_cstr, pyvalue) < 0) {
970
- return ST_STOP;
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
- return pycall_call_python_callable(attr, argc, argv);
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
- 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;
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 *
@@ -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.1"
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.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-01-08 00:00:00.000000000 Z
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.13
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: []