@@ -294,6 +294,22 @@ def is_different_exe(pyprogramname, sys_executable):
294
294
295
295
_julia_runtime = [False ]
296
296
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
+
297
313
class Julia (object ):
298
314
"""
299
315
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,
407
423
self .api .jl_typeof_str .restype = char_p
408
424
self .api .jl_unbox_voidpointer .restype = py_object
409
425
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
+
410
437
self .api .jl_exception_clear .restype = None
411
438
self .api .jl_stderr_obj .argtypes = []
412
439
self .api .jl_stderr_obj .restype = void_p
@@ -489,6 +516,29 @@ def _call(self, src):
489
516
490
517
return ans
491
518
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
+
492
542
def check_exception (self , src = None ):
493
543
exoc = self .api .jl_exception_occurred ()
494
544
self ._debug ("exception occured? " + str (exoc ))
0 commit comments