@@ -37,28 +37,47 @@ const CTYPES_SIMPLE_TYPES = [
3737function init_ctypes ()
3838 for (t, T) in CTYPES_SIMPLE_TYPES
3939 isptr = endswith (t, " _p" )
40- isreal = ! isptr
41- isnumber = isreal
40+ isnumber = ! isptr
4241 isfloat = t in (" float" , " double" )
43- isint = isreal && ! isfloat
42+ isint = isnumber && ! isfloat
4443 isuint = isint && (startswith (t, " u" ) || t == " size_t" )
4544
4645 name = " ctypes:c_$t "
4746 rule = pyconvert_rule_ctypessimplevalue {T,false} ()
4847 saferule = pyconvert_rule_ctypessimplevalue {T,true} ()
4948
50- t == " char_p" && pyconvert_add_rule (name, Cstring, Cstring, saferule)
51- t == " wchar_p" && pyconvert_add_rule (name, Cwstring, Cwstring, saferule)
52- pyconvert_add_rule (name, T, T, saferule)
53- isuint && pyconvert_add_rule (name, UInt, UInt, sizeof (T) ≤ sizeof (UInt) ? saferule : rule)
54- isuint && pyconvert_add_rule (name, Int, Int, sizeof (T) < sizeof (Int) ? saferule : rule)
55- isint &&
56- ! isuint &&
57- pyconvert_add_rule (name, Int, Int, sizeof (T) ≤ sizeof (Int) ? saferule : rule)
58- isint && pyconvert_add_rule (name, Integer, Integer, rule)
59- isfloat && pyconvert_add_rule (name, Float64, Float64, saferule)
60- isreal && pyconvert_add_rule (name, Real, Real, rule)
61- isnumber && pyconvert_add_rule (name, Number, Number, rule)
62- isptr && pyconvert_add_rule (name, Ptr, Ptr, saferule)
49+ if isnumber
50+ # Rules added later are tried first. Prefer the source's exact Julia type,
51+ # followed by increasingly general lossless representations, before allowing
52+ # conversion to floating-point and other number types.
53+ pyconvert_add_rule (name, Number, Number, rule)
54+ pyconvert_add_rule (name, Real, Number, rule)
55+ pyconvert_add_rule (name, AbstractFloat, Number, rule)
56+ if isint
57+ pyconvert_add_rule (name, Integer, Number, rule)
58+ pyconvert_add_rule (name, isuint ? Unsigned : Signed, Number, rule)
59+ if isuint
60+ pyconvert_add_rule (
61+ name,
62+ UInt,
63+ Number,
64+ sizeof (T) ≤ sizeof (UInt) ? saferule : rule,
65+ )
66+ else
67+ pyconvert_add_rule (
68+ name,
69+ Int,
70+ Number,
71+ sizeof (T) ≤ sizeof (Int) ? saferule : rule,
72+ )
73+ end
74+ elseif isfloat
75+ pyconvert_add_rule (name, Float64, Number, saferule)
76+ end
77+ pyconvert_add_rule (name, T, Number, saferule)
78+ elseif isptr
79+ pyconvert_add_rule (name, Ptr, Ptr, saferule)
80+ pyconvert_add_rule (name, T, Ptr, saferule)
81+ end
6382 end
6483end
0 commit comments