[ANN] pyml_bindgen: a CLI app to generate Python bindings directly from OCaml value specifications

New releases

Version 0.3.0 and 0.3.1 are now available on GitHub. 0.3.0 has been merged into opam, and a PR for 0.3.1 has been opened. The change log has more details about the changes.

Binding tuples

You can now bind tuples directly. Here’s a Python function that takes two lists of points (where each “point” is a tuple like (x, y)) and adds them together

def add(points1, points2):
    return [(x1 + y1, x2 + y2) for (x1, x2), (y1, y2) in zip(points1, points2)]

And you could bind it using tuples from the OCaml side as well.

val add : points1:(int * int) list -> points2:(int * int) list -> unit -> (int * int) list

Note there are some restrictions regarding tuples, which you can read about here, here, or here.

Attributes

You can use attributes on value specifications. Currently the only one supported is py_fun_name, which allows you to decouple the Python method name and the generated OCaml function name.

As an example, take the following Python function, which adds to “things”.

def add(x, y):
    return x + y

You could bind multiple OCaml functions to this single function now.

val add_int : x:int -> y:int -> unit -> int
[@@py_fun_name add]

val add_float : x:float -> y:float -> unit -> float
[@@py_fun_name add]

val add_string : x:string -> y:string -> unit -> string
[@@py_fun_name add]

Python magic methods

This is also nice for binding Python magic methods. For example, you don’t have to use __init__ as the name of the OCaml function you use to make instances of a Python class. You can bind it to a more natural name like create or make.

val create : name:string -> age:int -> unit -> t
[@@py_fun_name __init__]

Using Pytypes.pyobject directly

Sometimes you may not want to bother converting Python types to normal OCaml types at all. You can do that now in value specifications by using the Pytypes.pyobject and Py.Object.t types directly.

Fewer dependencies

re is now used instead of re2, which drops the number of dependencies that need to be installed by about half. Additionally, core, core_bench, and bisect_ppx don’t need to be installed if you want to install pyml_bindgen directly from the git repository, which greatly cuts the required dependencies in this case.

Thanks again to UnixJunkie for spurring many of these updates!

7 Likes