-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathtype.jl
More file actions
83 lines (78 loc) · 2.33 KB
/
type.jl
File metadata and controls
83 lines (78 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
const pyjltypetype = pynew()
function pyjltype_getitem(self::Type, k_)
if pyistuple(k_)
k = pyconvert(Vector{Any}, k_)
pydel!(k_)
Py(self{k...})
else
k = pyconvert(Any, k_)
Py(self{k})
end
end
const PYNUMPYDTYPE = IdDict{Type,Py}()
function pyjltype_numpy_dtype(self::Type)
ans = get!(PYNUMPYDTYPE, self) do
typestr, descr = pytypestrdescr(self)
# unsupported type
if typestr == ""
return PyNULL
end
np = pyimport("numpy")
# simple scalar type
if pyisnull(descr)
return np.dtype(typestr)
end
# We could juse use np.dtype(descr), but when there is padding, np.dtype(descr)
# changes the names of the padding fields from "" to "f{N}". Using this other
# dtype constructor avoids this issue and preserves the invariant:
# np.dtype(eltype(array)) == np.array(array).dtype
names = []
formats = []
offsets = []
for i = 1:fieldcount(self)
nm = fieldname(self, i)
push!(names, nm isa Integer ? "f$(nm-1)" : String(nm))
ts, ds = pytypestrdescr(fieldtype(self, i))
push!(formats, pyisnull(ds) ? ts : ds)
push!(offsets, fieldoffset(self, i))
end
return np.dtype(
pydict(
names = pylist(names),
formats = pylist(formats),
offsets = pylist(offsets),
itemsize = sizeof(self),
),
)
end
if pyisnull(ans)
errset(pybuiltins.AttributeError, "__numpy_dtype__")
end
return ans
end
function init_type()
jl = pyjuliacallmodule
pybuiltins.exec(
pybuiltins.compile(
"""
$("\n"^(@__LINE__()-1))
class TypeValue(AnyValue):
__slots__ = ()
def __getitem__(self, k):
return self._jl_callmethod($(pyjl_methodnum(pyjltype_getitem)), k)
def __setitem__(self, k, v):
raise TypeError("not supported")
def __delitem__(self, k):
raise TypeError("not supported")
@property
def __numpy_dtype__(self):
return self._jl_callmethod($(pyjl_methodnum(pyjltype_numpy_dtype)))
""",
@__FILE__(),
"exec",
),
jl.__dict__,
)
pycopy!(pyjltypetype, jl.TypeValue)
end
pyjltype(::Type) = pyjltypetype