pycall 1.5.0 → 1.5.2

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: 7b2f11d56347f0f7a8977916c73468aa165a23350ed271e7cdb064341211aabb
4
- data.tar.gz: 0d4c68470567e1a2d58d2512f8ca883dfaca1329f4d89a255d0917f3b2c85f7b
3
+ metadata.gz: c0793d5cd5f93c4eb9cd5938b7999799649db72f2abd35b4ae3247c450aec7ce
4
+ data.tar.gz: 404e3c06167a752f94cfc9051734a259725366f7c981c654e4f8744a3613c907
5
5
  SHA512:
6
- metadata.gz: dd61f72199c6986c9bbe5260a7f43c92a6e8ef2036a4fb94c2d3ff14a74c1b21a306f601e6ccee73dd709fb76cc48b24af1002a3b95cbe18ecc7604015f8e028
7
- data.tar.gz: 4040cec7aa67bb7edf1a8f07896e6c7b62b971b7e15a78171d8424465087dff5b25e8bedd0971f9c2060944712f1b14905605e9261933f480162a87f2bbd925b
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"
@@ -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"
@@ -42,6 +43,7 @@ jobs:
42
43
  - { os: ubuntu-20.04 , ruby: 2.4 , python: "3.x" , python_architecture: x64 , venv: "" }
43
44
 
44
45
  # Ruby 2.7 with Each Python 3.x
46
+ - { os: ubuntu-20.04 , ruby: 2.7 , python: "3.12" , python_architecture: x64 , venv: "" }
45
47
  - { os: ubuntu-20.04 , ruby: 2.7 , python: "3.11" , python_architecture: x64 , venv: "" }
46
48
  - { os: ubuntu-20.04 , ruby: 2.7 , python: "3.10" , python_architecture: x64 , venv: "" }
47
49
  - { os: ubuntu-20.04 , ruby: 2.7 , python: "3.9" , python_architecture: x64 , venv: "" }
@@ -52,12 +54,11 @@ jobs:
52
54
  # Ruby-debug with the latest Python 3
53
55
  - { os: ubuntu-20.04 , ruby: debug , python: "3.x" , python_architecture: x64 , venv: "" }
54
56
 
55
- # Ruby 3.1 with the latest Python 3 with venv
56
- - { os: ubuntu-20.04 , ruby: "3.1" , python: "3.x" , 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:" }
57
59
 
58
60
  # macOS with venv
59
- - { os: macos-latest , ruby: "3.1" , python: "3.x" , python_architecture: x64 , venv: "venv:" }
60
- - { 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:" }
61
62
 
62
63
  #- { os: macos-latest , ruby: debug , python: "3.x" , python_architecture: x64 , venv: "" }
63
64
 
data/CHANGES.md CHANGED
@@ -1,5 +1,23 @@
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
+
3
21
  ## 1.5.0
4
22
 
5
23
  * Fix to prevent distutils deprecation warning (#159)
@@ -1,3 +1,5 @@
1
1
  require 'mkmf'
2
2
 
3
+ have_func("RTYPEDDATA_GET_DATA")
4
+
3
5
  create_makefile('pycall')
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
- gcguard_delete(gcguard, pyobj);
103
+ if (!NIL_P(gcguard)) {
104
+ gcguard_delete(gcguard, pyobj);
105
+ }
102
106
  }
103
107
 
104
108
  void
@@ -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
- pycall_Py_DecRef(pyobj);
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
- return pycall_pyobject_to_ruby(res);
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);
@@ -1269,7 +1278,9 @@ pycall_libpython_helpers_m_str(VALUE mod, VALUE pyptr)
1269
1278
  pycall_pyerror_fetch_and_raise("PyObject_Str");
1270
1279
  }
1271
1280
 
1272
- return pycall_pyobject_to_ruby(pyobj_str);
1281
+ VALUE v = pycall_pyobject_to_ruby(pyobj_str);
1282
+ pycall_Py_DecRef(pyobj_str);
1283
+ return v;
1273
1284
  }
1274
1285
 
1275
1286
  static VALUE
@@ -1689,19 +1700,21 @@ pycall_pyunicode_to_ruby(PyObject *pyobj)
1689
1700
  return Qnil;
1690
1701
  }
1691
1702
 
1692
- pyobj = Py_API(PyUnicode_AsUTF8String)(pyobj);
1693
- if (!pyobj) {
1703
+ PyObject *pyobj_uni = Py_API(PyUnicode_AsUTF8String)(pyobj);
1704
+ if (!pyobj_uni) {
1694
1705
  Py_API(PyErr_Clear)();
1695
1706
  return Qnil;
1696
1707
  }
1697
1708
 
1698
- res = Py_API(PyString_AsStringAndSize)(pyobj, &str, &len);
1709
+ res = Py_API(PyString_AsStringAndSize)(pyobj_uni, &str, &len);
1699
1710
  if (res < 0) {
1700
- pycall_Py_DecRef(pyobj);
1711
+ pycall_Py_DecRef(pyobj_uni);
1701
1712
  return Qnil;
1702
1713
  }
1703
1714
 
1704
- return rb_enc_str_new(str, len, rb_enc_from_index(rb_utf8_encindex()));
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;
1705
1718
  }
1706
1719
 
1707
1720
  static VALUE
@@ -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 = (struct enumerator_head *)DATA_PTR(obj);
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 = (struct enumerator_head *)DATA_PTR(obj);
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);
@@ -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
- PyRuby_dealloc(pyro);
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
- return PyRuby_repr(pyro);
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
- return (long)(intptr_t)PyRuby_hash_long(pyro);
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
- return (Py_hash_t)PyRuby_hash_hash_t(pyro);
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, &params);
271
280
  }
272
-
273
- return PyRuby_call(&params);
281
+ else {
282
+ return PyRuby_call(&params);
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, &params);
350
360
  }
351
-
352
- return PyRuby_getattro(&params);
361
+ else {
362
+ return PyRuby_getattro(&params);
363
+ }
353
364
  }
354
365
 
355
366
  /* ==== PyCall::PyRubyPtr ==== */
@@ -1,5 +1,5 @@
1
1
  module PyCall
2
- VERSION = "1.5.0"
2
+ VERSION = "1.5.2"
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.5.0
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: 2023-08-25 00:00:00.000000000 Z
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.3.13
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: []