clj-python / libpython-clj

Python bindings for Clojure
Eclipse Public License 2.0
1.08k stars 68 forks source link

`python error in flight` when mixing `clojure.core.async`, `python/next` and `py/with` #207

Closed aur3l14no closed 2 years ago

aur3l14no commented 2 years ago

Hi~ I'm playing with telethon and clojure's async library.

In python, I can use the following code to print a message.

"""A Telegram wrapper, """
from telethon.sync import TelegramClient
import toml

config = toml.load('config.toml')

client = TelegramClient('me',
                        config['telegram']['api_id'],
                        config['telegram']['api_hash'])

with client:
    iterator = client.iter_messages('some_channel', limit=10)
    print(next(iterator))

In clojure, the following code fails and raises an exeption.

(ns main.telegram
  (:require [libpython-clj2.require :refer [require-python]]
            [libpython-clj2.python :refer [py. py.. py.-] :as py]
            [toml.core :as toml]
            [clojure.core.async :as async :refer [>! <! chan]]))

(require-python '[telethon.sync :as telethon]  ; use sync because worried that python asyncio would interfere
                '[builtins :as python])

(def config
  (toml/read (slurp "config.toml") :keywordize))

(def tg-client (telethon/TelegramClient
                "me"
                (-> config :telegram :api_id)
                (-> config :telegram :api_hash)))

(def raw-tg-chan (chan))

(defn watch-chan
  [ch]
  (async/go-loop []
    (println (<! ch))
    (recur)))

(watch-chan raw-tg-chan)

(async/go (>! raw-tg-chan "Hello World!"))

(comment
  (py/with [tg-client tg-client]
           (let
            [iterator
             (py. tg-client iter_messages
                  "some_channel" :limit 10)]
             (pr (python/next iterator))  ; works
             (async/go-loop []
               (>! raw-tg-chan (python/next iterator))  ; raises error
               (recur)))))

Error message

Exception in thread "async-dispatch-15" 
clojure.lang.ExceptionInfo: python error in flight {:type #object[tech.v3.datatype.ffi.Pointer 0xe99401 "{:address 0x000000012DE4A5B0 }"], :value #object[tech.v3.datatype.ffi.Pointer 0x1ba525c4 "{:address 0x000000014B679C70 }"], :traceback #object[tech.v3.datatype.ffi.Pointer 0x2baec794 "{:address 0x000000014B656E00 }"]}
        at libpython_clj2.python.with$python_pyerr_fetch_error_handler.invokeStatic(with.clj:14)
        at libpython_clj2.python.with$python_pyerr_fetch_error_handler.invoke(with.clj:10)
        at libpython_clj2.python.ffi$check_error_str.invokeStatic(ffi.clj:684)
        at libpython_clj2.python.ffi$check_error_str.invoke(ffi.clj:678)
        at libpython_clj2.python.ffi$check_error_throw.invokeStatic(ffi.clj:703)
        at libpython_clj2.python.ffi$check_error_throw.invoke(ffi.clj:701)
        at libpython_clj2.python.ffi$simplify_or_track.invokeStatic(ffi.clj:960)
        at libpython_clj2.python.ffi$simplify_or_track.invoke(ffi.clj:941)
        at libpython_clj2.python.fn$call_py_fn.invokeStatic(fn.clj:197)
        at libpython_clj2.python.fn$call_py_fn.invoke(fn.clj:177)
        at libpython_clj2.python.bridge_as_jvm$generic_callable_pyobject$reify__15944.call(bridge_as_jvm.clj:427)
        at libpython_clj2.python.fn$call_kw.invokeStatic(fn.clj:217)
        at libpython_clj2.python.fn$call_kw.invoke(fn.clj:214)
        at libpython_clj2.python.fn$cfn.invokeStatic(fn.clj:282)
        at libpython_clj2.python.fn$cfn.doInvoke(fn.clj:273)
        at clojure.lang.RestFn.invoke(RestFn.java:423)
        at libpython_clj2.python.bridge_as_jvm$generic_callable_pyobject$reify__15944.invoke(bridge_as_jvm.clj:427)
        at main.telegram$eval32123$fn__32124$fn__32145$state_machine__26575__auto____32152$fn__32154.invoke(NO_SOURCE_FILE:35)
        at main.telegram$eval32123$fn__32124$fn__32145$state_machine__26575__auto____32152.invoke(NO_SOURCE_FILE:35)
        at clojure.core.async.impl.ioc_macros$run_state_machine.invokeStatic(ioc_macros.clj:978)
        at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:977)
        at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invokeStatic(ioc_macros.clj:982)
        at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:980)
        at main.telegram$eval32123$fn__32124$fn__32145.invoke(NO_SOURCE_FILE:35)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at clojure.core.async.impl.concurrent$counted_thread_factory$reify__20349$fn__20350.invoke(concurrent.clj:29)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.base/java.lang.Thread.run(Thread.java:833)
aur3l14no commented 2 years ago

Related issue #106 and documents on telethon.sync.

aur3l14no commented 2 years ago

Closed in favor of the more precise #208