@@ -142,14 +142,37 @@ function pyconvert_get_rules(type::Type, pytype::Py)
142
142
@assert all (pyis (x,y) for (x,y) in zip (omro, omro_))
143
143
144
144
# get the names of the types in the MRO of pytype
145
- mro = String[" $(t. __module__) /$(t. __qualname__) " for t in mro]
145
+ xmro = [[" $(t. __module__) /$(t. __qualname__) " ] for t in mro]
146
+
147
+ # add special names corresponding to certain interfaces
148
+ # these get inserted just above the topmost type satisfying the interface
149
+ for (t, x) in reverse (collect (zip (mro, xmro)))
150
+ if pyhasattr (t, " __array_struct__" )
151
+ push! (x, " <arraystruct>" )
152
+ break
153
+ end
154
+ end
155
+ for (t, x) in reverse (collect (zip (mro, xmro)))
156
+ if pyhasattr (t, " __array_interface__" )
157
+ push! (x, " <arrayinterface>" )
158
+ break
159
+ end
160
+ end
161
+ for (t, x) in reverse (collect (zip (mro, xmro)))
162
+ if pyhasattr (t, " __array__" )
163
+ push! (x, " <array>" )
164
+ break
165
+ end
166
+ end
167
+ for (t, x) in reverse (collect (zip (mro, xmro)))
168
+ if C. PyType_CheckBuffer (getptr (t))
169
+ push! (x, " <buffer>" )
170
+ break
171
+ end
172
+ end
146
173
147
- # add special names
148
- # currently we don't care where they go because they are tested in their own priority (200)
149
- pyhasattr (pytype, " __array_struct__" ) && push! (mro, " <arraystruct>" )
150
- pyhasattr (pytype, " __array_interface__" ) && push! (mro, " <arrayinterface>" )
151
- pyhasattr (pytype, " __array__" ) && push! (mro, " <array>" )
152
- C. PyType_CheckBuffer (getptr (pytype)) && push! (mro, " <buffer>" )
174
+ # flatten to get the MRO as a list of strings
175
+ mro = String[x for xs in xmro for x in xs]
153
176
154
177
# get corresponding rules
155
178
rules = PyConvertRule[rule for tname in mro for rule in get! (Vector{PyConvertRule}, PYCONVERT_RULES, tname)]
@@ -172,7 +195,7 @@ function pyconvert_get_rules(type::Type, pytype::Py)
172
195
# filter out repeated rules
173
196
rules = [rule for (i, rule) in enumerate (rules) if ! any ((rule. func === rules[j]. func) && ((rule. type) <: (rules[j].type) ) for j in 1 : (i- 1 ))]
174
197
175
- # @info "pyconvert" rules
198
+ @debug " pyconvert" type pytype mro = join (mro, " " ) rules
176
199
return Function[pyconvert_fix (rule. type, rule. func) for rule in rules]
177
200
end
178
201
@@ -282,10 +305,10 @@ function init_pyconvert()
282
305
pyconvert_add_rule (" juliacall/As" , Any, pyconvert_rule_jlas, 300 )
283
306
pyconvert_add_rule (" juliacall/ValueBase" , Any, pyconvert_rule_jlvalue, 300 )
284
307
# priority 200: arrays
285
- pyconvert_add_rule (" <arraystruct>" , AbstractArray, pyconvert_rule_array , 200 )
286
- pyconvert_add_rule (" <arrayinterface>" , AbstractArray, pyconvert_rule_array , 200 )
287
- pyconvert_add_rule (" <array>" , AbstractArray, pyconvert_rule_array , 200 )
288
- pyconvert_add_rule (" <buffer>" , AbstractArray, pyconvert_rule_array , 200 )
308
+ pyconvert_add_rule (" <arraystruct>" , PyArray, pyconvert_rule_array_nocopy , 200 )
309
+ pyconvert_add_rule (" <arrayinterface>" , PyArray, pyconvert_rule_array_nocopy , 200 )
310
+ pyconvert_add_rule (" <array>" , PyArray, pyconvert_rule_array_nocopy , 200 )
311
+ pyconvert_add_rule (" <buffer>" , PyArray, pyconvert_rule_array_nocopy , 200 )
289
312
# priority 100: canonical
290
313
pyconvert_add_rule (" builtins/NoneType" , Nothing, pyconvert_rule_none, 100 )
291
314
pyconvert_add_rule (" builtins/bool" , Bool, pyconvert_rule_bool, 100 )
@@ -327,6 +350,14 @@ function init_pyconvert()
327
350
pyconvert_add_rule (" collections.abc/Sequence" , Tuple, pyconvert_rule_iterable)
328
351
pyconvert_add_rule (" collections.abc/Set" , Set, pyconvert_rule_iterable)
329
352
pyconvert_add_rule (" collections.abc/Mapping" , Dict, pyconvert_rule_mapping)
353
+ pyconvert_add_rule (" <arraystruct>" , Array, pyconvert_rule_array)
354
+ pyconvert_add_rule (" <arrayinterface>" , Array, pyconvert_rule_array)
355
+ pyconvert_add_rule (" <array>" , Array, pyconvert_rule_array)
356
+ pyconvert_add_rule (" <buffer>" , Array, pyconvert_rule_array)
357
+ pyconvert_add_rule (" <arraystruct>" , AbstractArray, pyconvert_rule_array)
358
+ pyconvert_add_rule (" <arrayinterface>" , AbstractArray, pyconvert_rule_array)
359
+ pyconvert_add_rule (" <array>" , AbstractArray, pyconvert_rule_array)
360
+ pyconvert_add_rule (" <buffer>" , AbstractArray, pyconvert_rule_array)
330
361
# priority -100: fallbacks
331
362
pyconvert_add_rule (" builtins/object" , Py, pyconvert_rule_object, - 100 )
332
363
# priority -200: explicit
0 commit comments