You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _docs_src/src/recursive.md
+17-44Lines changed: 17 additions & 44 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,10 +16,17 @@ class Bar:
16
16
17
17
`Foo` has a method that returns a `Bar` object, and `Bar` has a method that returns a `Foo` object.
18
18
19
-
While this works fine in Python, we have to be more explicit in OCaml to use recursive modules. Technically, `pyml_bindgen` doesn't handle recursive modules. But it is simple enough to edit the output by hand. Let's see.
19
+
While this works fine in Python, we have to be more explicit in OCaml in these kinds of situations.
20
20
21
+
## Auto-generate bindings
21
22
22
-
## Value specs
23
+
As of version `0.4.0-SNAPSHOT`, `pyml_bindgen` ships two helper scripts for dealing with this type of thing automatically: `gen_multi` and `combine_rec_modules`. Check out the [Recursive Modules](https://github.com/mooreryan/ocaml_python_bindgen/tree/main/examples/recursive_modules) example on GitHub for how to use them.
24
+
25
+
## Semi-manually generate bindings
26
+
27
+
The `pyml_bindgen` itself doesn't handle recursive modules. But it is simple enough to edit the output by hand. Let's see how.
28
+
29
+
### Value specs
23
30
24
31
Since there are two classes to bind, we will make two val spec files.
25
32
@@ -35,7 +42,7 @@ val make_bar : unit -> Bar.t
35
42
val make_foo : unit -> Foo.t
36
43
```
37
44
38
-
## Run `pyml_bindgen`
45
+
###Run `pyml_bindgen`
39
46
40
47
Now, run `pyml_bindgen` with some extra shell commands to make the output look nicer.
41
48
@@ -49,7 +56,7 @@ pyml_bindgen bar_val_specs.txt silly Bar --caml-module Bar -r no_check \
49
56
| ocamlformat --enable --name=a.ml - >> lib.ml
50
57
```
51
58
52
-
## Fix the output
59
+
###Fix the output
53
60
54
61
If you were to try and compile that code, you'd get a lot of errors including about unknown`Bar` module.
55
62
@@ -61,61 +68,27 @@ Here is what the output should look like:
61
68
62
69
```ocaml
63
70
module rec Foo : sig
64
-
type t
65
71
66
-
val of_pyobject : Pytypes.pyobject -> t
72
+
... sig ...
67
73
68
-
val to_pyobject : t -> Pytypes.pyobject
69
-
70
-
val make_bar : unit -> Bar.t
71
74
end = struct
72
-
let filter_opt l = List.filter_map Fun.id l
73
-
74
-
let import_module () = Py.Import.import_module "silly"
75
-
76
-
type t = Pytypes.pyobject
77
75
78
-
let of_pyobject pyo = pyo
76
+
... impl ...
79
77
80
-
let to_pyobject x = x
81
-
82
-
let make_bar () =
83
-
let class_ = Py.Module.get (import_module ()) "Foo" in
84
-
let callable = Py.Object.find_attr_string class_ "make_bar" in
You may come across cyclic classes when binding Python code. If you want to bind them in OCaml as it, you will need to use recursive module. For now, `pyml_bindgen` won't generate them for you automatically, but it is not *too* bad to change them by hand :)
106
+
You may come across cyclic classes when binding Python code. If you want to bind them in OCaml as it, you will need to use recursive module. This page shows you how to do it semi-manually using `pyml_bindgen`. If you would like a more automatic way to do this, see the [Recursive Modules](https://github.com/mooreryan/ocaml_python_bindgen/tree/main/examples/recursive_modules) example on GitHub.
Copy file name to clipboardExpand all lines: examples/recursive_modules/README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,4 +40,4 @@ class Human:
40
40
41
41
You can see that the `Cat` and `Human` classes make reference to one another. This can be a problem when writing OCaml bindings.
42
42
43
-
One solution is to use [recursive modules](https://ocaml.org/manual/recursivemodules.html). Rather than run `pyml_bindgen` separately for each class we want to bind, and then manually modify the results to make the modules recursive, this directory shows you how you can use the helper scripts `gen_multi` and `combine_rec_modules` to automate this task.
43
+
One solution is to use [recursive modules](https://ocaml.org/manual/recursivemodules.html). Rather than run `pyml_bindgen` separately for each class we want to bind, and then manually [modify](https://mooreryan.github.io/ocaml_python_bindgen/recursive/) the results to make the modules recursive, this directory shows you how you can use the helper scripts `gen_multi` and `combine_rec_modules` to automate this task.
0 commit comments