@@ -12,8 +12,8 @@ struct PyConvertRule
1212 priority:: PyConvertPriority
1313end
1414
15- const PYCONVERT_RULES = Dict {String,Vector{PyConvertRule}} ()
16- const PYCONVERT_EXTRATYPES = Py[]
15+ const PYCONVERT_RULES = Lockable ( Dict {String,Vector{PyConvertRule}} () )
16+ const PYCONVERT_EXTRATYPES = Lockable ( Py[])
1717
1818"""
1919 pyconvert_add_rule(tname::String, T::Type, func::Function, priority::PyConvertPriority=PYCONVERT_PRIORITY_NORMAL)
@@ -69,11 +69,11 @@ function pyconvert_add_rule(
6969 priority:: PyConvertPriority = PYCONVERT_PRIORITY_NORMAL,
7070)
7171 @nospecialize type func
72- push! (
73- get! (Vector{PyConvertRule}, PYCONVERT_RULES, pytypename),
72+ Base . @lock PYCONVERT_RULES push! (
73+ get! (Vector{PyConvertRule}, PYCONVERT_RULES[] , pytypename),
7474 PyConvertRule (type, func, priority),
7575 )
76- Base. @lock PYCONVERT_RULES_CACHE_LOCK empty! .(values (PYCONVERT_RULES_CACHE))
76+ Base. @lock PYCONVERT_RULES_CACHE empty! .(values (PYCONVERT_RULES_CACHE[] ))
7777 return
7878end
7979
@@ -163,7 +163,7 @@ function _pyconvert_get_rules(pytype::Py)
163163 omro = collect (pytype. __mro__)
164164 basetypes = Py[pytype]
165165 basemros = Vector{Py}[omro]
166- for xtype in PYCONVERT_EXTRATYPES
166+ Base . @lock PYCONVERT_EXTRATYPES for xtype in PYCONVERT_EXTRATYPES[]
167167 # find the topmost supertype of
168168 xbase = PyNULL
169169 for base in omro
@@ -248,9 +248,9 @@ function _pyconvert_get_rules(pytype::Py)
248248 mro = String[x for xs in xmro for x in xs]
249249
250250 # get corresponding rules
251- rules = PyConvertRule[
251+ rules = Base . @lock PYCONVERT_RULES PyConvertRule[
252252 rule for tname in mro for
253- rule in get! (Vector{PyConvertRule}, PYCONVERT_RULES, tname)
253+ rule in get! (Vector{PyConvertRule}, PYCONVERT_RULES[] , tname)
254254 ]
255255
256256 # order the rules by priority, then by original order
@@ -261,11 +261,10 @@ function _pyconvert_get_rules(pytype::Py)
261261 return rules
262262end
263263
264- const PYCONVERT_PREFERRED_TYPE = Dict {Py,Type} ()
265- const PYCONVERT_PREFERRED_TYPE_LOCK = Threads. SpinLock ()
264+ const PYCONVERT_PREFERRED_TYPE = Lockable (Dict {Py,Type} ())
266265
267266pyconvert_preferred_type (pytype:: Py ) =
268- Base. @lock PYCONVERT_PREFERRED_TYPE_LOCK get! (PYCONVERT_PREFERRED_TYPE, pytype) do
267+ Base. @lock PYCONVERT_PREFERRED_TYPE get! (PYCONVERT_PREFERRED_TYPE[] , pytype) do
269268 if pyissubclass (pytype, pybuiltins. int)
270269 Union{Int,BigInt}
271270 else
@@ -308,11 +307,10 @@ end
308307
309308pyconvert_fix (:: Type{T} , func) where {T} = x -> func (T, x)
310309
311- const PYCONVERT_RULES_CACHE = Dict {Type,Dict{C.PyPtr,Vector{Function}}} ()
312- const PYCONVERT_RULES_CACHE_LOCK = Threads. SpinLock ()
310+ const PYCONVERT_RULES_CACHE = Lockable (Dict {Type,Dict{C.PyPtr,Vector{Function}}} ())
313311
314312@generated pyconvert_rules_cache (:: Type{T} ) where {T} =
315- Base. @lock PYCONVERT_RULES_CACHE_LOCK get! (Dict{C. PyPtr,Vector{Function}}, PYCONVERT_RULES_CACHE, T)
313+ Base. @lock PYCONVERT_RULES_CACHE get! (Dict{C. PyPtr,Vector{Function}}, PYCONVERT_RULES_CACHE[] , T)
316314
317315function pyconvert_rule_fast (:: Type{T} , x:: Py ) where {T}
318316 if T isa Union
@@ -353,12 +351,13 @@ function pytryconvert(::Type{T}, x_) where {T}
353351 # get rules from the cache
354352 # TODO : we should hold weak references and clear the cache if types get deleted
355353 tptr = C. Py_Type (x)
356- trules = pyconvert_rules_cache (T)
357- rules = Base. @lock PYCONVERT_RULES_CACHE_LOCK get! (trules, tptr) do
358- t = pynew (incref (tptr))
359- ans = pyconvert_get_rules (T, t):: Vector{Function}
360- pydel! (t)
361- ans
354+ rules = Base. @lock PYCONVERT_RULES_CACHE let trules = pyconvert_rules_cache (T)
355+ get! (trules, tptr) do
356+ t = pynew (incref (tptr))
357+ ans = pyconvert_get_rules (T, t):: Vector{Function}
358+ pydel! (t)
359+ ans
360+ end
362361 end
363362
364363 # apply the rules
@@ -420,15 +419,17 @@ pyconvertarg(::Type{T}, x, name) where {T} = @autopy x @pyconvert T x_ begin
420419end
421420
422421function init_pyconvert ()
423- push! (PYCONVERT_EXTRATYPES, pyimport (" io" => " IOBase" ))
424- push! (
425- PYCONVERT_EXTRATYPES,
426- pyimport (" numbers" => (" Number" , " Complex" , " Real" , " Rational" , " Integral" ))... ,
427- )
428- push! (
429- PYCONVERT_EXTRATYPES,
430- pyimport (" collections.abc" => (" Iterable" , " Sequence" , " Set" , " Mapping" ))... ,
431- )
422+ Base. @lock PYCONVERT_EXTRATYPES begin
423+ push! (PYCONVERT_EXTRATYPES[], pyimport (" io" => " IOBase" ))
424+ push! (
425+ PYCONVERT_EXTRATYPES[],
426+ pyimport (" numbers" => (" Number" , " Complex" , " Real" , " Rational" , " Integral" ))... ,
427+ )
428+ push! (
429+ PYCONVERT_EXTRATYPES[],
430+ pyimport (" collections.abc" => (" Iterable" , " Sequence" , " Set" , " Mapping" ))... ,
431+ )
432+ end
432433
433434 priority = PYCONVERT_PRIORITY_CANONICAL
434435 pyconvert_add_rule (" builtins:NoneType" , Nothing, pyconvert_rule_none, priority)
0 commit comments