Skip to content

Commit

Permalink
Handle conversion of generic-alias and union-type types in ->jvm
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-polecat committed Sep 5, 2023
1 parent f39c78c commit 8990164
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 27 deletions.
61 changes: 34 additions & 27 deletions src/libpython_clj2/python/copy.clj
Original file line number Diff line number Diff line change
Expand Up @@ -172,36 +172,43 @@
stop (py-base/->jvm (py-proto/get-attr pyobj "stop"))]
(range start stop step))))

(def mapping-exceptions
"These types pass PyMapping_Check but cannot be treated as a collection."
;; See github issue#250
#{:generic-alias
:union-type})

(defmethod py-proto/pyobject->jvm :default
[pyobj & [options]]
(cond
(= :none-type (py-ffi/pyobject-type-kwd pyobj))
nil
;;Things could implement mapping and sequence logically so mapping
;;takes precedence
(= 1 (py-ffi/PyMapping_Check pyobj))
(do
(if-let [map-items (py-ffi/PyMapping_Items pyobj)]
(try
(python->jvm-copy-hashmap pyobj map-items)
(finally
(py-ffi/Py_DecRef map-items)))
(do
;;Ignore error. The mapping check isn't thorough enough to work for all
;;python objects.
(py-ffi/PyErr_Clear)
(python->jvm-copy-persistent-vector pyobj))))
;;Sequences become persistent vectors
(= 1 (py-ffi/PySequence_Check pyobj))
(python->jvm-copy-persistent-vector pyobj)
:else
{:type (py-ffi/pyobject-type-kwd pyobj)
;;Create a new GC root as the old reference is released.
:value (let [new-obj (py-ffi/track-pyobject
(Pointer. (.address (dt-ffi/->pointer pyobj))))]
(py-ffi/Py_IncRef new-obj)
new-obj)}))
(let [python-type-keyword (py-ffi/pyobject-type-kwd pyobj)]
(cond
(= :none-type python-type-keyword)
nil
;;Things could implement mapping and sequence logically so mapping
;;takes precedence
(and (= 1 (py-ffi/PyMapping_Check pyobj))
(not (mapping-exceptions python-type-keyword)))
(do
(if-let [map-items (py-ffi/PyMapping_Items pyobj)]
(try
(python->jvm-copy-hashmap pyobj map-items)
(finally
(py-ffi/Py_DecRef map-items)))
(do
;;Ignore error. The mapping check isn't thorough enough to work for all
;;python objects.
(py-ffi/PyErr_Clear)
(python->jvm-copy-persistent-vector pyobj))))
;;Sequences become persistent vectors
(= 1 (py-ffi/PySequence_Check pyobj))
(python->jvm-copy-persistent-vector pyobj)
:else
{:type python-type-keyword
;;Create a new GC root as the old reference is released.
:value (let [new-obj (py-ffi/track-pyobject
(Pointer. (.address (dt-ffi/->pointer pyobj))))]
(py-ffi/Py_IncRef new-obj)
new-obj)})))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
9 changes: 9 additions & 0 deletions test/libpython_clj2/require_python_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,12 @@
"Methods have line numbers")
(is (string? file)
"Methods have file paths"))))

(deftest convert-types
(let [typing-module (py/import-module "typing")]
(testing "convert generic alias type to JVM"
(-> (py/py. typing-module GenericAlias list str)
py/->jvm
:type
(= :generic-alias)
is))))

0 comments on commit 8990164

Please sign in to comment.