pycall 1.5.0 → 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 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: []