|
1 | 1 | (ns clojure-python.core |
2 | | - (:require (clojure [string :as s])) |
3 | | - (:import (org.python.util PythonInterpreter) |
4 | | - (org.python.core.*))) |
| 2 | + (:require [clojure [string :as str]]) |
| 3 | + (:import [org.python.util PythonInterpreter] |
| 4 | + [org.python.core PyObject Py])) |
5 | 5 |
|
6 | 6 | (declare ^:dynamic *interp*) |
7 | 7 |
|
8 | 8 | (defn append-paths |
9 | | - "appends a vector of paths to the python system path" |
| 9 | + "Appends a vector of paths to the python system path." |
10 | 10 | [libpaths] |
11 | 11 | (.exec *interp* "import sys") |
12 | 12 | (doseq [p libpaths] |
13 | 13 | (.exec *interp* (str "sys.path.append('" p "')"))) |
14 | 14 | *interp*) |
15 | 15 |
|
16 | 16 | (defn init |
17 | | - "Establish a global python interpreter. |
18 | | - The init function is only usefully called once. |
19 | | - Alternatively, only use with-interpreter." |
| 17 | + "Establish a global python interpreter. The init function is only usefully |
| 18 | + called once. Alternatively, only use with-interpreter." |
20 | 19 | [{:keys [libpaths] :as options}] |
21 | 20 | (defonce ^:dynamic |
22 | 21 | ^{:doc "root binding serves as global python interpreter"} |
23 | 22 | *interp* |
24 | | - (org.python.util.PythonInterpreter.)) |
| 23 | + (PythonInterpreter.)) |
25 | 24 | (append-paths libpaths)) |
26 | 25 |
|
27 | 26 | (defmacro with-interpreter |
28 | 27 | "Dynamically bind a new python interpreter for the calling context." |
29 | 28 | [{:keys [libpaths] :as options} & body] |
30 | | - `(binding [*interp* (org.python.util.PythonInterpreter.)] |
| 29 | + `(binding [*interp* (PythonInterpreter.)] |
31 | 30 | (append-paths ~libpaths) |
32 | 31 | ~@body)) |
33 | 32 |
|
34 | 33 | (defmacro py-import-lib |
35 | | - "import lib |
36 | | - defaults to use same name it has in python |
37 | | - if it something like foo.bar, the name is bar." |
| 34 | + "Import lib. Defaults to use same name it has in python. If it is something |
| 35 | + like foo.bar, the name is bar." |
38 | 36 | [lib & libs] |
39 | 37 | (let [lib-sym (or (last libs) lib) |
40 | 38 | lib-strs (map name (cons lib libs)) |
41 | | - py-name (s/join "." lib-strs)] |
| 39 | + py-name (str/join "." lib-strs)] |
42 | 40 | `(do (.exec *interp* (str "import " ~py-name)) |
43 | 41 | (def ~lib-sym |
44 | 42 | (-> *interp* |
|
49 | 47 | .__dict__))))) |
50 | 48 |
|
51 | 49 | (defmacro py-import-obj |
52 | | - "import objects from lib" |
| 50 | + "Import objects from lib." |
53 | 51 | [lib obj & objs] |
54 | 52 | (cons 'do |
55 | 53 | (map |
56 | 54 | (fn [o#] |
57 | 55 | `(def ~o# (.__finditem__ ~lib ~(name o#))))) |
58 | 56 | (cons obj objs))) |
59 | 57 |
|
60 | | -(defmacro py-fn |
61 | | - "create a native clojure function applying the python |
62 | | - wrapper calls on a python function at the top level of the library |
63 | | - use this where lambda is preferred over named function" |
| 58 | +(defmacro py-fn |
| 59 | + "Create a native clojure function applying the python wrapper calls on a python |
| 60 | + function at the top level of the library use this where lambda is preferred |
| 61 | + over named function." |
64 | 62 | [lib fun] |
65 | 63 | `(let [f# (.__finditem__ |
66 | 64 | ~lib |
67 | 65 | ~(name fun))] |
68 | 66 | (fn [& args#] |
69 | 67 | (call f# args#)))) |
70 | 68 |
|
71 | | -(defmacro import-fn |
72 | | - "this is like import but it defines the imported item |
73 | | - as a native function that applies the python wrapper calls" |
| 69 | +(defmacro import-fn |
| 70 | + "This is like import but it defines the imported item as a native function that |
| 71 | + applies the python wrapper calls." |
74 | 72 | [lib fun & funs] |
75 | 73 | (cons 'do |
76 | 74 | (map |
|
79 | 77 | (cons fun funs)))) |
80 | 78 |
|
81 | 79 | (defmacro __ |
82 | | - "access attribute of class or attribute of attribute of (and so on) class" |
| 80 | + "Access attribute of class or attribute of attribute of (and so on) class." |
83 | 81 | ([class attr] |
84 | 82 | `(.__findattr__ ~class ~(name attr))) |
85 | 83 | ([class attr & attrs] |
86 | 84 | `(__ (__ ~class ~attr) ~@attrs))) |
87 | 85 |
|
88 | | -(defmacro _> |
89 | | - "call attribute as a method |
90 | | - basic usage: (_> [class attrs ...] args ...) |
91 | | - usage with keyword args: (_> [class attrs ...] args ... :key arg :key arg) |
92 | | - keyword args must come after any non-keyword args" |
| 86 | +(defmacro _> |
| 87 | + "Call attribute as a method. |
| 88 | + Basic usage: (_> [class attrs ...] args ...) |
| 89 | + Usage with keyword args: (_> [class attrs ...] args ... :key arg :key arg) |
| 90 | + Keyword args must come after any non-keyword args" |
93 | 91 | ([[class & attrs] & args] |
94 | 92 | (let [keywords (map name (filter keyword? args)) |
95 | 93 | non-keywords (filter (fn [a] (not (keyword? a))) args)] |
96 | 94 | `(call (__ ~class ~@attrs) [~@non-keywords] ~@keywords)))) |
97 | 95 |
|
98 | | -(defn dir |
99 | | - "it's slightly nicer to call the dir method in this way" |
| 96 | +(defn dir |
| 97 | + "It's slightly nicer to call the dir method in this way." |
100 | 98 | [x] (seq (.__dir__ x))) |
101 | 99 |
|
102 | 100 | (defn pyobj-nth |
103 | | - "nth item in a 'PyObjectDerived'" |
| 101 | + "Nth item in a 'PyObjectDerived'." |
104 | 102 | [o i] (.__getitem__ o i)) |
105 | 103 |
|
106 | 104 | (defn pyobj-range |
107 | | - "access 'PyObjectDerived' items as non-lazy range" |
| 105 | + "Access 'PyObjectDerived' items as non-lazy range." |
108 | 106 | [o start end] (for [i (range start end)] (pyobj-nth o i))) |
109 | 107 |
|
110 | 108 | (defn pyobj-iterate |
111 | | - "access 'PyObjectDerived' items as Lazy Seq" |
| 109 | + "Access 'PyObjectDerived' items as Lazy Seq." |
112 | 110 | [pyobj] (lazy-seq (.__iter__ pyobj))) |
113 | 111 |
|
114 | 112 | (defn java2py |
115 | | - "to wrap java objects for input as jython, and unwrap Jython output as java" |
| 113 | + "To wrap java objects for input as jython, and unwrap Jython output as java." |
116 | 114 | [args] |
117 | | - (into-array |
118 | | - org.python.core.PyObject |
119 | | - (map #(. org.python.core.Py java2py %) args))) |
120 | | - |
121 | | -(defn call |
122 | | - "The first len(args)-len(keywords) members of args[] |
123 | | - are plain arguments. The last len(keywords) arguments |
124 | | - are the values of the keyword arguments." |
| 115 | + (into-array |
| 116 | + PyObject |
| 117 | + (map #(. Py java2py %) args))) |
| 118 | + |
| 119 | +(defn call |
| 120 | + "The first len(args)-len(keywords) members of args[] are plain arguments. The |
| 121 | + last len(keywords) arguments are the values of the keyword arguments." |
125 | 122 | [fun args & key-args] |
126 | 123 | (.__tojava__ |
127 | 124 | (if key-args |
|
0 commit comments