|
3 | 3 | with the JVM -- Python dicts become java.util.Maps, for instance." |
4 | 4 | (:require [libpython-clj2.python.protocols :as py-proto] |
5 | 5 | [libpython-clj2.python.base :as py-base] |
| 6 | + [libpython-clj2.python.copy :as py-copy] |
6 | 7 | [libpython-clj2.python.fn :as py-fn] |
7 | 8 | [libpython-clj2.python.ffi :refer [with-gil] :as py-ffi] |
8 | 9 | [libpython-clj2.python.gc :as pygc] |
| 10 | + [tech.v3.datatype :as dtype] |
| 11 | + [tech.v3.datatype.protocols :as dt-proto] |
9 | 12 | [tech.v3.datatype.errors :as errors] |
10 | 13 | [tech.v3.datatype.ffi :as dt-ffi] |
11 | 14 | [clojure.core.protocols :as clj-proto]) |
12 | | - (:import [java.util Map] |
| 15 | + (:import [java.util Map Set] |
13 | 16 | [clojure.lang IFn MapEntry Fn] |
14 | 17 | [tech.v3.datatype.ffi Pointer] |
15 | 18 | [tech.v3.datatype ObjectBuffer])) |
|
197 | 200 | py-proto/PyCall |
198 | 201 | (call [callable# arglist# kw-arg-map#] |
199 | 202 | (with-gil |
200 | | - (-> (py-fn/call-py-fn @pyobj*# arglist# kw-arg-map# py-base/->python) |
| 203 | + (-> (py-fn/call-py-fn @pyobj*# arglist# kw-arg-map# fn-arg->python) |
201 | 204 | (py-base/as-jvm)))) |
202 | 205 | (marshal-return [callable# retval#] |
203 | 206 | (with-gil |
|
234 | 237 | (.write ^java.io.Writer w ^String (.toString ^Object pyobj))) |
235 | 238 |
|
236 | 239 |
|
| 240 | +(defn fn-arg->python |
| 241 | + "Slightly clever so we can pass ranges and such as function arguments." |
| 242 | + ([item opts] |
| 243 | + (cond |
| 244 | + (dt-proto/convertible-to-range? item) |
| 245 | + (py-copy/->py-range item) |
| 246 | + (dtype/reader? item) |
| 247 | + (py-proto/->python (dtype/->reader item) opts) |
| 248 | + ;;There is one more case here for iterables that aren't anything else - |
| 249 | + ;; - specifically for sequences. |
| 250 | + (and (instance? Iterable item) |
| 251 | + (not (instance? Map item)) |
| 252 | + (not (instance? String item)) |
| 253 | + (not (instance? Set item))) |
| 254 | + (py-proto/as-python item opts) |
| 255 | + :else |
| 256 | + (py-base/->python item opts))) |
| 257 | + ([item] |
| 258 | + (fn-arg->python item nil))) |
| 259 | + |
| 260 | + |
237 | 261 | (defn call-impl-fn |
238 | 262 | [fn-name att-map args] |
239 | 263 | (if-let [py-fn* (get att-map fn-name)] |
240 | 264 | ;;laziness is carefully constructed here in order to allow the arguments to |
241 | 265 | ;;be released within the context of the function call during fn.clj call-py-fn. |
242 | | - (-> (py-fn/call-py-fn @py-fn* args nil py-base/->python) |
| 266 | + (-> (py-fn/call-py-fn @py-fn* args nil fn-arg->python) |
243 | 267 | (py-base/as-jvm)) |
244 | 268 | (throw (UnsupportedOperationException. |
245 | 269 | (format "Python object has no attribute: %s" |
|
0 commit comments