Skip to content

Commit d9db81f

Browse files
author
Christopher Doris
committed
numpy and ctypes conversions
1 parent dacb7a9 commit d9db81f

File tree

7 files changed

+168
-275
lines changed

7 files changed

+168
-275
lines changed

src/PythonCall.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ include("concrete/fraction.jl")
4040
include("concrete/method.jl")
4141
include("concrete/datetime.jl")
4242
include("concrete/code.jl")
43+
include("concrete/ctypes.jl")
44+
include("concrete/numpy.jl")
4345
# @py
4446
# anything below can depend on @py, anything above cannot
4547
include("py_macro.jl")
@@ -105,6 +107,8 @@ function __init__()
105107
init_gui()
106108
init_ipython()
107109
init_tables()
110+
init_numpy()
111+
init_ctypes()
108112
end
109113
@require PyCall="438e738f-606a-5dbb-bf0a-cddfbfd45ab0" init_pycall(PyCall)
110114
end

src/concrete/ctypes.jl

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
struct pyconvert_rule_ctypessimplevalue{R,S} <: Function end
2+
3+
function (::pyconvert_rule_ctypessimplevalue{R,SAFE})(::Type{T}, x::Py) where {R,SAFE,T}
4+
ptr = GC.@preserve x C.PySimpleObject_GetValue(Ptr{R}, getptr(x))
5+
ans = unsafe_load(ptr)
6+
if SAFE
7+
pyconvert_return(convert(T, ans))
8+
else
9+
pyconvert_tryconvert(T, ans)
10+
end
11+
end
12+
13+
const CTYPES_SIMPLE_TYPES = [
14+
("char", Cchar),
15+
("wchar", Cwchar_t),
16+
("byte", Cchar),
17+
("ubyte", Cuchar),
18+
("short", Cshort),
19+
("ushort", Cushort),
20+
("int", Cint),
21+
("uint", Cuint),
22+
("long", Clong),
23+
("ulong", Culong),
24+
("longlong", Clonglong),
25+
("ulonglong", Culonglong),
26+
("size_t", Csize_t),
27+
("ssize_t", Cssize_t),
28+
("float", Cfloat),
29+
("double", Cdouble),
30+
("char_p", Ptr{Cchar}),
31+
("wchar_p", Ptr{Cwchar_t}),
32+
("void_p", Ptr{Cvoid}),
33+
]
34+
35+
function init_ctypes()
36+
for (t,T) in CTYPES_SIMPLE_TYPES
37+
isptr = endswith(t, "_p")
38+
isreal = !isptr
39+
isnumber = isreal
40+
isfloat = t in ("float", "double")
41+
isint = isreal && !isfloat
42+
isuint = isint && (startswith(t, "u") || t == "size_t")
43+
44+
name = "ctypes/c_$t"
45+
rule = pyconvert_rule_ctypessimplevalue{T, false}()
46+
saferule = pyconvert_rule_ctypessimplevalue{T, true}()
47+
48+
t == "char_p" && pyconvert_add_rule(name, Cstring, saferule)
49+
t == "wchar_p" && pyconvert_add_rule(name, Cwstring, saferule)
50+
pyconvert_add_rule(name, T, saferule)
51+
isuint && pyconvert_add_rule(name, UInt, sizeof(T) sizeof(UInt) ? saferule : rule)
52+
isuint && pyconvert_add_rule(name, Int, sizeof(T) < sizeof(Int) ? saferule : rule)
53+
isint && !isuint && pyconvert_add_rule(name, Int, sizeof(T) sizeof(Int) ? saferule : rule)
54+
isint && pyconvert_add_rule(name, Integer, rule)
55+
isfloat && pyconvert_add_rule(name, Float64, saferule)
56+
isreal && pyconvert_add_rule(name, Real, rule)
57+
isnumber && pyconvert_add_rule(name, Number, rule)
58+
isptr && pyconvert_add_rule(name, Ptr, saferule)
59+
end
60+
end

src/concrete/numpy.jl

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
struct pyconvert_rule_numpysimplevalue{R,S} <: Function end
2+
3+
function (::pyconvert_rule_numpysimplevalue{R,SAFE})(::Type{T}, x::Py) where {R,SAFE,T}
4+
ans = GC.@preserve x C.PySimpleObject_GetValue(R, getptr(x))
5+
if SAFE
6+
pyconvert_return(convert(T, ans))
7+
else
8+
pyconvert_tryconvert(T, ans)
9+
end
10+
end
11+
12+
const NUMPY_SIMPLE_TYPES = [
13+
("int8", Int8),
14+
("int16", Int16),
15+
("int32", Int32),
16+
("int64", Int64),
17+
("uint8", UInt8),
18+
("uint16", UInt16),
19+
("uint32", UInt32),
20+
("uint64", UInt64),
21+
("float16", Float16),
22+
("float32", Float32),
23+
("float64", Float64),
24+
("complex32", ComplexF16),
25+
("complex64", ComplexF32),
26+
("complex128", ComplexF64),
27+
]
28+
29+
function init_numpy()
30+
for (t,T) in NUMPY_SIMPLE_TYPES
31+
isint = occursin("int", t)
32+
isuint = occursin("uint", t)
33+
isfloat = occursin("float", t)
34+
iscomplex = occursin("complex", t)
35+
isreal = isint || isfloat
36+
isnumber = isreal || iscomplex
37+
38+
name = "numpy/$t"
39+
rule = pyconvert_rule_numpysimplevalue{T, false}()
40+
saferule = pyconvert_rule_numpysimplevalue{T, true}()
41+
42+
pyconvert_add_rule(name, T, saferule, 100)
43+
isuint && pyconvert_add_rule(name, UInt, sizeof(T) sizeof(UInt) ? saferule : rule)
44+
isuint && pyconvert_add_rule(name, Int, sizeof(T) < sizeof(Int) ? saferule : rule)
45+
isint && !isuint && pyconvert_add_rule(name, Int, sizeof(T) sizeof(Int) ? saferule : rule)
46+
isint && pyconvert_add_rule(name, Integer, rule)
47+
isfloat && pyconvert_add_rule(name, Float64, saferule)
48+
isreal && pyconvert_add_rule(name, Real, rule)
49+
iscomplex && pyconvert_add_rule(name, ComplexF64, saferule)
50+
iscomplex && pyconvert_add_rule(name, Complex, rule)
51+
isnumber && pyconvert_add_rule(name, Number, rule)
52+
end
53+
end

src/cpython/extras.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ function PyOS_RunInputHook()
5151
end
5252
end
5353

54+
function PySimpleObject_GetValue(::Type{T}, o::PyPtr) where {T}
55+
UnsafePtr{PySimpleObject{T}}(o).value[!]
56+
end
57+
5458
# FAST REFCOUNTING
5559
#
5660
# _Py_IncRef(o) = ccall(POINTERS.Py_IncRef, Cvoid, (PyPtr,), o)

src/old/cpython/CPython.jl

Lines changed: 0 additions & 247 deletions
This file was deleted.

src/old/cpython/ctypes.jl

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)