File tree Expand file tree Collapse file tree 2 files changed +52
-0
lines changed Expand file tree Collapse file tree 2 files changed +52
-0
lines changed Original file line number Diff line number Diff line change @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55and this project adheres to [ Semantic Versioning] ( https://semver.org/spec/v2.0.0.html ) .
66
77## [ Unreleased]
8+ ### Added
9+ * Added ` afor ` and ` awith ` macros to support async Python interop (#1179 , #1181 )
10+
811### Changed
912 * Single arity functions can be tagged with ` ^:allow-unsafe-names ` to preserve their parameter names (#1212 )
1013
Original file line number Diff line number Diff line change 40854085 (finally
40864086 (println (* 1000 (- (perf-counter) start#)) "msecs")))))
40874087
4088+ ;;;;;;;;;;;;;;;;;;
4089+ ;; Async Macros ;;
4090+ ;;;;;;;;;;;;;;;;;;
4091+
4092+ (defmacro afor
4093+ "Repeatedly execute ``body`` while the binding name is repeatedly rebound to
4094+ successive values from the asynchronous iterable."
4095+ [binding & body]
4096+ (if (operator/ne 2 (count binding))
4097+ (throw
4098+ (ex-info "bindings take the form [name iter]"
4099+ {:bindings binding}))
4100+ nil)
4101+ (let [bound-name (first binding)
4102+ iter (second binding)]
4103+ `(let [it# (. ~iter ~'__aiter__)]
4104+ (loop [is-running?# true]
4105+ (when is-running?#
4106+ (try
4107+ (let [~bound-name (await (. it# ~'__anext__))]
4108+ ~@body)
4109+ (catch python/StopAsyncIteration _
4110+ (recur false))))))))
4111+
4112+ (defmacro awith
4113+ "Evaluate ``body`` within a ``try`` / ``except`` expression, binding the named
4114+ expressions as per Python's async context manager protocol spec (Python's
4115+ ``async with`` blocks)."
4116+ [bindings & body]
4117+ (let [binding (first bindings)
4118+ expr (second bindings)]
4119+ `(let [obj# ~expr
4120+ ~binding (await (. obj# ~'__aenter__))
4121+ hit-except# (volatile! false)]
4122+ (try
4123+ (let [res# ~@(if (nthnext bindings 2)
4124+ [(concat
4125+ (list 'awith (vec (nthrest bindings 2)))
4126+ body)]
4127+ (list (concat '(do) body)))]
4128+ res#)
4129+ (catch python/Exception e#
4130+ (vreset! hit-except# true)
4131+ (when-not (await (. obj# (~'__aexit__ (python/type e#) e# (.- e# ~'__traceback__))))
4132+ (throw e#)))
4133+ (finally
4134+ (when-not @hit-except#
4135+ (await (. obj# (~'__aexit__ nil nil nil)))))))))
4136+
40884137;;;;;;;;;;;;;;;;;;;;;;
40894138;; Threading Macros ;;
40904139;;;;;;;;;;;;;;;;;;;;;;
You can’t perform that action at this time.
0 commit comments