Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
py_type.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
module P = Py_base let type_name obj = let ptr = P.Object.to_c_ptr obj |> Ctypes.from_voidp Init._Py_object in if Ctypes.is_null ptr then None else let ob_type = Ctypes.getf (Ctypes.(!@) ptr) Init.ob_type in if Ctypes.is_null ob_type then None else Some (Ctypes.getf (Ctypes.(!@) ob_type) Init.tp_name) let tp_flags obj = let ptr = P.Object.to_c_ptr obj |> Ctypes.from_voidp Init._Py_object in if Ctypes.is_null ptr then None else let ob_type = Ctypes.getf (Ctypes.(!@) ptr) Init.ob_type in if Ctypes.is_null ob_type then None else let tp_flags = Ctypes.getf (Ctypes.(!@) ob_type) Init.tp_flags in Some (Unsigned.ULong.to_int tp_flags) let has_flag' tp_flags ~flag_id = match tp_flags with | None -> false | Some tp_flags -> (tp_flags land (1 lsl flag_id)) <> 0 let has_flag obj ~flag_id = tp_flags obj |> has_flag' ~flag_id (* The related cpython constants can be found in: https://github.com/python/cpython/blob/master/Include/object.h *) let long_subclass = has_flag ~flag_id:24 let list_subclass = has_flag ~flag_id:25 let tuple_subclass = has_flag ~flag_id:26 let bytes_subclass = has_flag ~flag_id:27 let unicode_subclass = has_flag ~flag_id:28 let dict_subclass = has_flag ~flag_id:29 let base_exc_subclass = has_flag ~flag_id:30 let type_subclass = has_flag ~flag_id:31 (* Floats are not handled in the same way as other basic types so we compare the object type with the float object type. This will not work for float subclasses. *) let is_float obj = let ptr = P.Object.to_c_ptr obj |> Ctypes.from_voidp Init._Py_object in if Ctypes.is_null ptr then false else let ob_type = Ctypes.getf (Ctypes.(!@) ptr) Init.ob_type in Ctypes.ptr_compare ob_type Init._PyFloat_Type = 0 type t = | Null | None | Long | List | Tuple | Bytes | Unicode | Dict | Base_exc | Type | Float let get obj = if P.Object.is_null obj then [ Null ] else if P.Object.is_none obj then [ None ] else let tp_flags = tp_flags obj in let maybe_add v ~flag_id acc = if has_flag' tp_flags ~flag_id then v :: acc else acc in (if is_float obj then [ Float ] else []) |> maybe_add Long ~flag_id:24 |> maybe_add List ~flag_id:25 |> maybe_add Tuple ~flag_id:26 |> maybe_add Bytes ~flag_id:27 |> maybe_add Unicode ~flag_id:28 |> maybe_add Dict ~flag_id:29 |> maybe_add Base_exc ~flag_id:30 |> maybe_add Type ~flag_id:31 let rec of_object obj : P.t = match get obj with | [ Null ] | [ None ] -> Nil | [ Float ] -> Float (P.Object.to_float obj) | [ Long ] -> Int (P.Object.to_int obj) | [ List ] -> List (P.Object.to_list of_object obj) | [ Tuple ] -> Tuple (P.Object.to_array of_object obj) | [ Bytes ] -> Bytes (P.Object.to_bytes obj) | [ Unicode ] -> String (P.Object.to_string obj) | [ Dict ] -> Dict (P.PyDict.items of_object of_object obj) | _ -> Ptr obj