Skip to content

Commit

Permalink
Add Julia._unbox_as
Browse files Browse the repository at this point in the history
  • Loading branch information
tkf committed Aug 18, 2018
1 parent a1f0b4b commit 5d577a2
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions julia/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,22 @@ def is_different_exe(pyprogramname, sys_executable):

_julia_runtime = [False]


UNBOXABLE_TYPES = (
'bool',
'int8',
'uint8',
'int16',
'uint16',
'int32',
'uint32',
'int64',
'uint64',
'float32',
'float64',
)


class Julia(object):
"""
Implements a bridge to the Julia interpreter or library.
Expand Down Expand Up @@ -407,6 +423,17 @@ def __init__(self, init_julia=True, jl_runtime_path=None, jl_init_path=None,
self.api.jl_typeof_str.restype = char_p
self.api.jl_unbox_voidpointer.restype = py_object

for c_type in UNBOXABLE_TYPES:
jl_unbox = getattr(self.api, "jl_unbox_{}".format(c_type))
jl_unbox.argtypes = [void_p]
jl_unbox.restype = getattr(ctypes, "c_{}".format({
"float32": "float",
"float64": "double",
}.get(c_type, c_type)))

self.api.jl_typeof.argtypes = [void_p]
self.api.jl_typeof.restype = void_p

self.api.jl_exception_clear.restype = None
self.api.jl_stderr_obj.argtypes = []
self.api.jl_stderr_obj.restype = void_p
Expand Down Expand Up @@ -489,6 +516,29 @@ def _call(self, src):

return ans

@staticmethod
def _check_unboxable(c_type):
if c_type not in UNBOXABLE_TYPES:
raise ValueError("Julia value cannot be unboxed as c_type={!r}.\n"
"c_type supported by PyJulia are:\n"
"{}".format(c_type, "\n".join(UNBOXABLE_TYPES)))

def _is_unboxable_as(self, pointer, c_type):
self._check_unboxable(c_type)
jl_type = getattr(self.api, 'jl_{}_type'.format(c_type))
desired = ctypes.cast(jl_type, ctypes.POINTER(ctypes.c_void_p))[0]
actual = self.api.jl_typeof(pointer)
return actual == desired

def _unbox_as(self, pointer, c_type):
self._check_unboxable(c_type)
jl_unbox = getattr(self.api, 'jl_unbox_{}'.format(c_type))
if self._is_unboxable_as(pointer, c_type):
return jl_unbox(pointer)
else:
raise TypeError("Cannot unbox pointer {} as {}"
.format(pointer, c_type))

def check_exception(self, src=None):
exoc = self.api.jl_exception_occurred()
self._debug("exception occured? " + str(exoc))
Expand Down

0 comments on commit 5d577a2

Please sign in to comment.