Skip to content

Commit 5d577a2

Browse files
committed
Add Julia._unbox_as
1 parent a1f0b4b commit 5d577a2

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

julia/core.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,22 @@ def is_different_exe(pyprogramname, sys_executable):
294294

295295
_julia_runtime = [False]
296296

297+
298+
UNBOXABLE_TYPES = (
299+
'bool',
300+
'int8',
301+
'uint8',
302+
'int16',
303+
'uint16',
304+
'int32',
305+
'uint32',
306+
'int64',
307+
'uint64',
308+
'float32',
309+
'float64',
310+
)
311+
312+
297313
class Julia(object):
298314
"""
299315
Implements a bridge to the Julia interpreter or library.
@@ -407,6 +423,17 @@ def __init__(self, init_julia=True, jl_runtime_path=None, jl_init_path=None,
407423
self.api.jl_typeof_str.restype = char_p
408424
self.api.jl_unbox_voidpointer.restype = py_object
409425

426+
for c_type in UNBOXABLE_TYPES:
427+
jl_unbox = getattr(self.api, "jl_unbox_{}".format(c_type))
428+
jl_unbox.argtypes = [void_p]
429+
jl_unbox.restype = getattr(ctypes, "c_{}".format({
430+
"float32": "float",
431+
"float64": "double",
432+
}.get(c_type, c_type)))
433+
434+
self.api.jl_typeof.argtypes = [void_p]
435+
self.api.jl_typeof.restype = void_p
436+
410437
self.api.jl_exception_clear.restype = None
411438
self.api.jl_stderr_obj.argtypes = []
412439
self.api.jl_stderr_obj.restype = void_p
@@ -489,6 +516,29 @@ def _call(self, src):
489516

490517
return ans
491518

519+
@staticmethod
520+
def _check_unboxable(c_type):
521+
if c_type not in UNBOXABLE_TYPES:
522+
raise ValueError("Julia value cannot be unboxed as c_type={!r}.\n"
523+
"c_type supported by PyJulia are:\n"
524+
"{}".format(c_type, "\n".join(UNBOXABLE_TYPES)))
525+
526+
def _is_unboxable_as(self, pointer, c_type):
527+
self._check_unboxable(c_type)
528+
jl_type = getattr(self.api, 'jl_{}_type'.format(c_type))
529+
desired = ctypes.cast(jl_type, ctypes.POINTER(ctypes.c_void_p))[0]
530+
actual = self.api.jl_typeof(pointer)
531+
return actual == desired
532+
533+
def _unbox_as(self, pointer, c_type):
534+
self._check_unboxable(c_type)
535+
jl_unbox = getattr(self.api, 'jl_unbox_{}'.format(c_type))
536+
if self._is_unboxable_as(pointer, c_type):
537+
return jl_unbox(pointer)
538+
else:
539+
raise TypeError("Cannot unbox pointer {} as {}"
540+
.format(pointer, c_type))
541+
492542
def check_exception(self, src=None):
493543
exoc = self.api.jl_exception_occurred()
494544
self._debug("exception occured? " + str(exoc))

0 commit comments

Comments
 (0)