@@ -346,6 +346,22 @@ def is_compatible_exe(jlinfo, _debug=lambda *_: None):
346
346
347
347
_julia_runtime = [False ]
348
348
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
+
349
365
class Julia (object ):
350
366
"""
351
367
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,
460
476
self .api .jl_unbox_voidpointer .argtypes = [void_p ]
461
477
self .api .jl_unbox_voidpointer .restype = py_object
462
478
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
+
463
490
self .api .jl_exception_clear .restype = None
464
491
self .api .jl_stderr_obj .argtypes = []
465
492
self .api .jl_stderr_obj .restype = void_p
@@ -557,6 +584,29 @@ def _call(self, src):
557
584
558
585
return ans
559
586
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
+
560
610
def check_exception (self , src = "<unknown code>" ):
561
611
exoc = self .api .jl_exception_occurred ()
562
612
self ._debug ("exception occured? " + str (exoc ))
0 commit comments