pycall 1.4.0 → 1.4.1
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/CHANGES.md +5 -0
- data/ext/pycall/gc.c +84 -5
- data/lib/pycall.rb +5 -0
- data/lib/pycall/iterable_wrapper.rb +32 -0
- data/lib/pycall/version.rb +1 -1
- data/lib/pycall/wrapper_object_cache.rb +6 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b016b6c9b12867d113713238ecc171cc4fde8965197c79c59abf66d8bb3b252e
|
4
|
+
data.tar.gz: abb36597376d37744972f7bb537ab61032387c73947d7846b9947bb622bf04ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18bc020ef0c1f1d82e3796ae023170ee287bbf966c3efd12dd48f730eec585b7b70e00352d316e8e524e608c70bff0348937c1afc434ba7d6ae634223f0e1fa6
|
7
|
+
data.tar.gz: 9ea69bb090386a7a280be6a7c779b406f49a3de2da5b406c64529be6a462535cbe9eefaad404e3dd1dab6bc98a5840e2825708f8d1602e1404ab4dbd83ce43b2
|
data/CHANGES.md
CHANGED
data/ext/pycall/gc.c
CHANGED
@@ -1,5 +1,74 @@
|
|
1
1
|
#include "pycall_internal.h"
|
2
2
|
|
3
|
+
struct gcguard {
|
4
|
+
st_table *guarded_objects;
|
5
|
+
};
|
6
|
+
|
7
|
+
static int
|
8
|
+
gcguard_mark_i(st_data_t key, st_data_t val, st_data_t arg)
|
9
|
+
{
|
10
|
+
VALUE obj = (VALUE)val;
|
11
|
+
rb_gc_mark(obj);
|
12
|
+
return ST_CONTINUE;
|
13
|
+
}
|
14
|
+
|
15
|
+
static void
|
16
|
+
gcguard_mark(void* ptr)
|
17
|
+
{
|
18
|
+
struct gcguard *gg = (struct gcguard *)ptr;
|
19
|
+
st_foreach(gg->guarded_objects, gcguard_mark_i, 0);
|
20
|
+
}
|
21
|
+
|
22
|
+
static void
|
23
|
+
gcguard_free(void* ptr)
|
24
|
+
{
|
25
|
+
struct gcguard *gg = (struct gcguard *)ptr;
|
26
|
+
st_free_table(gg->guarded_objects);
|
27
|
+
}
|
28
|
+
|
29
|
+
static size_t
|
30
|
+
gcguard_memsize(const void* ptr)
|
31
|
+
{
|
32
|
+
const struct gcguard *gg = (const struct gcguard *)ptr;
|
33
|
+
return st_memsize(gg->guarded_objects);
|
34
|
+
}
|
35
|
+
|
36
|
+
static rb_data_type_t gcguard_data_type = {
|
37
|
+
"PyCall::gcguard",
|
38
|
+
{
|
39
|
+
gcguard_mark,
|
40
|
+
gcguard_free,
|
41
|
+
gcguard_memsize,
|
42
|
+
},
|
43
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
44
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
45
|
+
#endif
|
46
|
+
};
|
47
|
+
|
48
|
+
static void
|
49
|
+
gcguard_aset(VALUE gcguard, PyObject *pyptr, VALUE rbobj)
|
50
|
+
{
|
51
|
+
struct gcguard *gg;
|
52
|
+
TypedData_Get_Struct(gcguard, struct gcguard, &gcguard_data_type, gg);
|
53
|
+
|
54
|
+
st_insert(gg->guarded_objects, (st_data_t)pyptr, (st_data_t)rbobj);
|
55
|
+
}
|
56
|
+
|
57
|
+
static void
|
58
|
+
gcguard_delete(VALUE gcguard, PyObject *pyptr)
|
59
|
+
{
|
60
|
+
if (rb_typeddata_is_kind_of(gcguard, &gcguard_data_type)) {
|
61
|
+
/* This check is necessary to avoid error on the process finalization phase */
|
62
|
+
struct gcguard *gg;
|
63
|
+
st_data_t key, val;
|
64
|
+
|
65
|
+
TypedData_Get_Struct(gcguard, struct gcguard, &gcguard_data_type, gg);
|
66
|
+
|
67
|
+
key = (st_data_t)pyptr;
|
68
|
+
st_delete(gg->guarded_objects, &key, &val);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
3
72
|
static ID id_gcguard_table;
|
4
73
|
static PyObject *weakref_callback_pyobj;
|
5
74
|
static PyObject *gcguard_weakref_destroyed(PyObject *self, PyObject *weakref);
|
@@ -21,15 +90,15 @@ gcguard_weakref_destroyed(PyObject *self, PyObject *weakref)
|
|
21
90
|
void
|
22
91
|
pycall_gcguard_aset(PyObject *pyobj, VALUE rbobj)
|
23
92
|
{
|
24
|
-
VALUE
|
25
|
-
|
93
|
+
VALUE gcguard = rb_ivar_get(mPyCall, id_gcguard_table);
|
94
|
+
gcguard_aset(gcguard, pyobj, rbobj);
|
26
95
|
}
|
27
96
|
|
28
97
|
void
|
29
98
|
pycall_gcguard_delete(PyObject *pyobj)
|
30
99
|
{
|
31
|
-
VALUE
|
32
|
-
|
100
|
+
VALUE gcguard = rb_ivar_get(mPyCall, id_gcguard_table);
|
101
|
+
gcguard_delete(gcguard, pyobj);
|
33
102
|
}
|
34
103
|
|
35
104
|
void
|
@@ -64,11 +133,21 @@ pycall_gcguard_register(PyObject *pyobj, VALUE obj)
|
|
64
133
|
pycall_gcguard_aset(wref, obj);
|
65
134
|
}
|
66
135
|
|
136
|
+
static VALUE
|
137
|
+
gcguard_new(void)
|
138
|
+
{
|
139
|
+
struct gcguard *gg;
|
140
|
+
VALUE obj = TypedData_Make_Struct(0, struct gcguard, &gcguard_data_type, gg);
|
141
|
+
gg->guarded_objects = st_init_numtable();
|
142
|
+
|
143
|
+
return obj;
|
144
|
+
}
|
145
|
+
|
67
146
|
void
|
68
147
|
pycall_init_gcguard(void)
|
69
148
|
{
|
70
149
|
id_gcguard_table = rb_intern("gcguard_table");
|
71
|
-
rb_ivar_set(mPyCall, id_gcguard_table,
|
150
|
+
rb_ivar_set(mPyCall, id_gcguard_table, gcguard_new());
|
72
151
|
|
73
152
|
weakref_callback_pyobj = Py_API(PyCFunction_NewEx)(&gcguard_weakref_callback_def, NULL, NULL);
|
74
153
|
}
|
data/lib/pycall.rb
CHANGED
@@ -5,6 +5,7 @@ module PyCall
|
|
5
5
|
require 'pycall/pyobject_wrapper'
|
6
6
|
require 'pycall/pytypeobject_wrapper'
|
7
7
|
require 'pycall/pymodule_wrapper'
|
8
|
+
require 'pycall/iterable_wrapper'
|
8
9
|
require 'pycall/init'
|
9
10
|
|
10
11
|
module_function
|
@@ -73,6 +74,10 @@ module PyCall
|
|
73
74
|
LibPython::Helpers.import_module(name)
|
74
75
|
end
|
75
76
|
|
77
|
+
def iterable(obj)
|
78
|
+
IterableWrapper.new(obj)
|
79
|
+
end
|
80
|
+
|
76
81
|
def len(obj)
|
77
82
|
case obj
|
78
83
|
when PyObjectWrapper
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module PyCall
|
2
|
+
class IterableWrapper
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(obj)
|
6
|
+
@obj = check_iterable(obj)
|
7
|
+
end
|
8
|
+
|
9
|
+
private def check_iterable(obj)
|
10
|
+
unless PyCall.hasattr?(obj, :__iter__)
|
11
|
+
raise ArgumentError, "%p object is not iterable" % obj
|
12
|
+
end
|
13
|
+
obj
|
14
|
+
end
|
15
|
+
|
16
|
+
def each
|
17
|
+
return enum_for(__method__) unless block_given?
|
18
|
+
iter = @obj.__iter__()
|
19
|
+
while true
|
20
|
+
begin
|
21
|
+
yield iter.__next__()
|
22
|
+
rescue PyCall::PyError => err
|
23
|
+
if err.type == PyCall.builtins.StopIteration
|
24
|
+
break
|
25
|
+
else
|
26
|
+
raise err
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/pycall/version.rb
CHANGED
@@ -6,7 +6,12 @@ module PyCall
|
|
6
6
|
rescue
|
7
7
|
WMAP_SUPPORT_INT_KEY = false
|
8
8
|
else
|
9
|
-
|
9
|
+
case RUBY_PLATFORM
|
10
|
+
when /cygwin/, /mingw/, /mswin/
|
11
|
+
WMAP_SUPPORT_INT_KEY = false
|
12
|
+
else
|
13
|
+
WMAP_SUPPORT_INT_KEY = true
|
14
|
+
end
|
10
15
|
end
|
11
16
|
|
12
17
|
if WMAP_SUPPORT_INT_KEY
|
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.
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenta Murata
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -196,6 +196,7 @@ files:
|
|
196
196
|
- lib/pycall/import.rb
|
197
197
|
- lib/pycall/init.rb
|
198
198
|
- lib/pycall/iruby_helper.rb
|
199
|
+
- lib/pycall/iterable_wrapper.rb
|
199
200
|
- lib/pycall/libpython.rb
|
200
201
|
- lib/pycall/libpython/finder.rb
|
201
202
|
- lib/pycall/libpython/pyobject_struct.rb
|
@@ -235,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
235
236
|
- !ruby/object:Gem::Version
|
236
237
|
version: '0'
|
237
238
|
requirements: []
|
238
|
-
rubygems_version: 3.2.
|
239
|
+
rubygems_version: 3.2.21
|
239
240
|
signing_key:
|
240
241
|
specification_version: 4
|
241
242
|
summary: pycall
|