pycall 1.4.2 → 1.5.2
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 +4 -4
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/ci.yml +8 -20
- data/.github/workflows/windows.yml +2 -3
- data/CHANGES.md +31 -0
- data/README.md +31 -18
- data/ext/pycall/extconf.rb +2 -0
- data/ext/pycall/gc.c +6 -2
- data/ext/pycall/libpython.c +4 -0
- data/ext/pycall/pycall.c +46 -23
- data/ext/pycall/pycall_internal.h +9 -0
- data/ext/pycall/range.c +8 -2
- data/ext/pycall/ruby_wrapper.c +22 -11
- data/lib/pycall/python/investigator.py +1 -1
- data/lib/pycall/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0793d5cd5f93c4eb9cd5938b7999799649db72f2abd35b4ae3247c450aec7ce
|
4
|
+
data.tar.gz: 404e3c06167a752f94cfc9051734a259725366f7c981c654e4f8744a3613c907
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c8f666bb616b01f69bcd33130991cd22f9f2bfea3b67946e87550c846327032bd14d69d2522d8b83ee18db5551cea3bf0fa51f7043d7cfcfd8a8490c6bf04df
|
7
|
+
data.tar.gz: 041600f566b4d8158dc4772830ab1a8eb00479a82b118f0f135e20130d05d9047dba53b8ab32701c2bee20ec770a48cd540cd259d369163e64f4da775e7e26ae
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# To get started with Dependabot version updates, you'll need to specify which
|
2
|
+
# package ecosystems to update and where the package manifests are located.
|
3
|
+
# Please see the documentation for all configuration options:
|
4
|
+
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
5
|
+
|
6
|
+
version: 2
|
7
|
+
updates:
|
8
|
+
- package-ecosystem: "bundler" # See documentation for possible values
|
9
|
+
directory: "/" # Location of package manifests
|
10
|
+
schedule:
|
11
|
+
interval: "daily"
|
data/.github/workflows/ci.yml
CHANGED
@@ -25,6 +25,7 @@ jobs:
|
|
25
25
|
- ubuntu-20.04
|
26
26
|
- macos-latest
|
27
27
|
ruby:
|
28
|
+
- "3.3"
|
28
29
|
- "3.2"
|
29
30
|
- "3.1"
|
30
31
|
- "3.0"
|
@@ -41,41 +42,28 @@ jobs:
|
|
41
42
|
- { os: ubuntu-20.04 , ruby: 2.5 , python: "3.x" , python_architecture: x64 , venv: "" }
|
42
43
|
- { os: ubuntu-20.04 , ruby: 2.4 , python: "3.x" , python_architecture: x64 , venv: "" }
|
43
44
|
|
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
45
|
# Ruby 2.7 with Each Python 3.x
|
46
|
+
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.12" , python_architecture: x64 , venv: "" }
|
53
47
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.11" , python_architecture: x64 , venv: "" }
|
54
48
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.10" , python_architecture: x64 , venv: "" }
|
55
49
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.9" , python_architecture: x64 , venv: "" }
|
56
50
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.8" , python_architecture: x64 , venv: "" }
|
57
51
|
- { os: ubuntu-20.04 , ruby: 2.7 , python: "3.7" , python_architecture: x64 , venv: "" }
|
58
52
|
- { 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
53
|
|
61
54
|
# Ruby-debug with the latest Python 3
|
62
55
|
- { os: ubuntu-20.04 , ruby: debug , python: "3.x" , python_architecture: x64 , venv: "" }
|
63
56
|
|
64
|
-
# Ruby
|
65
|
-
- { os: ubuntu-20.04 , ruby: "3.
|
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:" }
|
57
|
+
# The latest stable Ruby with the latest Python 3 with venv
|
58
|
+
- { os: ubuntu-20.04 , ruby: "3.3" , python: "3.x" , python_architecture: x64 , venv: "venv:" }
|
70
59
|
|
71
60
|
# macOS with venv
|
72
|
-
- { os: macos-latest , ruby: "3.
|
73
|
-
- { os: macos-latest , ruby: "3.1" , python: "3.8" , python_architecture: x64 , venv: "venv:" }
|
61
|
+
- { os: macos-latest , ruby: "3.3" , python: "3.x" , python_architecture: x64 , venv: "venv:" }
|
74
62
|
|
75
63
|
#- { os: macos-latest , ruby: debug , python: "3.x" , python_architecture: x64 , venv: "" }
|
76
64
|
|
77
65
|
steps:
|
78
|
-
- uses: actions/checkout@
|
66
|
+
- uses: actions/checkout@v3
|
79
67
|
with:
|
80
68
|
fetch-depth: 1
|
81
69
|
|
@@ -84,7 +72,7 @@ jobs:
|
|
84
72
|
with:
|
85
73
|
ruby-version: ${{ matrix.ruby }}
|
86
74
|
|
87
|
-
- uses: actions/setup-python@
|
75
|
+
- uses: actions/setup-python@v4
|
88
76
|
with:
|
89
77
|
python-version: ${{ matrix.python }}
|
90
78
|
architecture: ${{ matrix.python_architecture }}
|
@@ -119,7 +107,7 @@ jobs:
|
|
119
107
|
matrix:
|
120
108
|
os:
|
121
109
|
- ubuntu-20.04
|
122
|
-
|
110
|
+
#- macos-latest
|
123
111
|
ruby:
|
124
112
|
- "3.1"
|
125
113
|
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,36 @@
|
|
1
1
|
# The change history of PyCall
|
2
2
|
|
3
|
+
## 1.5.2
|
4
|
+
|
5
|
+
* Fix memory leak with str(list) (#169).
|
6
|
+
|
7
|
+
*mknkmyza*
|
8
|
+
|
9
|
+
* Fix SEGV occured on Ruby process finalization.
|
10
|
+
|
11
|
+
* Fix for supporting Ruby >= 3.3.
|
12
|
+
|
13
|
+
* Fix for supporting Python >= 3.2.
|
14
|
+
|
15
|
+
## 1.5.1
|
16
|
+
|
17
|
+
* Fix memory leak in rich compare methods (#167, #168).
|
18
|
+
|
19
|
+
*mknkmyza*
|
20
|
+
|
21
|
+
## 1.5.0
|
22
|
+
|
23
|
+
* Fix to prevent distutils deprecation warning (#159)
|
24
|
+
|
25
|
+
*Christopher Dilks*
|
26
|
+
|
27
|
+
* Drop Python 2.7 support
|
28
|
+
|
29
|
+
* Fix memory leak of Python objects. (#129)
|
30
|
+
This should fixes #128 and maybe also fixes #164.
|
31
|
+
|
32
|
+
*mknkmyza*
|
33
|
+
|
3
34
|
## 1.4.2
|
4
35
|
|
5
36
|
* 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/extconf.rb
CHANGED
data/ext/pycall/gc.c
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
#include "pycall_internal.h"
|
2
2
|
|
3
|
+
static ID id_gcguard_table;
|
4
|
+
|
3
5
|
struct gcguard {
|
4
6
|
st_table *guarded_objects;
|
5
7
|
};
|
@@ -24,6 +26,7 @@ gcguard_free(void* ptr)
|
|
24
26
|
{
|
25
27
|
struct gcguard *gg = (struct gcguard *)ptr;
|
26
28
|
st_free_table(gg->guarded_objects);
|
29
|
+
rb_ivar_set(mPyCall, id_gcguard_table, Qnil);
|
27
30
|
}
|
28
31
|
|
29
32
|
static size_t
|
@@ -69,7 +72,6 @@ gcguard_delete(VALUE gcguard, PyObject *pyptr)
|
|
69
72
|
}
|
70
73
|
}
|
71
74
|
|
72
|
-
static ID id_gcguard_table;
|
73
75
|
static PyObject *weakref_callback_pyobj;
|
74
76
|
static PyObject *gcguard_weakref_destroyed(PyObject *self, PyObject *weakref);
|
75
77
|
|
@@ -98,7 +100,9 @@ void
|
|
98
100
|
pycall_gcguard_delete(PyObject *pyobj)
|
99
101
|
{
|
100
102
|
VALUE gcguard = rb_ivar_get(mPyCall, id_gcguard_table);
|
101
|
-
|
103
|
+
if (!NIL_P(gcguard)) {
|
104
|
+
gcguard_delete(gcguard, pyobj);
|
105
|
+
}
|
102
106
|
}
|
103
107
|
|
104
108
|
void
|
data/ext/pycall/libpython.c
CHANGED
@@ -217,6 +217,10 @@ pycall_init_libpython_api_table(VALUE libpython_handle)
|
|
217
217
|
INIT_API_TABLE_ENTRY2(PyUnicode_DecodeUTF8, PyUnicodeUCS2_DecodeUTF8, required);
|
218
218
|
INIT_API_TABLE_ENTRY2(PyUnicode_FromFormatV, PyUnicodeUCS2_FromFormatV, required);
|
219
219
|
}
|
220
|
+
|
221
|
+
INIT_API_TABLE_ENTRY(PyGILState_Check, required);
|
222
|
+
INIT_API_TABLE_ENTRY(PyGILState_Ensure, required);
|
223
|
+
INIT_API_TABLE_ENTRY(PyGILState_Release, required);
|
220
224
|
}
|
221
225
|
|
222
226
|
void
|
data/ext/pycall/pycall.c
CHANGED
@@ -139,7 +139,15 @@ pycall_pyptr_free(void *ptr)
|
|
139
139
|
fprintf(stderr, "zero refcnt object %p of type %s\n", pyobj, Py_TYPE(pyobj)->tp_name);
|
140
140
|
}
|
141
141
|
#endif /* PYCALL_DEBUG_DUMP_REFCNT */
|
142
|
-
|
142
|
+
|
143
|
+
if (Py_API(PyGILState_Check())) {
|
144
|
+
pycall_Py_DecRef(pyobj);
|
145
|
+
}
|
146
|
+
else {
|
147
|
+
PyGILState_STATE gstate = Py_API(PyGILState_Ensure)();
|
148
|
+
pycall_Py_DecRef(pyobj);
|
149
|
+
Py_API(PyGILState_Release)(gstate);
|
150
|
+
}
|
143
151
|
}
|
144
152
|
|
145
153
|
static size_t _PySys_GetSizeOf(PyObject *);
|
@@ -792,8 +800,9 @@ pycall_libpython_helpers_m_compare(VALUE mod, VALUE op, VALUE pyptr_a, VALUE pyp
|
|
792
800
|
if (!res) {
|
793
801
|
pycall_pyerror_fetch_and_raise("PyObject_RichCompare in pycall_libpython_helpers_m_compare");
|
794
802
|
}
|
795
|
-
|
796
|
-
|
803
|
+
VALUE obj = pycall_pyobject_to_ruby(res);
|
804
|
+
pycall_Py_DecRef(res);
|
805
|
+
return obj;
|
797
806
|
}
|
798
807
|
|
799
808
|
static int is_pyobject_wrapper(VALUE obj);
|
@@ -966,10 +975,10 @@ pycall_extract_kwargs_from_ruby_hash(VALUE key, VALUE value, VALUE arg)
|
|
966
975
|
key_cstr = StringValueCStr(key);
|
967
976
|
pyvalue = pycall_pyobject_from_ruby(value);
|
968
977
|
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
return ST_CONTINUE;
|
978
|
+
int res = Py_API(PyDict_SetItemString)(kwargs, key_cstr, pyvalue);
|
979
|
+
pycall_Py_DecRef(pyvalue);
|
980
|
+
|
981
|
+
return (res < 0) ? ST_STOP : ST_CONTINUE;
|
973
982
|
}
|
974
983
|
|
975
984
|
static void
|
@@ -1061,6 +1070,10 @@ pycall_call_python_callable(PyObject *pycallable, int argc, VALUE *argv)
|
|
1061
1070
|
}
|
1062
1071
|
|
1063
1072
|
res = pyobject_call(pycallable, args, kwargs); /* New reference */
|
1073
|
+
pycall_Py_DecRef(args);
|
1074
|
+
if (kwargs) {
|
1075
|
+
pycall_Py_DecRef(kwargs);
|
1076
|
+
}
|
1064
1077
|
if (!res) {
|
1065
1078
|
pycall_pyerror_fetch_and_raise("PyObject_Call in pycall_call_python_callable");
|
1066
1079
|
}
|
@@ -1099,9 +1112,9 @@ pycall_pyobject_wrapper_wrapper_method(int argc, VALUE *argv, VALUE wrapper)
|
|
1099
1112
|
|
1100
1113
|
name_cstr[RSTRING_LEN(name) - 1] = '\0';
|
1101
1114
|
res = Py_API(PyObject_SetAttrString)(pyobj, name_cstr, attr);
|
1115
|
+
pycall_Py_DecRef(attr);
|
1102
1116
|
name_cstr[RSTRING_LEN(name) - 1] = '=';
|
1103
1117
|
if (res == -1) {
|
1104
|
-
pycall_Py_DecRef(attr);
|
1105
1118
|
pycall_pyerror_fetch_and_raise("PyObject_SetAttrString in pycall_pyobject_wrapper_wrapper_method");
|
1106
1119
|
}
|
1107
1120
|
|
@@ -1119,7 +1132,9 @@ pycall_pyobject_wrapper_wrapper_method(int argc, VALUE *argv, VALUE wrapper)
|
|
1119
1132
|
if (PyType_Check(attr) || PyClass_Check(attr))
|
1120
1133
|
return pycall_pyobject_to_ruby(attr);
|
1121
1134
|
|
1122
|
-
|
1135
|
+
VALUE obj = pycall_call_python_callable(attr, argc, argv);
|
1136
|
+
pycall_Py_DecRef(attr);
|
1137
|
+
return obj;
|
1123
1138
|
}
|
1124
1139
|
|
1125
1140
|
static VALUE
|
@@ -1203,6 +1218,7 @@ pycall_libpython_helpers_m_getitem(VALUE mod, VALUE pyptr, VALUE key)
|
|
1203
1218
|
pyobj_key = pycall_convert_index(key);
|
1204
1219
|
|
1205
1220
|
pyobj_v = Py_API(PyObject_GetItem)(pyobj, pyobj_key);
|
1221
|
+
pycall_Py_DecRef(pyobj_key);
|
1206
1222
|
if (!pyobj_v) {
|
1207
1223
|
pycall_pyerror_fetch_and_raise("PyObject_GetItem in pycall_libpython_helpers_m_getitem");
|
1208
1224
|
}
|
@@ -1223,11 +1239,11 @@ pycall_libpython_helpers_m_setitem(VALUE mod, VALUE pyptr, VALUE key, VALUE v)
|
|
1223
1239
|
pyobj_value = pycall_pyobject_from_ruby(v);
|
1224
1240
|
|
1225
1241
|
res = Py_API(PyObject_SetItem)(pyobj, pyobj_key, pyobj_value);
|
1242
|
+
pycall_Py_DecRef(pyobj_key);
|
1243
|
+
pycall_Py_DecRef(pyobj_value);
|
1226
1244
|
if (res == -1) {
|
1227
1245
|
pycall_pyerror_fetch_and_raise("PyObject_SetItem in pycall_libpython_helpers_m_setitem");
|
1228
1246
|
}
|
1229
|
-
Py_API(Py_DecRef(pyobj_key));
|
1230
|
-
Py_API(Py_DecRef(pyobj_value));
|
1231
1247
|
|
1232
1248
|
return v;
|
1233
1249
|
}
|
@@ -1242,6 +1258,7 @@ pycall_libpython_helpers_m_delitem(VALUE mod, VALUE pyptr, VALUE key)
|
|
1242
1258
|
pyobj_key = pycall_convert_index(key);
|
1243
1259
|
|
1244
1260
|
res = Py_API(PyObject_DelItem)(pyobj, pyobj_key);
|
1261
|
+
pycall_Py_DecRef(pyobj_key);
|
1245
1262
|
if (res == -1) {
|
1246
1263
|
pycall_pyerror_fetch_and_raise("PyObject_DelItem");
|
1247
1264
|
}
|
@@ -1261,7 +1278,9 @@ pycall_libpython_helpers_m_str(VALUE mod, VALUE pyptr)
|
|
1261
1278
|
pycall_pyerror_fetch_and_raise("PyObject_Str");
|
1262
1279
|
}
|
1263
1280
|
|
1264
|
-
|
1281
|
+
VALUE v = pycall_pyobject_to_ruby(pyobj_str);
|
1282
|
+
pycall_Py_DecRef(pyobj_str);
|
1283
|
+
return v;
|
1265
1284
|
}
|
1266
1285
|
|
1267
1286
|
static VALUE
|
@@ -1273,6 +1292,7 @@ pycall_libpython_helpers_m_dict_contains(VALUE mod, VALUE pyptr, VALUE key)
|
|
1273
1292
|
pyobj = check_get_pyobj_ptr(pyptr, Py_API(PyDict_Type));
|
1274
1293
|
pyobj_key = pycall_pyobject_from_ruby(key);
|
1275
1294
|
res = Py_API(PyDict_Contains)(pyobj, pyobj_key);
|
1295
|
+
pycall_Py_DecRef(pyobj_key);
|
1276
1296
|
if (res == -1) {
|
1277
1297
|
pycall_pyerror_fetch_and_raise("PyDict_Contains");
|
1278
1298
|
}
|
@@ -1311,6 +1331,7 @@ pycall_libpython_helpers_m_sequence_contains(VALUE mod, VALUE pyptr, VALUE key)
|
|
1311
1331
|
|
1312
1332
|
pyobj_key = pycall_pyobject_from_ruby(key);
|
1313
1333
|
res = Py_API(PySequence_Contains)(pyobj, pyobj_key);
|
1334
|
+
pycall_Py_DecRef(pyobj_key);
|
1314
1335
|
if (res == -1) {
|
1315
1336
|
pycall_pyerror_fetch_and_raise("PySequence_Contains");
|
1316
1337
|
}
|
@@ -1679,19 +1700,21 @@ pycall_pyunicode_to_ruby(PyObject *pyobj)
|
|
1679
1700
|
return Qnil;
|
1680
1701
|
}
|
1681
1702
|
|
1682
|
-
|
1683
|
-
if (!
|
1703
|
+
PyObject *pyobj_uni = Py_API(PyUnicode_AsUTF8String)(pyobj);
|
1704
|
+
if (!pyobj_uni) {
|
1684
1705
|
Py_API(PyErr_Clear)();
|
1685
1706
|
return Qnil;
|
1686
1707
|
}
|
1687
1708
|
|
1688
|
-
res = Py_API(PyString_AsStringAndSize)(
|
1709
|
+
res = Py_API(PyString_AsStringAndSize)(pyobj_uni, &str, &len);
|
1689
1710
|
if (res < 0) {
|
1690
|
-
pycall_Py_DecRef(
|
1711
|
+
pycall_Py_DecRef(pyobj_uni);
|
1691
1712
|
return Qnil;
|
1692
1713
|
}
|
1693
1714
|
|
1694
|
-
|
1715
|
+
VALUE v = rb_enc_str_new(str, len, rb_enc_from_index(rb_utf8_encindex()));
|
1716
|
+
pycall_Py_DecRef(pyobj_uni);
|
1717
|
+
return v;
|
1695
1718
|
}
|
1696
1719
|
|
1697
1720
|
static VALUE
|
@@ -1708,6 +1731,7 @@ pycall_pytuple_to_a(PyObject *pyobj)
|
|
1708
1731
|
PyObject *pytem = Py_API(PyTuple_GetItem)(pyobj, i);
|
1709
1732
|
Py_API(Py_IncRef)(pytem);
|
1710
1733
|
rb_ary_push(ary, pycall_pyobject_to_ruby(pytem));
|
1734
|
+
pycall_Py_DecRef(pytem);
|
1711
1735
|
}
|
1712
1736
|
|
1713
1737
|
return ary;
|
@@ -1726,6 +1750,7 @@ pycall_pysequence_to_a(PyObject *pyobj)
|
|
1726
1750
|
for (i = 0; i < n; ++i) {
|
1727
1751
|
PyObject *pytem = Py_API(PySequence_GetItem)(pyobj, i);
|
1728
1752
|
rb_ary_push(ary, pycall_pyobject_to_ruby(pytem));
|
1753
|
+
pycall_Py_DecRef(pytem);
|
1729
1754
|
}
|
1730
1755
|
|
1731
1756
|
return ary;
|
@@ -1938,12 +1963,10 @@ pycall_pydict_from_ruby_iter(VALUE key, VALUE value, VALUE arg)
|
|
1938
1963
|
pyobj_key = pycall_pyobject_from_ruby(key);
|
1939
1964
|
pyobj_value = pycall_pyobject_from_ruby(value);
|
1940
1965
|
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;
|
1966
|
+
pycall_Py_DecRef(pyobj_key);
|
1967
|
+
pycall_Py_DecRef(pyobj_value);
|
1968
|
+
|
1969
|
+
return (res == -1) ? ST_STOP : ST_CONTINUE;
|
1947
1970
|
}
|
1948
1971
|
|
1949
1972
|
PyObject *
|
@@ -519,6 +519,11 @@ PyObject * PyRuby_New(VALUE ruby_object);
|
|
519
519
|
|
520
520
|
/* ==== thread support ==== */
|
521
521
|
|
522
|
+
typedef enum {
|
523
|
+
PyGILState_LOCKED,
|
524
|
+
PyGILState_UNLOCKED
|
525
|
+
} PyGILState_STATE;
|
526
|
+
|
522
527
|
#if defined(PYCALL_THREAD_WIN32)
|
523
528
|
typedef DWORD pycall_tls_key;
|
524
529
|
#elif defined(PYCALL_THREAD_PTHREAD)
|
@@ -669,6 +674,10 @@ typedef struct {
|
|
669
674
|
PyObject * (* PyUnicode_AsUTF8String)(PyObject *);
|
670
675
|
PyObject * (* PyUnicode_DecodeUTF8)(char const*, Py_ssize_t, char const *);
|
671
676
|
PyObject * (* PyUnicode_FromFormatV)(char const*, ...);
|
677
|
+
|
678
|
+
int (* PyGILState_Check)(void);
|
679
|
+
PyGILState_STATE (* PyGILState_Ensure)(void);
|
680
|
+
void (* PyGILState_Release)(PyGILState_STATE);
|
672
681
|
} pycall_libpython_api_table_t;
|
673
682
|
|
674
683
|
pycall_libpython_api_table_t *pycall_libpython_api_table(void);
|
data/ext/pycall/range.c
CHANGED
@@ -6,6 +6,12 @@ struct enumerator_head {
|
|
6
6
|
VALUE args;
|
7
7
|
};
|
8
8
|
|
9
|
+
#ifdef HAVE_RTYPEDDATA_GET_DATA
|
10
|
+
# define GET_ENUMERATOR_DATA(obj) ((struct enumerator_head *)RTYPEDDATA_GET_DATA(obj))
|
11
|
+
#else
|
12
|
+
# define GET_ENUMERATOR_DATA(obj) ((struct enumerator_head *)DATA_PTR(obj))
|
13
|
+
#endif
|
14
|
+
|
9
15
|
int
|
10
16
|
pycall_obj_is_step_range(VALUE obj)
|
11
17
|
{
|
@@ -19,7 +25,7 @@ pycall_obj_is_step_range(VALUE obj)
|
|
19
25
|
return 0;
|
20
26
|
}
|
21
27
|
|
22
|
-
eh = (
|
28
|
+
eh = GET_ENUMERATOR_DATA(obj);
|
23
29
|
|
24
30
|
if (!rb_obj_is_kind_of(eh->obj, rb_cRange)) {
|
25
31
|
return 0;
|
@@ -50,7 +56,7 @@ pycall_extract_range(VALUE obj, VALUE *pbegin, VALUE *pend, int *pexclude_end, V
|
|
50
56
|
exclude_end = rb_funcallv(obj, id_exclude_end, 0, 0);
|
51
57
|
}
|
52
58
|
else if (pycall_obj_is_step_range(obj)) {
|
53
|
-
struct enumerator_head *eh = (
|
59
|
+
struct enumerator_head *eh = GET_ENUMERATOR_DATA(obj);
|
54
60
|
begin = rb_funcallv(eh->obj, id_begin, 0, 0);
|
55
61
|
end = rb_funcallv(eh->obj, id_end, 0, 0);
|
56
62
|
exclude_end = rb_funcallv(eh->obj, id_exclude_end, 0, 0);
|
data/ext/pycall/ruby_wrapper.c
CHANGED
@@ -59,10 +59,11 @@ PyObject *
|
|
59
59
|
PyRuby_New(VALUE ruby_object)
|
60
60
|
{
|
61
61
|
if (!ruby_thread_has_gvl_p()) {
|
62
|
-
CALL_WITH_GVL(PyRuby_New_impl, ruby_object);
|
62
|
+
return CALL_WITH_GVL(PyRuby_New_impl, ruby_object);
|
63
|
+
}
|
64
|
+
else {
|
65
|
+
return PyRuby_New_impl(ruby_object);
|
63
66
|
}
|
64
|
-
|
65
|
-
return PyRuby_New_impl(ruby_object);
|
66
67
|
}
|
67
68
|
|
68
69
|
static void *
|
@@ -90,7 +91,9 @@ PyRuby_dealloc_with_gvl(PyRubyObject *pyro)
|
|
90
91
|
if (!ruby_thread_has_gvl_p()) {
|
91
92
|
CALL_WITH_GVL(PyRuby_dealloc, pyro);
|
92
93
|
}
|
93
|
-
|
94
|
+
else {
|
95
|
+
PyRuby_dealloc(pyro);
|
96
|
+
}
|
94
97
|
}
|
95
98
|
|
96
99
|
static PyObject *
|
@@ -114,7 +117,9 @@ PyRuby_repr_with_gvl(PyRubyObject *pyro)
|
|
114
117
|
if (!ruby_thread_has_gvl_p()) {
|
115
118
|
return CALL_WITH_GVL(PyRuby_repr, pyro);
|
116
119
|
}
|
117
|
-
|
120
|
+
else {
|
121
|
+
return PyRuby_repr(pyro);
|
122
|
+
}
|
118
123
|
}
|
119
124
|
|
120
125
|
#if SIZEOF_SSIZE_T < 8
|
@@ -154,7 +159,9 @@ PyRuby_hash_long_with_gvl(PyRubyObject *pyro)
|
|
154
159
|
if (!ruby_thread_has_gvl_p()) {
|
155
160
|
return (long)(intptr_t)CALL_WITH_GVL(PyRuby_hash_long, pyro);
|
156
161
|
}
|
157
|
-
|
162
|
+
else {
|
163
|
+
return (long)(intptr_t)PyRuby_hash_long(pyro);
|
164
|
+
}
|
158
165
|
}
|
159
166
|
|
160
167
|
static void *
|
@@ -185,7 +192,9 @@ PyRuby_hash_hash_t_with_gvl(PyRubyObject *pyro)
|
|
185
192
|
if (!ruby_thread_has_gvl_p()) {
|
186
193
|
return (Py_hash_t)CALL_WITH_GVL(PyRuby_hash_hash_t, pyro);
|
187
194
|
}
|
188
|
-
|
195
|
+
else {
|
196
|
+
return (Py_hash_t)PyRuby_hash_hash_t(pyro);
|
197
|
+
}
|
189
198
|
}
|
190
199
|
|
191
200
|
struct call_rb_funcallv_params {
|
@@ -269,8 +278,9 @@ PyRuby_call_with_gvl(PyRubyObject *pyro, PyObject *pyobj_args, PyObject *pyobj_k
|
|
269
278
|
if (!ruby_thread_has_gvl_p()) {
|
270
279
|
return CALL_WITH_GVL(PyRuby_call, ¶ms);
|
271
280
|
}
|
272
|
-
|
273
|
-
|
281
|
+
else {
|
282
|
+
return PyRuby_call(¶ms);
|
283
|
+
}
|
274
284
|
}
|
275
285
|
|
276
286
|
struct PyRuby_getattro_params {
|
@@ -348,8 +358,9 @@ PyRuby_getattro_with_gvl(PyRubyObject *pyro, PyObject *pyobj_name)
|
|
348
358
|
if (!ruby_thread_has_gvl_p()) {
|
349
359
|
return CALL_WITH_GVL(PyRuby_getattro, ¶ms);
|
350
360
|
}
|
351
|
-
|
352
|
-
|
361
|
+
else {
|
362
|
+
return PyRuby_getattro(¶ms);
|
363
|
+
}
|
353
364
|
}
|
354
365
|
|
355
366
|
/* ==== PyCall::PyRubyPtr ==== */
|
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.2
|
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:
|
11
|
+
date: 2024-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -144,6 +144,7 @@ extensions:
|
|
144
144
|
- ext/pycall/extconf.rb
|
145
145
|
extra_rdoc_files: []
|
146
146
|
files:
|
147
|
+
- ".github/dependabot.yml"
|
147
148
|
- ".github/workflows/ci.yml"
|
148
149
|
- ".github/workflows/windows.yml"
|
149
150
|
- ".gitignore"
|
@@ -221,7 +222,7 @@ homepage: https://github.com/mrkn/pycall
|
|
221
222
|
licenses:
|
222
223
|
- MIT
|
223
224
|
metadata: {}
|
224
|
-
post_install_message:
|
225
|
+
post_install_message:
|
225
226
|
rdoc_options: []
|
226
227
|
require_paths:
|
227
228
|
- lib
|
@@ -236,8 +237,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
237
|
- !ruby/object:Gem::Version
|
237
238
|
version: '0'
|
238
239
|
requirements: []
|
239
|
-
rubygems_version: 3.
|
240
|
-
signing_key:
|
240
|
+
rubygems_version: 3.5.10
|
241
|
+
signing_key:
|
241
242
|
specification_version: 4
|
242
243
|
summary: pycall
|
243
244
|
test_files: []
|