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 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: []