Skip to content

Commit a954914

Browse files
committed
Add Julia._unbox_as
1 parent 9d1833f commit a954914

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
@@ -346,6 +346,22 @@ def is_compatible_exe(jlinfo, _debug=lambda *_: None):
346346

347347
_julia_runtime = [False]
348348

349+
350+
UNBOXABLE_TYPES = (
351+
'bool',
352+
'int8',
353+
'uint8',
354+
'int16',
355+
'uint16',
356+
'int32',
357+
'uint32',
358+
'int64',
359+
'uint64',
360+
'float32',
361+
'float64',
362+
)
363+
364+
349365
class Julia(object):
350366
"""
351367
Implements a bridge to the Julia interpreter or library.
@@ -460,6 +476,17 @@ def __init__(self, init_julia=True, jl_runtime_path=None, jl_init_path=None,
460476
self.api.jl_unbox_voidpointer.argtypes = [void_p]
461477
self.api.jl_unbox_voidpointer.restype = py_object
462478

479+
for c_type in UNBOXABLE_TYPES:
480+
jl_unbox = getattr(self.api, "jl_unbox_{}".format(c_type))
481+
jl_unbox.argtypes = [void_p]
482+
jl_unbox.restype = getattr(ctypes, "c_{}".format({
483+
"float32": "float",
484+
"float64": "double",
485+
}.get(c_type, c_type)))
486+
487+
self.api.jl_typeof.argtypes = [void_p]
488+
self.api.jl_typeof.restype = void_p
489+
463490
self.api.jl_exception_clear.restype = None
464491
self.api.jl_stderr_obj.argtypes = []
465492
self.api.jl_stderr_obj.restype = void_p
@@ -557,6 +584,29 @@ def _call(self, src):
557584

558585
return ans
559586

587+
@staticmethod
588+
def _check_unboxable(c_type):
589+
if c_type not in UNBOXABLE_TYPES:
590+
raise ValueError("Julia value cannot be unboxed as c_type={!r}.\n"
591+
"c_type supported by PyJulia are:\n"
592+
"{}".format(c_type, "\n".join(UNBOXABLE_TYPES)))
593+
594+
def _is_unboxable_as(self, pointer, c_type):
595+
self._check_unboxable(c_type)
596+
jl_type = getattr(self.api, 'jl_{}_type'.format(c_type))
597+
desired = ctypes.cast(jl_type, ctypes.POINTER(ctypes.c_void_p))[0]
598+
actual = self.api.jl_typeof(pointer)
599+
return actual == desired
600+
601+
def _unbox_as(self, pointer, c_type):
602+
self._check_unboxable(c_type)
603+
jl_unbox = getattr(self.api, 'jl_unbox_{}'.format(c_type))
604+
if self._is_unboxable_as(pointer, c_type):
605+
return jl_unbox(pointer)
606+
else:
607+
raise TypeError("Cannot unbox pointer {} as {}"
608+
.format(pointer, c_type))
609+
560610
def check_exception(self, src="<unknown code>"):
561611
exoc = self.api.jl_exception_occurred()
562612
self._debug("exception occured? " + str(exoc))

0 commit comments

Comments
 (0)