camlspotter avatar camlspotter committed b0ac4b5 Merge

merge

Comments (0)

Files changed (14)

 test_bug1$
 tests/from_string_iteration$
 tests/set_closure_string$
-
+api\.auto\.mli$
+OOApiauto\.ml$
 name = "OPyCaml"
-version = "1.0.0"
+version = "1.1.0"
 description = "( ゚∀゚)o彡°O'PyCaml"
 
 requires = ""
 autoapi.ml : auto.ml module.pl $(addsuffix .idl.in, $(IDLS))
     ./module.pl *.idl.in > $@
 
+api.cmo api.cmi api.cmx: autoapi.cmi
+
 api.auto.mli: api.cmi api.ml
 
 OOApiauto.ml: api.auto.mli oowrap/oowrap.cmo
-module OPy = struct
-  include OOApiauto
-end
+module OPy = OOApiauto
+include OOApiauto.M
 
 open OPy
 module Slice = Slice
 
       PyTuple_GET_ITEM => Tuple._GET_ITEM
 
- 
+OO Interface
+
+    OO style interface, OOApi.ml is now also provided. This module is automatically generated from api.ml.
+    See examples/testoo.ml for how to use.
+
+    - open Opycaml.OOApi at the beginning of your module
+
+    - The Api function calls like [Api.M.func m args] are in OO style in OOApi, [m#func args], if [m]'s an object of [M].
+
+    - If an Api function call [Api.M.func m args] has no trivial OO style translation, i.e. if [m] is not an object of [M], [OOApi.M.func] is available.
+    
+    - For example,
+
+        open Opycaml.Api
+
+        let _ = Base.initialize ()
+        ... Dict.getItemString dict "foobar" ...
+
+      becomes as follows in OO style:
+
+        open Opycaml.OOApi
+
+        let _ = Base.initialize ()           (* It has no trivial OO translation. *)
+        ... dict#getItemString "foobar" ...  
+
+Js_of_ocaml Interface
+
+    If you have js_of_ocaml installed, there is a small tool to use the syntax sugar of js_of_ocaml for Python dictionary access in OPyCaml. See js_of_ocaml directory.
+
+
+
   module Number = Number
   module Type = Type
   module Mapping = Mapping
-  module Dict = Dict
   module DictProxy = DictProxy
+  module Dict = struct
+    include Dict
+    let new_proxy = DictProxy.new_
+  end
 
   module Index = Index
   module Import = Import
   module Iter = Iter
-  module Callable = Callable
+
   module Sequence = Sequence
   module Eval = Eval
   module Run = Run
     include Module
       
     module X : sig
-      val setToSys : string -> [>_Module] t -> unit
+      val setToSys : [>_Module] t -> string -> unit
 	(** [setToSys name m] registers a module [m] as [name] into
-	    the Python system modules dictionary. *)
+	    the Python system modules dictionary. 
+
+            Note: the argument order is fliped for OO interface
+        *)
 
       val setItemString : [>_Module] t -> string -> [>_Object] t -> unit
 	(** [setItemString m name t] adds object [t] to the module [m]'s
 	(** [setItemString m name t] adds object [t] to the module [m]'s
 	    dictionary as [name]. *)
     end = struct
-      let setToSys name m =
+      let setToSys m name =
 	let sys = Import.importModule "sys" in
 	let sysdict = Module.getDict sys in
 	let modules = Dict.coerce (Dict.getItemString sysdict "modules") in
     end
 
     include X
+
+    (* copied from Base *)       
+    let debug o s = Base.debug s o
+    let address = Base.address
+    let decref = Base.decref
+    let incref = Base.incref
+    let refcnt = Base.refcnt
+    let phys_eq = Base.phys_eq
+
+    (* copied from ByteArray *)
+    let toByteArray = ByteArray.fromObject
+
+    (* from Err *) (* CR jfuruse: not sure they are ok or not *)
+    let errWriteUnraisable = Err.writeUnraisable
+    let errNewException str o1 o2 = Err.newException o1 str o2
+    let errSetNone = Err.setNone
+    let errSetObject = Err.setObject
+    let errSetString = Err.setString
+    let errGivenExceptionMatches = Err.givenExceptionMatches
+    let errExceptionMatches = Err.exceptionMatches
+  
   end
   
+  module Callable = struct
+    include Callable
+
+    let _internal_call = Object._internal_call
+    let _internal_callObject = Object._internal_callObject
+    let call = Object.call
+    let callObject = Object.callObject
+  end
+
   module Err = struct
     include Err
 
     include X
   end
 
+  module Class = struct
+    let isSubclass = Object.isSubclass
+  end
+  
 end
-  
+
 (* Name space hack: Modules whose names do not collide with the OCaml
    standard library are exported here too. *)
 open Py
 module Object = Object
 module Err = Err
 module Int = Int
+module Class = Class
 
 let _ = Base.initialize ()

examples/testoo.ml

 
   let res = Object.callObject (Callable.coerce capitalize) [lowercase] in
 
-  (* String class is not accessible by String but OPy.String, in order
-     to avoid the name space collision with String in OCaml standard
-     library. *)
   prerr_endline (OPy.String.coerce res)#asString;
 
   Base.finalize ()

js_of_ocaml/opy_of_ocaml.ml

 open Opycaml.OOApi
-
-module OT = Opycaml.Type
+open OPy
 
 module Js : sig
   type 'a t
   type 'a gen_prop
   type 'a readonly_prop = < get : 'a> gen_prop
   type 'a meth
-  val dict : #OPy.o_Dict -> 'a t
+  val dict : #o_Dict -> 'a t
   module Unsafe : sig
     val get : 'a t -> string -> 'b
-    val meth_call : 'a t -> string -> #OPy.o_Object array -> 'b
-    val inject : #OPy.o_Object -> OPy.o_Object
+    val meth_call : 'a t -> string -> #o_Object array -> 'b
+    val inject : #o_Object -> o_Object
   end
 end = struct
-  type 'a t = OPy.o_Dict
+  type 'a t = o_Dict
   type 'a gen_prop
   let dict = Obj.magic
   module Unsafe = struct
     let get (o : 'a t) name = Obj.magic (o#getItemString name)
-    let meth_call (o : OPy.o_Dict) name args = 
+    let meth_call (o : o_Dict) name args = 
       Obj.magic (Object.callObject (Callable.coerce (o#getItemString name)) (Array.to_list args ))
     let inject = Obj.magic
   end

js_of_ocaml/testoo.ml

 open Opy_of_ocaml
 
 class type module_string = object
-  method lowercase  : OPy.o_String Js.readonly_prop
-  method capitalize : #OPy.o_String -> OPy.o_String Js.meth
+  method lowercase  : o_String Js.readonly_prop
+  method capitalize : #o_String -> o_String Js.meth
 end
 
 let import_module_dict name = Js.dict (Import.importModule name)#getDict
   let lowercase = module_string##lowercase in
   let res = module_string##capitalize( lowercase ) in
 
-  (* String class is not accessible by String but OPy.String, in order
-     to avoid the name space collision with String in OCaml standard
-     library. *)
   prerr_endline res#asString;
 
   Base.finalize ()

test.ml

-open Opycaml.Api (* Use the API *)
-
-let _ = 
-  prerr_endline "start";
-  Base.initialize () (* CR jfuruse: Actually, no effect, since this is called inside api.ml *)
-;;
-
-let _ =
-  prerr_endline "*** import non-existing module";
-  try
-    ignore (Import.importModule "hogehoge")
-  with
-  | Error (e, detail) ->
-      Printf.eprintf "Error: %s %s\n%!" (Py.String.asString (Object.repr e)) (Py.String.asString (Object.repr detail))
-	(* Opycaml.Api.Py.String is not available as
-	   Opycaml.Api.String, to avoid the name collision with the original OCaml String module under ``open Opycaml.Api''.
-	*)
-;;
-
-let _ =
-  prerr_endline "*** create string";
-  let o = Py.String.fromString "hello world" in
-  Base.debug "o" o;
-
-  prerr_endline "*** phys_equality";
-  assert (Base.phys_eq o o);
-
-  prerr_endline "*** repr";
-  let repr = Object.repr o in
-  Base.debug "repr" repr;
-
-  prerr_endline "*** hash";
-  let hash = Object.hash o in
-  Printf.eprintf "hash=%nd\n%!" hash;
-
-  try
-    prerr_endline "*** importing string module";
-    let stringModule = Import.importModule "string" in (* from string import * *)
-    Base.debug "stringModule" stringModule;
-
-    prerr_endline "*** dict of string";
-    let dict = Module.getDict stringModule in
-    (* Base.debug "dict" dict; *)
-
-    prerr_endline "*** get lowercase";
-    let lowercase = Dict.getItemString dict "lowercase" in
-    Base.debug "lowercase" lowercase;
-
-    prerr_endline "*** get capitalize";
-    let capitalize = Dict.getItemString dict "capitalize" in
-    Base.debug "capitalize" capitalize;
-
-    prerr_endline "*** check callable of capitalize";
-    if not (Callable.check capitalize) then begin
-      prerr_endline "capitalize is not a function!";
-      failwith "capitalize is not a function!";
-    end;
-
-    prerr_endline "*** tuple creation";
-    let tpl = Tuple.new_ 1 in
-    Base.debug "tpl" tpl;
-
-    prerr_endline "*** tuple setting";
-    prerr_endline "* ref count before:";
-    Base.debug "o" o;
-    Tuple.setItem tpl 0 o;
-    prerr_endline "* tuple set";
-    prerr_endline "* ref count after:";
-    Base.debug "tuple" tpl;
-    Base.debug "o" o; (* ref by tuple and o *)
-
-    prerr_endline "*** getItem";
-    let x = Tuple.getItem tpl 0 in
-    Base.debug "x" x; (* ref by tuple, o and x *) 
-    Base.debug "o" o; (* ref by tuple, o and x *) 
-
-    prerr_endline "*** GET_ITEM";
-    let xx = Tuple._GET_ITEM tpl 0 in
-    Base.debug "xx" xx; (* ref by tuple, o, x and xx *)
-    Base.debug "o" o;
-
-    prerr_endline "*** calling function";
-    let res = Object.callObject (Callable.coerce capitalize) [o] in
-    Printf.eprintf "res : refcnt = %d\n%!" (Base.refcnt res);
-    prerr_endline "* function called!";
-    prerr_endline (Py.String.asString (Py.String.coerce res));
-    prerr_endline (Py.String.asString o);
-
-    prerr_endline "*** fromLong (-1)";
-    let minus_1 = Int.fromLong (-1) in
-    assert (Int.asLong minus_1 = -1); 
-
-    prerr_endline "*** Run.simpleString";
-    Run.simpleString "print 'Run.simpleString'";
-    (* Run.simpleString "print(string.lowercase)"; *) (* does not work *)
-    (* Run.simpleString "print(lowercase)"; *) (* does not work *)
-
-    prerr_endline "*** registering opycaml command";
-    (* Register test command in python *)
-    Hashtbl.add Py.Callback.functions "test" 
-      (fun (self_opt : _Object t option) (args : _Object t list) ->
-	Format.eprintf "With self: %b@." (self_opt <> None);
-	Format.eprintf "#Args %d@." (List.length args);
-	Object.obj (Base.none ()));
-      (* Opycaml.Api.Py.Callback is not available as
-	 Opycaml.Api.Callback, to avoid the name collision with the original OCaml Callback module under ``open Opycaml.Api''.
-      *)
-    prerr_endline "* Now you can use opycaml.ocaml(\"test\", 1, 2, 3) to call the test OCaml function from Python";
-
-    prerr_endline "*** module insertion";
-    let m = Import.importModule "opycaml" in
-    Module.setItemString m "bar" xx;
-    prerr_endline "* check / import opycaml / opycaml.__dict__ / opycaml.bar";
-
-    prerr_endline "*** new module creation";
-    let m = Module.new_ "foo" in
-    Module.setItemString m "bar" xx;
-    Module.setToSys "foo" m;
-    prerr_endline "* check / import foo / foo.__dict__ / foo.bar";
-
-    prerr_endline "*** OCaml value embedding";
-    (* OCaml value => _Object t *)
-    let py_ocaml_1 = Base.unsafe_embed 1 in
-    Base.debug "py_ocaml_1" py_ocaml_1;
-
-    prerr_endline "*** inserting a closure into module opycaml";
-    let f (args : _Tuple t) : _Object t =
-      let i = ref 0 in
-      List.iter (fun t -> 
-	Format.eprintf "Arg %d : %s@." !i (Object.repr_string t);
-	incr i;
-      ) (Tuple.to_list args);
-      Object.obj (Base.none ())
-    in
-    
-    let m = Import.importModule "opycaml" in
-    Module.setClosureString m "f" f;
-    prerr_endline "* check / import opycaml / opycaml.__dict__ / opycaml.f(1)";
-
-    prerr_endline "*** Entering the toploop";
-    ignore (Base.main []);
-    prerr_endline "exited from toploop";
-
-  with
-  | Error (e, detail) -> 
-      Printf.eprintf "Error: %s %s\n%!" (Py.String.asString (Object.repr e)) (Py.String.asString (Object.repr detail))
-;;
-
-let _ = Base.finalize ()

test_bug1.ml

-open Opycaml.Api
-
-let _ = 
-  Base.initialize ();
-  ignore (Base.main []);
-  (* We cannot import things after Base.main ??? *)
-  ignore (Import.importModule "hogehoge"); 
-  Base.finalize ();
-  prerr_endline "finished"
-

tests/set_closure_string.ml

 let _ = Base.initialize ()
 
 let m = Module.new_ "x"
-let _ = Module.setToSys "x" m
+let _ = Module.setToSys m "x" 
 
 let _ = Format.eprintf "test start@."
 
+open Opycaml.Api (* Use the API *)
+
+let _ = 
+  prerr_endline "start";
+  Base.initialize () (* CR jfuruse: Actually, no effect, since this is called inside api.ml *)
+;;
+
+let _ =
+  prerr_endline "*** import non-existing module";
+  try
+    ignore (Import.importModule "hogehoge")
+  with
+  | Error (e, detail) ->
+      Printf.eprintf "Error: %s %s\n%!" (Py.String.asString (Object.repr e)) (Py.String.asString (Object.repr detail))
+	(* Opycaml.Api.Py.String is not available as
+	   Opycaml.Api.String, to avoid the name collision with the original OCaml String module under ``open Opycaml.Api''.
+	*)
+;;
+
+let _ =
+  prerr_endline "*** create string";
+  let o = Py.String.fromString "hello world" in
+  Base.debug "o" o;
+
+  prerr_endline "*** phys_equality";
+  assert (Base.phys_eq o o);
+
+  prerr_endline "*** repr";
+  let repr = Object.repr o in
+  Base.debug "repr" repr;
+
+  prerr_endline "*** hash";
+  let hash = Object.hash o in
+  Printf.eprintf "hash=%nd\n%!" hash;
+
+  try
+    prerr_endline "*** importing string module";
+    let stringModule = Import.importModule "string" in (* from string import * *)
+    Base.debug "stringModule" stringModule;
+
+    prerr_endline "*** dict of string";
+    let dict = Module.getDict stringModule in
+    (* Base.debug "dict" dict; *)
+
+    prerr_endline "*** get lowercase";
+    let lowercase = Dict.getItemString dict "lowercase" in
+    Base.debug "lowercase" lowercase;
+
+    prerr_endline "*** get capitalize";
+    let capitalize = Dict.getItemString dict "capitalize" in
+    Base.debug "capitalize" capitalize;
+
+    prerr_endline "*** check callable of capitalize";
+    if not (Callable.check capitalize) then begin
+      prerr_endline "capitalize is not a function!";
+      failwith "capitalize is not a function!";
+    end;
+
+    prerr_endline "*** tuple creation";
+    let tpl = Tuple.new_ 1 in
+    Base.debug "tpl" tpl;
+
+    prerr_endline "*** tuple setting";
+    prerr_endline "* ref count before:";
+    Base.debug "o" o;
+    Tuple.setItem tpl 0 o;
+    prerr_endline "* tuple set";
+    prerr_endline "* ref count after:";
+    Base.debug "tuple" tpl;
+    Base.debug "o" o; (* ref by tuple and o *)
+
+    prerr_endline "*** getItem";
+    let x = Tuple.getItem tpl 0 in
+    Base.debug "x" x; (* ref by tuple, o and x *) 
+    Base.debug "o" o; (* ref by tuple, o and x *) 
+
+    prerr_endline "*** GET_ITEM";
+    let xx = Tuple._GET_ITEM tpl 0 in
+    Base.debug "xx" xx; (* ref by tuple, o, x and xx *)
+    Base.debug "o" o;
+
+    prerr_endline "*** calling function";
+    let res = Object.callObject (Callable.coerce capitalize) [o] in
+    Printf.eprintf "res : refcnt = %d\n%!" (Base.refcnt res);
+    prerr_endline "* function called!";
+    prerr_endline (Py.String.asString (Py.String.coerce res));
+    prerr_endline (Py.String.asString o);
+
+    prerr_endline "*** fromLong (-1)";
+    let minus_1 = Int.fromLong (-1) in
+    assert (Int.asLong minus_1 = -1); 
+
+    prerr_endline "*** Run.simpleString";
+    Run.simpleString "print 'Run.simpleString'";
+    (* Run.simpleString "print(string.lowercase)"; *) (* does not work *)
+    (* Run.simpleString "print(lowercase)"; *) (* does not work *)
+
+    prerr_endline "*** registering opycaml command";
+    (* Register test command in python *)
+    Hashtbl.add Py.Callback.functions "test" 
+      (fun (self_opt : _Object t option) (args : _Object t list) ->
+	Format.eprintf "With self: %b@." (self_opt <> None);
+	Format.eprintf "#Args %d@." (List.length args);
+	Object.obj (Base.none ()));
+      (* Opycaml.Api.Py.Callback is not available as
+	 Opycaml.Api.Callback, to avoid the name collision with the original OCaml Callback module under ``open Opycaml.Api''.
+      *)
+    prerr_endline "* Now you can use opycaml.ocaml(\"test\", 1, 2, 3) to call the test OCaml function from Python";
+
+    prerr_endline "*** module insertion";
+    let m = Import.importModule "opycaml" in
+    Module.setItemString m "bar" xx;
+    prerr_endline "* check / import opycaml / opycaml.__dict__ / opycaml.bar";
+
+    prerr_endline "*** new module creation";
+    let m = Module.new_ "foo" in
+    Module.setItemString m "bar" xx;
+    Module.setToSys "foo" m;
+    prerr_endline "* check / import foo / foo.__dict__ / foo.bar";
+
+    prerr_endline "*** OCaml value embedding";
+    (* OCaml value => _Object t *)
+    let py_ocaml_1 = Base.unsafe_embed 1 in
+    Base.debug "py_ocaml_1" py_ocaml_1;
+
+    prerr_endline "*** inserting a closure into module opycaml";
+    let f (args : _Tuple t) : _Object t =
+      let i = ref 0 in
+      List.iter (fun t -> 
+	Format.eprintf "Arg %d : %s@." !i (Object.repr_string t);
+	incr i;
+      ) (Tuple.to_list args);
+      Object.obj (Base.none ())
+    in
+    
+    let m = Import.importModule "opycaml" in
+    Module.setClosureString m "f" f;
+    prerr_endline "* check / import opycaml / opycaml.__dict__ / opycaml.f(1)";
+
+    prerr_endline "*** Entering the toploop";
+    ignore (Base.main []);
+    prerr_endline "exited from toploop";
+
+  with
+  | Error (e, detail) -> 
+      Printf.eprintf "Error: %s %s\n%!" (Py.String.asString (Object.repr e)) (Py.String.asString (Object.repr detail))
+;;
+
+let _ = Base.finalize ()

tests/test_bug1.ml

+open Opycaml.Api
+
+let _ = 
+  Base.initialize ();
+  ignore (Base.main []);
+  (* We cannot import things after Base.main ??? *)
+  ignore (Import.importModule "hogehoge"); 
+  Base.finalize ();
+  prerr_endline "finished"
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.