pycall 1.4.2 → 1.5.0

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