diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3fff1e46..8ae8cd44 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -15,6 +15,7 @@ jobs: fail-fast: false matrix: ocaml-compiler: + - 4.10.0 - 4.11.0 - 4.12.0 - 4.13.0 diff --git a/README.md b/README.md index ff1c9466..d67ebd5c 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ opam pin add jupyter https://github.com/akabe/ocaml-jupyter.git - [Introduction](https://github.com/akabe/ocaml-jupyter/blob/master/notebooks/introduction.ipynb): a very simple example for use of OCaml Jupyter and sub-packages. - [Get a description of a word from DuckDuckGo API](https://github.com/akabe/ocaml-jupyter/blob/master/notebooks/word_description_from_DuckDuckGoAPI.ipynb): - request to DuckDuckGo API server by `cohttp.lwt`, and parse a response JSON by `yojson` and `ppx_deriving_yojson`. + request to DuckDuckGo API server by `cohttp.lwt`, and parse a response JSON by `yojson` and `ppx_yojson_conv`. In addition, many examples (e.g, image processing, voice analysis, etc.) are available at [docker-ocaml-jupyter-datascience/notebooks](https://github.com/akabe/docker-ocaml-jupyter-datascience/tree/master/notebooks). diff --git a/config/dune b/config/dune index c73c7e4c..e67d926d 100644 --- a/config/dune +++ b/config/dune @@ -14,10 +14,8 @@ (targets ocaml_flags.sexp) (deps configure.exe) (action (run %{deps} -o %{targets} - -ppx ppx_deriving_yojson - -ppx lwt_ppx -ocamlfind %{bin:ocamlfind} - -ocaml-flag "-w A-4-31-33-34-39-41-42-43-44-45-48-49-50-58" + -ocaml-flag "-w A-4-31-33-34-39-41-42-43-44-45-48-49-50-58-66" -ocaml-flag "-safe-string -strict-sequence -strict-formats" -ocaml-flag "-short-paths"))) diff --git a/jupyter-archimedes/src/dune b/jupyter-archimedes/src/dune index 84d52195..af632616 100644 --- a/jupyter-archimedes/src/dune +++ b/jupyter-archimedes/src/dune @@ -5,6 +5,5 @@ (modes byte) (modules Jupyter_archimedes) (flags ((:include %{workspace_root}/config/ocaml_flags.sexp))) - (preprocess (pps ppx_deriving_yojson)) (libraries jupyter.notebook archimedes.cairo)) diff --git a/jupyter.opam b/jupyter.opam index ba728192..03ec8a67 100644 --- a/jupyter.opam +++ b/jupyter.opam @@ -17,7 +17,7 @@ build: [ [ "dune" "build" "-p" name "-j" jobs ] ] depends: [ - "ocaml" {>= "4.04.0" & < "4.15"} + "ocaml" {>= "4.10.0" & < "4.15"} "base-threads" "base-unix" "uuidm" {>= "0.9.6"} @@ -29,11 +29,12 @@ depends: [ "zmq" {>= "5.0.0"} "zmq-lwt" {>= "5.0.0"} "yojson" {>="1.6.0"} - "ppx_deriving_yojson" {>= "3.0"} + "ppx_yojson_conv" {>= "0.14.0"} "cryptokit" {>= "1.12"} "dune" {build & >= "1.0.0"} "ounit2" {with-test & >= "2.0.0"} "ocp-indent" {with-test & >= "1.7.0"} + "ppx_deriving" {with-test} ] depopts: [ "merlin" diff --git a/jupyter/src/comm/dune b/jupyter/src/comm/dune index ccf5c36f..093e28ec 100644 --- a/jupyter/src/comm/dune +++ b/jupyter/src/comm/dune @@ -10,6 +10,6 @@ (flags (:standard -thread (:include %{workspace_root}/config/ocaml_flags.sexp))) - (preprocess (pps ppx_deriving_yojson)) + (preprocess (pps ppx_yojson_conv)) (libraries jupyter jupyter.notebook)) diff --git a/jupyter/src/completor/dune b/jupyter/src/completor/dune index 61cd9ae7..8f3c9cc9 100644 --- a/jupyter/src/completor/dune +++ b/jupyter/src/completor/dune @@ -5,10 +5,10 @@ Merlin Intf) (flags ((:include %{workspace_root}/config/ocaml_flags.sexp))) - (preprocess (pps lwt_ppx ppx_deriving_yojson)) + (preprocess (pps lwt_ppx ppx_yojson_conv)) (libraries jupyter jupyter_log lwt lwt.unix yojson - ppx_deriving_yojson.runtime)) + ppx_yojson_conv_lib)) diff --git a/jupyter/src/completor/intf.ml b/jupyter/src/completor/intf.ml index 16d6b741..8a08cab6 100644 --- a/jupyter/src/completor/intf.ml +++ b/jupyter/src/completor/intf.ml @@ -45,7 +45,7 @@ sig cmpl_type : string; cmpl_doc : string; } - [@@deriving yojson { strict = false }] + [@@deriving yojson] type reply = { @@ -53,7 +53,7 @@ sig cmpl_start : int; cmpl_end : int; } - [@@deriving yojson { strict = false }] + [@@deriving yojson] type t diff --git a/jupyter/src/completor/merlin.ml b/jupyter/src/completor/merlin.ml index 995a2420..e2bfc363 100644 --- a/jupyter/src/completor/merlin.ml +++ b/jupyter/src/completor/merlin.ml @@ -73,9 +73,9 @@ let call merlin command flags printer = type 'a merlin_reply = | RETURN of 'a [@name "return"] - | FAILURE of Yojson.Safe.t [@name "failure"] - | ERROR of Yojson.Safe.t [@name "error"] - | EXN of Yojson.Safe.t [@name "exception"] + | FAILURE of Jupyter.Json.t [@name "failure"] + | ERROR of Jupyter.Json.t [@name "error"] + | EXN of Jupyter.Json.t [@name "exception"] [@@deriving of_yojson] type 'a merlin_reply_body = @@ -84,18 +84,17 @@ type 'a merlin_reply_body = value : 'a; notifications : string list; } -[@@deriving of_yojson { strict = false }] +[@@deriving of_yojson] +[@@yojson.allow_extra_fields] let parse_merlin_reply ~of_yojson str = let error_json msg json = error (fun pp -> pp "%s: %s" msg (Yojson.Safe.pretty_to_string json)) in let reply = Yojson.Safe.from_string str - |> [%of_yojson: Yojson.Safe.t merlin_reply_body] - |> Jupyter.Json.or_die in + |> [%of_yojson: Jupyter.Json.t merlin_reply_body] in `List [`String reply.klass; reply.value] |> merlin_reply_of_yojson of_yojson - |> Jupyter.Json.or_die |> function | RETURN ret -> Some ret | FAILURE j -> error_json "Merlin failure" j ; None @@ -109,14 +108,16 @@ type ident_position = id_line : int [@key "line"]; id_col : int [@key "col"]; } -[@@deriving yojson { strict = false }] +[@@deriving yojson] +[@@yojson.allow_extra_fields] type ident_reply = { id_start : ident_position [@key "start"]; id_end : ident_position [@key "end"]; } -[@@deriving yojson { strict = false }] +[@@deriving yojson] +[@@yojson.allow_extra_fields] let occurrences ~pos merlin code = let args = ["-identifier-at"; string_of_int pos] in @@ -164,7 +165,8 @@ type candidate = cmpl_type : string [@key "desc"]; cmpl_doc : string [@key "info"]; } -[@@deriving yojson { strict = false }] +[@@deriving yojson] +[@@yojson.allow_extra_fields] type reply = { @@ -172,7 +174,8 @@ type reply = cmpl_start : int [@key "start"] [@default 0]; cmpl_end : int [@key "end"] [@default 0]; } -[@@deriving yojson { strict = false }] +[@@deriving yojson] +[@@yojson.allow_extra_fields] let empty = { cmpl_candidates = []; cmpl_start = 0; cmpl_end = 0; } diff --git a/jupyter/src/core/comm.ml b/jupyter/src/core/comm.ml index 04e30e55..4c1fdd96 100644 --- a/jupyter/src/core/comm.ml +++ b/jupyter/src/core/comm.ml @@ -25,5 +25,7 @@ type t = { comm_target : string option [@key "target_name"] [@default None]; comm_id : string [@key "comm_id"]; - comm_data : Yojson.Safe.t [@key "data"]; - } [@@deriving yojson { strict = false }] + comm_data : Json.t [@key "data"]; + } +[@@deriving yojson] +[@@yojson.allow_extra_fields] diff --git a/jupyter/src/core/dune b/jupyter/src/core/dune index 7bee10ce..7a09e44c 100644 --- a/jupyter/src/core/dune +++ b/jupyter/src/core/dune @@ -12,5 +12,5 @@ Json Version) (flags ((:include %{workspace_root}/config/ocaml_flags.sexp))) - (preprocess (pps ppx_deriving_yojson)) - (libraries unix uuidm ppx_deriving_yojson.runtime)) + (preprocess (pps ppx_yojson_conv)) + (libraries unix uuidm ppx_yojson_conv_lib)) diff --git a/jupyter/src/core/iopub.ml b/jupyter/src/core/iopub.ml index 782f0704..816a67b4 100644 --- a/jupyter/src/core/iopub.ml +++ b/jupyter/src/core/iopub.ml @@ -27,27 +27,30 @@ type stream_name = | IOPUB_STDOUT [@name "stdout"] | IOPUB_STDERR [@name "stderr"] -[@@deriving yojson { strict = false }] +[@@deriving yojson] type stream = { stream_name : stream_name Json.enum [@key "name"]; stream_text : string [@key "text"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Display data} *) type transient = { display_id : string [@key "display_id"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] type display_data = { - display_data : Yojson.Safe.t [@key "data"]; - display_metadata : Yojson.Safe.t [@key "metadata"]; + display_data : Json.t [@key "data"]; + display_metadata : Json.t [@key "metadata"]; display_transient : transient option [@key "transient"] [@default None]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Code inputs} *) @@ -55,16 +58,18 @@ type exec_input = { exin_code : string [@key "code"]; exin_count : int [@key "execution_count"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Execution results} *) type exec_result = { exres_count : int [@key "execution_count"]; - exres_data : Yojson.Safe.t [@key "data"]; - exres_metadata : Yojson.Safe.t [@key "metadata"]; - } [@@deriving yojson { strict = false }] + exres_data : Json.t [@key "data"]; + exres_metadata : Json.t [@key "metadata"]; + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Kernel status} *) @@ -77,7 +82,8 @@ type exec_status = type status = { kernel_state : exec_status Json.enum [@key "execution_state"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Execution errors} *) @@ -86,14 +92,16 @@ type error = ename : string [@key "ename"]; evalue : string [@key "evalue"]; traceback : string list [@key "traceback"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Clear output} *) type clear_output = { clear_wait : bool [@key "wait"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 IOPUB Request} *) diff --git a/jupyter/src/core/json.ml b/jupyter/src/core/json.ml index e7fa4595..026c6725 100644 --- a/jupyter/src/core/json.ml +++ b/jupyter/src/core/json.ml @@ -22,18 +22,22 @@ (** JSON utility *) -let or_none = function - | Result.Error _ -> None - | Result.Ok x -> Some x - -let or_die = function - | Result.Error msg -> Yojson.json_error msg - | Result.Ok x -> x - type 'a enum = 'a let enum_of_yojson of_yojson json = of_yojson (`List [json]) -let enum_to_yojson to_yojson x = match to_yojson x with +let yojson_of_enum yojson_of x = match yojson_of x with | `List [json] -> json - | _ -> assert false + | _ -> assert false (* TODO: replace with a suitable exception *) + +type t = Yojson.Safe.t + +let yojson_of_t x = x + +let t_of_yojson x = x + +type 'a option_try = 'a option + +let option_try_of_yojson of_yojson x = + try Some (of_yojson x) + with _ -> None diff --git a/jupyter/src/core/json.mli b/jupyter/src/core/json.mli index e286ebc3..e5d9818a 100644 --- a/jupyter/src/core/json.mli +++ b/jupyter/src/core/json.mli @@ -22,8 +22,12 @@ (** JSON utility *) -val or_none : ('a, string) Result.result -> 'a option +type 'a enum = 'a [@@deriving yojson] -val or_die : ('a, string) Result.result -> 'a +type t = Yojson.Safe.t -type 'a enum = 'a [@@deriving yojson] +val yojson_of_t : t -> Yojson.Safe.t + +val t_of_yojson : Yojson.Safe.t -> t + +type 'a option_try = 'a option [@@deriving of_yojson] diff --git a/jupyter/src/core/message.ml b/jupyter/src/core/message.ml index efd200db..832a12ea 100644 --- a/jupyter/src/core/message.ml +++ b/jupyter/src/core/message.ml @@ -33,20 +33,19 @@ type header = the message is created *) username : string; (** the current username *) version : string; (** the message protocol version *) - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] let header_of_string str = Yojson.Safe.from_string str |> [%of_yojson: header] - |> Json.or_die -let header_option_of_string s = - Yojson.Safe.from_string s - |> [%of_yojson: header] - |> Json.or_none +let header_option_of_string str = + Yojson.Safe.from_string str + |> [%of_yojson: header Json.option_try] let string_of_header hdr = - [%to_yojson: header] hdr + [%yojson_of: header] hdr |> Yojson.Safe.to_string let string_of_header_option = function @@ -81,7 +80,8 @@ type 'content t = buffers : string list; (** optional: buffers is a list of binary data buffers for implementations that support binary extensions to the protocol. *) - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] let epoch_to_iso8601_string epoch = let open Unix in @@ -108,13 +108,13 @@ let create_next ?(time = Unix.gettimeofday ()) ~content_to_yojson parent content } let create_next_shell ?time parent content = - create_next ?time ~content_to_yojson:[%to_yojson: Shell.reply] parent content + create_next ?time ~content_to_yojson:[%yojson_of: Shell.reply] parent content let create_next_iopub ?time parent content = - create_next ?time ~content_to_yojson:[%to_yojson: Iopub.reply] parent content + create_next ?time ~content_to_yojson:[%yojson_of: Iopub.reply] parent content let create_next_stdin ?time parent content = - create_next ?time ~content_to_yojson:[%to_yojson: Stdin.reply] parent content + create_next ?time ~content_to_yojson:[%yojson_of: Stdin.reply] parent content (** {2 Messages} *) diff --git a/jupyter/src/core/shell.ml b/jupyter/src/core/shell.ml index 0c2e143e..4ecc54c9 100644 --- a/jupyter/src/core/shell.ml +++ b/jupyter/src/core/shell.ml @@ -35,16 +35,18 @@ type exec_request = exec_code : string [@key "code"]; exec_silent : bool [@key "silent"]; exec_store_history : bool [@key "store_history"]; - exec_user_expr : Yojson.Safe.t [@key "user_expressions"]; + exec_user_expr : Json.t [@key "user_expressions"]; exec_allow_stdin : bool [@key "allow_stdin"] [@default true]; exec_stop_on_error : bool [@key "stop_on_error"] [@default false]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] type exec_reply = { exec_count : int [@key "execution_count"]; exec_status : status Json.enum [@key "status"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Instrospection} *) @@ -53,15 +55,17 @@ type inspect_request = insp_code : string [@key "code"]; insp_pos : int [@key "cursor_pos"]; insp_detail : int [@key "detail_level"] [@default 0]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] type inspect_reply = { insp_status : status Json.enum [@key "status"]; insp_found : bool [@key "found"]; - insp_data : Yojson.Safe.t [@key "data"] [@default `Null]; - insp_metadata : Yojson.Safe.t [@key "metadata"] [@default `Null]; - } [@@deriving yojson { strict = false }] + insp_data : Json.t [@key "data"] [@default `Null]; + insp_metadata : Json.t [@key "metadata"] [@default `Null]; + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Completion} *) @@ -69,16 +73,18 @@ type complete_request = { cmpl_code : string [@key "code"]; cmpl_pos : int [@key "cursor_pos"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] type complete_reply = { cmpl_matches : string list [@key "matches"]; cmpl_start : int [@key "cursor_start"]; cmpl_end : int [@key "cursor_end"]; - cmpl_metadata : Yojson.Safe.t [@key "metadata"]; + cmpl_metadata : Json.t [@key "metadata"]; cmpl_status : status Json.enum [@key "status"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 History} *) @@ -93,25 +99,29 @@ type history_request = hist_n : int [@key "n"]; hist_pattern : string option [@key "pattern"] [@default None]; hist_unique : bool [@key "unique"] [@default false]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] type history_reply = { history : (int option * int * string) list; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Code completeness} *) type is_complete_request = { is_cmpl_code : string [@key "code"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] type is_complete_reply = { is_cmpl_status : string [@key "status"]; is_cmpl_indent : string option [@key "indent"] [@default None]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Connect} *) @@ -122,19 +132,22 @@ type connect_reply = conn_stdin_port : int [@key "stdin_port"]; conn_hb_port : int [@key "hb_port"]; conn_ctrl_port : int [@key "control_port"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Comm info} *) type comm_info_request = { ci_target : string option [@key "target_name"] [@default None]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] type comm_info_reply = { - ci_comms : Yojson.Safe.t [@key "comms"]; - } [@@deriving yojson { strict = false }] + ci_comms : Json.t [@key "comms"]; + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Kernel information} *) @@ -145,9 +158,10 @@ type language_info = lang_mimetype : string [@key "mimetype"]; (** mimetype *) lang_file_ext : string [@key "file_extension"]; (** file extension *) lang_lexer : string option [@key "pygments_lexer"]; (** pygments lexer *) - lang_mode : Yojson.Safe.t [@key "codemirror_mode"]; (** codemirror mode *) + lang_mode : Json.t [@key "codemirror_mode"]; (** codemirror mode *) lang_exporter : string option [@key "nbconverter_exporter"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] let language_info = { @@ -164,7 +178,8 @@ type help_link = { help_text : string [@key "text"]; help_url : string [@key "url"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] let help_links = [ @@ -183,7 +198,8 @@ type kernel_info_reply = kernel_help_links : help_link list [@key "help_links"]; kernel_lang_info : language_info [@key "language_info"]; kernel_lang : string [@key "language"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] let kernel_info_reply = let banner = @@ -207,7 +223,8 @@ let kernel_info_reply = type shutdown = { shutdown_restart : bool [@key "restart"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Request} *) @@ -224,7 +241,7 @@ type request = | SHELL_COMM_OPEN of Comm.t [@name "comm_open"] | SHELL_COMM_MSG of Comm.t [@name "comm_msg"] | SHELL_COMM_CLOSE of Comm.t [@name "comm_close"] -[@@deriving yojson { strict = false }] +[@@deriving yojson] (** {2 Reply} *) @@ -238,7 +255,7 @@ type reply = | SHELL_CONNECT_REP of connect_reply [@name "connect_reply"] | SHELL_COMM_INFO_REP of comm_info_reply [@name "comm_info_reply"] | SHELL_SHUTDOWN_REP of shutdown [@name "shutdown_reply"] -[@@deriving yojson { strict = false }] +[@@deriving yojson] let execute_reply ~count status = SHELL_EXEC_REP { exec_count = count; exec_status = status; } diff --git a/jupyter/src/core/stdin.ml b/jupyter/src/core/stdin.ml index 66b49cf1..dcf4c786 100644 --- a/jupyter/src/core/stdin.ml +++ b/jupyter/src/core/stdin.ml @@ -28,12 +28,14 @@ type input_request = { stdin_prompt : string [@key "prompt"]; stdin_password : bool [@key "password"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] type input_reply = { stdin_value : string [@key "value"]; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] (** {2 Request} *) diff --git a/jupyter/src/kernel/connection_info.ml b/jupyter/src/kernel/connection_info.ml index 557f41f7..d47fff97 100644 --- a/jupyter/src/kernel/connection_info.ml +++ b/jupyter/src/kernel/connection_info.ml @@ -38,7 +38,8 @@ type t = key : string option [@default None]; signature_scheme : string; transport : string; - } [@@deriving yojson { strict = false }] + } [@@deriving yojson] +[@@yojson.allow_extra_fields] let from_file fname = if not (Sys.file_exists fname) @@ -46,9 +47,8 @@ let from_file fname = let json = Yojson.Safe.from_file ~fname fname in info (fun pp -> pp "Load connection info: %s" (Yojson.Safe.to_string json)) ; match [%of_yojson: t] json with - | Result.Error msg -> Yojson.json_error msg - | Result.Ok info when info.key = Some "" -> { info with key = None } - | Result.Ok info -> info + | info when info.key = Some "" -> { info with key = None } + | info -> info (** [make_address info port] returns an address for ZeroMQ communication. *) let make_address info port = diff --git a/jupyter/src/kernel/dune b/jupyter/src/kernel/dune index 2a0e04f8..db6e7181 100644 --- a/jupyter/src/kernel/dune +++ b/jupyter/src/kernel/dune @@ -10,7 +10,7 @@ Connection_info Hmac) (flags ((:include %{workspace_root}/config/ocaml_flags.sexp))) - (preprocess (pps lwt_ppx ppx_deriving_yojson)) + (preprocess (pps lwt_ppx ppx_yojson_conv)) (libraries jupyter jupyter_repl jupyter_completor @@ -21,4 +21,4 @@ yojson zmq-lwt cryptokit - ppx_deriving_yojson.runtime)) + ppx_yojson_conv_lib)) diff --git a/jupyter/src/kernel/message_channel.ml b/jupyter/src/kernel/message_channel.ml index 55144e78..595cc8a5 100644 --- a/jupyter/src/kernel/message_channel.ml +++ b/jupyter/src/kernel/message_channel.ml @@ -76,8 +76,7 @@ struct let header = header_of_string header in let content = Yojson.Safe.from_string content |> compose_content ~msg_type:header.msg_type - |> [%of_yojson: Content.request] - |> Jupyter.Json.or_die in + |> [%of_yojson: Content.request] in { zmq_ids = ids; header; @@ -99,7 +98,7 @@ struct let header = string_of_header resp.header in let parent_header = string_of_header_option resp.parent_header in let content = - match [%to_yojson: Content.reply] resp.content with + match [%yojson_of: Content.reply] resp.content with | `List (_ :: content :: _) -> Yojson.Safe.to_string content | _ -> "{}" in let hmac = @@ -128,7 +127,7 @@ struct let reply ?time ~parent ch content = Jupyter.Message.create_next - ~content_to_yojson:[%to_yojson: Content.reply] + ~content_to_yojson:[%yojson_of: Content.reply] ?time parent content |> send ch diff --git a/jupyter/bin/dune b/jupyter/src/main/dune similarity index 72% rename from jupyter/bin/dune rename to jupyter/src/main/dune index 056d28dc..36191f69 100644 --- a/jupyter/bin/dune +++ b/jupyter/src/main/dune @@ -3,11 +3,10 @@ (modes byte) (package jupyter) (public_name ocaml-jupyter-kernel) - (preprocess (pps lwt_ppx ppx_deriving_yojson)) + (preprocess (pps lwt_ppx ppx_yojson_conv)) (libraries jupyter jupyter_log jupyter_repl jupyter_completor - jupyter_kernel - ppx_deriving.runtime) + jupyter_kernel) (flags ((:include %{workspace_root}/config/ocaml_flags.sexp)))) diff --git a/jupyter/bin/jupyter_args.ml b/jupyter/src/main/jupyter_args.ml similarity index 100% rename from jupyter/bin/jupyter_args.ml rename to jupyter/src/main/jupyter_args.ml diff --git a/jupyter/bin/jupyter_args.mli b/jupyter/src/main/jupyter_args.mli similarity index 100% rename from jupyter/bin/jupyter_args.mli rename to jupyter/src/main/jupyter_args.mli diff --git a/jupyter/bin/jupyter_main.ml b/jupyter/src/main/jupyter_main.ml similarity index 100% rename from jupyter/bin/jupyter_main.ml rename to jupyter/src/main/jupyter_main.ml diff --git a/jupyter/src/notebook/dune b/jupyter/src/notebook/dune index 3468e255..afd2c1a9 100644 --- a/jupyter/src/notebook/dune +++ b/jupyter/src/notebook/dune @@ -6,7 +6,7 @@ (modules Jupyter_notebook Unsafe) (flags ((:include %{workspace_root}/config/ocaml_flags.sexp))) - (preprocess (pps ppx_deriving_yojson)) + (preprocess (pps ppx_yojson_conv)) (libraries jupyter uuidm base64 diff --git a/jupyter/src/notebook/unsafe.ml b/jupyter/src/notebook/unsafe.ml index ebb73823..a967a7f4 100644 --- a/jupyter/src/notebook/unsafe.ml +++ b/jupyter/src/notebook/unsafe.ml @@ -52,5 +52,5 @@ let send_iopub ?ctx content = in let message = Jupyter.Message.create_next parent content - ~content_to_yojson:[%to_yojson: Jupyter.Iopub.reply] in + ~content_to_yojson:[%yojson_of: Jupyter.Iopub.reply] in send (Jupyter.Message.IOPUB_REP message) diff --git a/jupyter/src/repl/lwt_async_rewrite.cppo.ml b/jupyter/src/repl/lwt_async_rewrite.cppo.ml index a88fe8e2..21368ea5 100644 --- a/jupyter/src/repl/lwt_async_rewrite.cppo.ml +++ b/jupyter/src/repl/lwt_async_rewrite.cppo.ml @@ -21,16 +21,20 @@ type rewrite_rule = { (* Whether the rule is enabled or not. *) } +let longident l = match Longident.unflatten l with + | Some li -> li + | None -> failwith "Failed to parse longident" + let longident_lwt_main_run = Longident.Ldot (Longident.Lident "Lwt_main", "run") let longident_async_thread_safe_block_on_async_exn = - Longident.parse "Async.Thread_safe.block_on_async_exn" + longident ["Async"; "Thread_safe"; "block_on_async_exn"] let nolabel = Asttypes.Nolabel let rewrite_rules = [ (* Rewrite Lwt.t expressions to Lwt_main.run *) { - type_to_rewrite = Longident.parse "Lwt.t"; + type_to_rewrite = longident ["Lwt"; "t"]; path_to_rewrite = None; required_values = [longident_lwt_main_run]; rewrite = (fun loc e -> @@ -45,7 +49,7 @@ let rewrite_rules = [ (* Rewrite Async.Defered.t expressions to Async.Thread_safe.block_on_async_exn (fun () -> ). *) { - type_to_rewrite = Longident.parse "Async.Deferred.t"; + type_to_rewrite = longident ["Async"; "Deferred"; "t"]; path_to_rewrite = None; required_values = [longident_async_thread_safe_block_on_async_exn]; rewrite = (fun loc e -> diff --git a/notebooks/word_description_from_DuckDuckGoAPI.ipynb b/notebooks/word_description_from_DuckDuckGoAPI.ipynb index ca7ff322..fcc2d0ab 100644 --- a/notebooks/word_description_from_DuckDuckGoAPI.ipynb +++ b/notebooks/word_description_from_DuckDuckGoAPI.ipynb @@ -13,20 +13,24 @@ "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": true, "scrolled": true }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + ] + } + ], "source": [ - "#require \"cohttp,cohttp-lwt-unix,ppx_deriving_yojson\" ;;" + "#require \"cohttp,cohttp-lwt-unix,ppx_yojson_conv\" ;;" ] }, { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "open Lwt.Infix ;;" @@ -41,9 +45,8 @@ "data": { "text/plain": [ "type t = { definition : string; abstract : string; }\n", - "val to_yojson : t -> Yojson.Safe.json = \n", - "val of_yojson : Yojson.Safe.json -> t Ppx_deriving_yojson_runtime.error_or =\n", - " \n" + "val t_of_yojson : Ppx_yojson_conv_lib.Yojson.Safe.t -> t = \n", + "val yojson_of_t : t -> Ppx_yojson_conv_lib.Yojson.Safe.t = \n" ] }, "execution_count": 3, @@ -55,7 +58,7 @@ "type t = {\n", " definition : string [@key \"Definition\"];\n", " abstract : string [@key \"Abstract\"];\n", - " } [@@deriving yojson { strict = false }]" + " } [@@deriving yojson] [@@yojson.allow_extra_fields]" ] }, { @@ -80,7 +83,7 @@ "text/plain": [ "val body : string option =\n", " Some\n", - " \"OCaml, originally named Objective Caml, is the main implementation of the programming language Caml, created by Xavier Leroy, J\\195\\169r\\195\\180me Vouillon, Damien Doligez, Didier R\\195\\169my, Asc\\195\\161nder Su\\195\\161rez and others in 1996. A member of the ML language family, OCaml extends the core Caml language with object-oriented programming constructs.\"\n" + " \"OCaml is a general-purpose, multi-paradigm programming language which extends the Caml dialect of ML with object-oriented features. OCaml was created in 1996 by Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy, Ascánder Suárez, and others. The OCaml toolchain includes an interactive\"... (* string length 994; truncated *)\n" ] }, "execution_count": 4, @@ -96,14 +99,13 @@ " let uri = Uri.add_query_param base_uri (\"q\", [query]) in\n", " Cohttp_lwt_unix.Client.get uri >>= fun (resp, body) -> (* GET contents from a given uri *)\n", " assert (Cohttp.Response.status resp = `OK) ; (* Check HTTP response code *)\n", - " Cohttp_lwt_body.to_string body >|= fun body -> (* Receive contents *)\n", + " Cohttp_lwt.Body.to_string body >|= fun body -> (* Receive contents *)\n", " Yojson.Safe.from_string body\n", " |> [%of_yojson: t]\n", " |> function\n", - " | Result.Ok { definition = \"\"; abstract = \"\"; } -> None\n", - " | Result.Ok { definition = \"\"; abstract; } -> Some abstract\n", - " | Result.Ok { definition; abstract = \"\"; } -> Some definition\n", - " | _ -> failwith \"Oops!\"\n", + " | { definition = \"\"; abstract = \"\"; } -> None\n", + " | { definition = \"\"; abstract; } -> Some abstract\n", + " | { definition; _ } -> Some definition\n", " end" ] }, @@ -119,7 +121,7 @@ ], "metadata": { "kernelspec": { - "display_name": "OCaml 4.04.2", + "display_name": "OCaml 4.12.0", "language": "OCaml", "name": "ocaml-jupyter" }, @@ -130,7 +132,7 @@ "name": "OCaml", "nbconverter_exporter": null, "pygments_lexer": "OCaml", - "version": "4.04.2" + "version": "4.12.0" } }, "nbformat": 4, diff --git a/test/completor/dune b/test/completor/dune index 1c484acb..6f124a86 100644 --- a/test/completor/dune +++ b/test/completor/dune @@ -1,10 +1,9 @@ (executables (names test_completor) - (preprocess (pps lwt_ppx ppx_deriving.show ppx_deriving_yojson)) + (preprocess (pps lwt_ppx ppx_deriving.show ppx_yojson_conv)) (libraries jupyter jupyter_completor - ounit2 - ppx_deriving.runtime) + ounit2) (flags ((:include %{workspace_root}/config/ocaml_flags.sexp) (:include %{workspace_root}/config/ocaml_test_flags.sexp)))) diff --git a/test/completor/test_merlin.ml b/test/completor/test_merlin.ml index 7cf06dfa..85eb379b 100644 --- a/test/completor/test_merlin.ml +++ b/test/completor/test_merlin.ml @@ -28,7 +28,7 @@ open Jupyter_completor (** {2 Merlin.occurrences} *) let pp_ident_reply ppf reply = - [%to_yojson: Merlin.ident_reply] reply + [%yojson_of: Merlin.ident_reply] reply |> Yojson.Safe.to_string |> pp_print_string ppf @@ -81,7 +81,7 @@ let test_abs_position ctxt = (** {2 Merlin.complete} *) let pp_reply ppf reply = - [%to_yojson: Merlin.reply] reply + [%yojson_of: Merlin.reply] reply |> Yojson.Safe.to_string |> fprintf ppf "%s" diff --git a/test/integration/dune b/test/integration/dune index 5b4aca42..cfe9b34b 100644 --- a/test/integration/dune +++ b/test/integration/dune @@ -3,9 +3,11 @@ (executables (names runtest) - (preprocess (pps ppx_deriving_yojson)) + (preprocess (pps ppx_yojson_conv ppx_yojson_conv)) + (flags (:standard + -w A-4-31-33-34-39-41-42-43-44-45-48-49-50-58 + -safe-string -strict-sequence -strict-formats + -short-paths)) (libraries jupyter unix - ppx_deriving.runtime) - (flags ((:include %{workspace_root}/config/ocaml_flags.sexp) - (:include %{workspace_root}/config/ocaml_test_flags.sexp)))) + ppx_yojson_conv_lib)) diff --git a/test/integration/runtest.ml b/test/integration/runtest.ml index e018fe03..359b7946 100644 --- a/test/integration/runtest.ml +++ b/test/integration/runtest.ml @@ -29,7 +29,7 @@ type cell = execution_count : int; source : string list; outputs : string list; - metadata : Yojson.Safe.t; + metadata : Json.t; } [@@deriving yojson] @@ -90,7 +90,7 @@ let runtest ml_fname = let ipynb_fname = ml_fname ^ ".ipynb" in read_lines ml_fname |> ipynb_of_code - |> [%to_yojson: ipynb] + |> [%yojson_of: ipynb] |> Yojson.Safe.to_file ipynb_fname ; let cmd = sprintf "jupyter nbconvert --to notebook --execute %S" ipynb_fname in printf "%s>> %s%s@." AnsiCode.FG.cyan cmd AnsiCode.reset ; diff --git a/test/integration/suite/ppx.ml b/test/integration/suite/ppx.ml index 9513f9d9..b64ff809 100644 --- a/test/integration/suite/ppx.ml +++ b/test/integration/suite/ppx.ml @@ -1,4 +1,4 @@ -#require "ppx_deriving_yojson" ;; +#require "ppx_yojson_conv" ;; type t = { foo : int; baz : string; } [@@deriving yojson] @@ -6,7 +6,7 @@ let expected = "{\"foo\":42,\"baz\":\"hello\"}" let actual = { foo = 42; baz = "hello"; } - |> [%to_yojson: t] + |> [%yojson_of: t] |> Yojson.Safe.to_string let () = assert (expected = actual) diff --git a/test/kernel/dune b/test/kernel/dune index 3524db12..719b6fa6 100644 --- a/test/kernel/dune +++ b/test/kernel/dune @@ -1,11 +1,10 @@ (executables (names test_kernel) (modes byte) - (preprocess (pps lwt_ppx ppx_deriving.show ppx_deriving_yojson)) + (preprocess (pps lwt_ppx ppx_deriving.show ppx_yojson_conv)) (libraries jupyter jupyter_kernel - ounit2 - ppx_deriving.runtime) + ounit2) (flags ((:include %{workspace_root}/config/ocaml_flags.sexp) (:include %{workspace_root}/config/ocaml_test_flags.sexp)))) diff --git a/test/kernel/test_message_channel.ml b/test/kernel/test_message_channel.ml index da31849b..55d56949 100644 --- a/test/kernel/test_message_channel.ml +++ b/test/kernel/test_message_channel.ml @@ -53,7 +53,7 @@ let test_recv ctxt = let channel = Channel.create ~key ~ctx ~kind:Zmq.Socket.rep "" in let actual = Lwt_main.run @@ Channel.recv channel in assert_equal ~ctxt ~printer:(fun msg -> - [%to_yojson: Jupyter.Shell.request Jupyter.Message.t] msg + [%yojson_of: Jupyter.Shell.request Jupyter.Message.t] msg |> Yojson.Safe.to_string) message actual diff --git a/test/repl/dune b/test/repl/dune index 0f529fde..ec4d809d 100644 --- a/test/repl/dune +++ b/test/repl/dune @@ -2,11 +2,10 @@ (names test_evaluation test_process) (modes byte) - (preprocess (pps lwt_ppx ppx_deriving.show ppx_deriving_yojson)) + (preprocess (pps lwt_ppx ppx_deriving.show ppx_yojson_conv)) (libraries jupyter jupyter_repl - ounit2 - ppx_deriving.runtime) + ounit2) (flags ((:include %{workspace_root}/config/ocaml_flags.sexp) (:include %{workspace_root}/config/ocaml_test_flags.sexp)))) diff --git a/test/repl/test_evaluation.ml b/test/repl/test_evaluation.ml index 6a7dc1c0..6b466dab 100644 --- a/test/repl/test_evaluation.ml +++ b/test/repl/test_evaluation.ml @@ -27,12 +27,12 @@ open Jupyter.Shell open Jupyter_repl.Evaluation let pp_status ppf status = - [%to_yojson: Jupyter.Shell.status] status + [%yojson_of: Jupyter.Shell.status] status |> Yojson.Safe.to_string |> pp_print_string ppf let pp_reply ppf reply = - [%to_yojson: Jupyter.Iopub.reply] reply + [%yojson_of: Jupyter.Iopub.reply] reply |> Yojson.Safe.to_string |> pp_print_string ppf diff --git a/test/repl/test_process.ml b/test/repl/test_process.ml index b319d2ef..319135cd 100644 --- a/test/repl/test_process.ml +++ b/test/repl/test_process.ml @@ -36,9 +36,9 @@ type reply = let pp_reply ppf reply = begin match reply with - | Shell shell -> [%to_yojson: Jupyter.Shell.reply] shell - | Iopub iopub -> [%to_yojson: Jupyter.Iopub.reply] iopub - | Stdin stdin -> [%to_yojson: Jupyter.Stdin.reply] stdin + | Shell shell -> [%yojson_of: Jupyter.Shell.reply] shell + | Iopub iopub -> [%yojson_of: Jupyter.Iopub.reply] iopub + | Stdin stdin -> [%yojson_of: Jupyter.Stdin.reply] stdin end |> Yojson.Safe.to_string |> pp_print_string ppf