-
-
Notifications
You must be signed in to change notification settings - Fork 68
/
python.clj
143 lines (115 loc) · 3.83 KB
/
python.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
(ns libpython-clj.python
(:require [libpython-clj.jna :as libpy]
[libpython-clj.jna.base :as libpy-base]
[libpython-clj.python.logging
:refer [log-error log-warn log-info]]
[tech.parallel.utils :refer [export-symbols]]
[libpython-clj.python.interop :as pyinterop]
[libpython-clj.python.interpreter :as pyinterp
:refer [with-gil with-interpreter]]
[libpython-clj.python.object :as pyobject]
[libpython-clj.python.bridge])
(:import [com.sun.jna Pointer]
[java.io Writer]
[libpython_clj.jna PyObject]))
(set! *warn-on-reflection* true)
(export-symbols libpython-clj.python.protocols
python-type
dir
att-type-map
get-attr
has-attr?
set-attr!
callable?
has-item?
get-item
set-item!
call
call-kw
call-attr
call-attr-kw
len
as-map
as-list
as-tensor)
(export-symbols libpython-clj.python.object
->py-dict
->py-float
->py-list
->py-long
->py-string
->py-tuple
->py-fn
->python
->jvm)
(export-symbols libpython-clj.python.interop
libpython-clj-module-name)
(export-symbols libpython-clj.python.bridge
as-jvm
as-python
->numpy
as-numpy)
(defn run-simple-string
"Run a string expression returning a map of
{:globals :locals :result}.
This uses the global __main__ dict under the covers so it matches the behavior
of the cpython implementation with the exception of returning the various maps
used.
Note this will never return the result of the expression:
https://mail.python.org/pipermail/python-list/1999-April/018011.html
Globals, locals may be provided but are not necessary.
Implemented in cpython as:
PyObject *m, *d, *v;
m = PyImport_AddModule(\"__main__\");
if (m == NULL)
return -1;
d = PyModule_GetDict(m);
v = PyRun_StringFlags(command, Py_file_input, d, d, flags);
if (v == NULL) {
PyErr_Print();
return -1;
}
Py_DECREF(v);
return 0;"
[program & {:keys [globals locals]}]
(->> (pyinterop/run-simple-string program :globals globals :locals locals)
(map (fn [[k v]]
[k (as-jvm v)]))
(into {})))
(defn run-string
"Wrapper around the python c runtime PyRun_String method. This requires you to
understand what needs to be in the globals and locals dict in order for everything
to work out right and for this reason we recommend run-simple-string."
[program & {:keys [globals locals]}]
(->> (pyinterop/run-string program :globals globals :locals locals)
(map (fn [[k v]]
[k (as-jvm v)]))
(into {})))
(defn import-module
"Import a python module. Returns a bridge"
[modname]
(-> (pyinterop/import-module modname)
(as-jvm)))
(defn add-module
"Add a python module. Returns a bridge"
[modname]
(-> (pyinterop/add-module modname)
(as-jvm)))
(defn module-dict
"Get the module dictionary. Returns bridge."
[module]
(-> (pyinterop/module-dict module)
as-jvm))
(defn initialize!
[& {:keys [program-name no-io-redirect?]}]
(when-not @pyinterp/*main-interpreter*
(pyinterp/initialize! program-name)
;;setup bridge mechansim and io redirection
(pyinterop/register-bridge-type!)
(when-not no-io-redirect?
(pyinterop/setup-std-writer #'*err* "stderr")
(pyinterop/setup-std-writer #'*out* "stdout")))
:ok)
(defn finalize!
[]
(pyinterp/finalize!))