|
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