Skip to content

Commit

Permalink
Consider defn name metadata for internal processing
Browse files Browse the repository at this point in the history
Also added tests for decorators meta keys
  • Loading branch information
ikappaki committed Dec 19, 2024
1 parent 1c1eef9 commit b24c758
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Changed
* `import` now returns nil instead of the last module's string representation (#1174)
* `defn` now processes name metadata alongside `attr-map?`, enabling `defasync` to effectively pass meta keys like `:decorators` (part of #1178)

### Fixed
* Fix a bug in `defn` where the `attr-map?` and function metdata were merged into a seq instead of a map, causing `macroexpand` to fail in some cases (#1186)
Expand Down
7 changes: 5 additions & 2 deletions src/basilisp/core.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,10 @@
After the name, an optional mapping of meta attributes may be provided.
Any metadata values given will be attached to the metadata of the
interned Var. A few special meta keys change how ``defn`` emits the
final Var and function:
interned Var, taking precedence over existing metadata.
A few special meta keys change how ``defn`` emits the final Var and
function:
- ``:decorators`` is an optional vector of functions which will wrap
the final function emitted by ``defn``. Like standard Python
Expand Down Expand Up @@ -391,6 +393,7 @@
body (if fmeta
(rest body)
body)
fmeta (meta fname)
multi? (seq? (first body))
fsigs (if multi?
(loop [arities body
Expand Down
40 changes: 37 additions & 3 deletions tests/basilisp/test_core_macros.lpy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(ns tests.basilisp.test-core-macros
(:import contextlib inspect os socket tempfile)
(:import asyncio contextlib inspect os socket tempfile)
(:require
[basilisp.string :as str]
[basilisp.test :refer [deftest is are testing]]))
Expand Down Expand Up @@ -96,7 +96,24 @@
(is (= {:abc 10 :lmn 15 :xyz 11} (select-keys vmeta [:abc :lmn :xyz])))))

(testing "macroexpand with attr-map?"
(is (macroexpand '(defn fx {:abc 10} [] :kw)))))
(is (macroexpand '(defn fx {:abc 10} [] :kw))))

(testing "decorators"
(testing "single"
(let [add-5% #(fn [] (+ (%) 5))
fvar (defn f10 {:decorators [add-5%]} [] 7)]
(is (= 12 (f10)))))

(testing "single with arg"
(let [add-x% (fn [x] #(fn [] (+ (%) x)))
fvar (defn f11 {:decorators [(add-x% 10)]} [] 7)]
(is (= 17 (f11)))))

(testing "mix"
(let [add-5% #(fn [] (+ (%) 5))
add-x% (fn [x] #(fn [] (+ (%) x)))
fvar (defn f12 {:decorators [(add-x% 10) add-5%]} [] 9)]
(is (= 24 (f12)))))))

(deftest defasync-test
(testing "single arity defasync"
Expand Down Expand Up @@ -189,7 +206,24 @@
(is (:async vmeta))
(is (inspect/iscoroutinefunction af8))
(is (= "0.1" (:added vmeta)))
(is (= "another multi-arity docstring" (:doc vmeta)))))))
(is (= "another multi-arity docstring" (:doc vmeta)))))

(testing "async decorators"
(testing "single"
(let [add-5% #(fn ^:async _ [] (+ (await (%)) 5))
fvar (defasync ^{:decorators [add-5%]} af9 [] 7)]
(is (= 12 (asyncio/run (af9))))))

(testing "single with arg"
(let [add-x% (fn [x] #(fn ^:async _ [] (+ (await (%)) x)))
fvar (defasync ^{:decorators [(add-x% 10)]} af10 [] 7)]
(is (= 17 (asyncio/run (af10))))))

(testing "mix"
(let [add-5% #(fn ^:async _ [] (+ (await (%)) 5))
add-x% (fn [x] #(fn ^:async _ [] (+ (await (%)) x)))
fvar (defasync af11 {:decorators [(add-x% 10) add-5%]} [] 9)]
(is (= 24 (asyncio/run (af11)))))))))

(deftest defn-private-test
(testing "single arity defn-"
Expand Down

0 comments on commit b24c758

Please sign in to comment.