So this is sort of a subtly weird thing that can trip you up if you're not careful.
Say you have a python fun like this:
def say_hi(self, to_whom=None, greeting='hi'):
if to_whom:
return(f'{self.name} says {greeting} to {to_whom.name}')
else:
return(f'{self.name} says {greeting}')
Given that to_whom takes None in the python, you decide to make it explicit in the OCaml binding.
val say_hi : t -> to_whom:t option -> greeting:string option -> unit -> string
However, this generates code that has the wrong signature
let say_hi t ~to_whom ~greeting () =
let callable = Py.Object.find_attr_string t "say_hi" in
let kwargs =
filter_opt
[
Some ("to_whom", to_pyobject to_whom);
Some
( "greeting",
(function Some x -> Py.String.of_string x | None -> Py.none)
greeting );
]
in
Py.String.to_string
@@ Py.Callable.to_function_with_keywords callable [||] kwargs
That sig is val say_hi : t -> to_whom:t -> greeting:string option -> unit -> string.
To make that arg actually optional with t, you would have to do this instead.
val say_hi2 : t -> ?to_whom:t -> greeting:string option -> unit -> string
Note that this problem is only there for t option and custom option eg Doc.t option.
Fixing it
It's not straightforward to fix as t option as an argument passed to a python function and t option as a return type of an OCaml function need to be treated differently (and that depends on the --of-pyo-ret-type flag).
Short term fix is to document the weirdness and give an error when users try to use t option in this way. Currently, the bindings will be generated and you won't know something is wrong until you try to build it.
Long term is to actually handle t option properly as an arg and also properly as a return type.
So this is sort of a subtly weird thing that can trip you up if you're not careful.
Say you have a python fun like this:
Given that
to_whomtakesNonein the python, you decide to make it explicit in the OCaml binding.However, this generates code that has the wrong signature
That sig is
val say_hi : t -> to_whom:t -> greeting:string option -> unit -> string.To make that arg actually optional with
t, you would have to do this instead.Note that this problem is only there for
t optionand custom option egDoc.t option.Fixing it
It's not straightforward to fix as
t optionas an argument passed to a python function andt optionas a return type of an OCaml function need to be treated differently (and that depends on the--of-pyo-ret-typeflag).Short term fix is to document the weirdness and give an error when users try to use
t optionin this way. Currently, the bindings will be generated and you won't know something is wrong until you try to build it.Long term is to actually handle
t optionproperly as an arg and also properly as a return type.