Skip to content

Fix multiple small bugs in basilisp.core #1232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
### Added
* Added support for referring imported Python names as by `from ... import ...` (#1154)
* Added support for referring imported Python names as by `from ... import ...` (#1154)

### Fixed
* Fix a bug where protocols with methods with leading hyphens in the could not be defined (#1230)
* Fix a bug where attempting to `:refer` a non-existent Var from another namespace would throw an unhelpful exception (#1231)

## [v0.3.8]
### Added
Expand Down
42 changes: 28 additions & 14 deletions src/basilisp/core.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -5235,8 +5235,12 @@
(seq refer-opt)
(let [new-ns-interns (ns-interns new-ns)]
(doseq [var-sym refer-opt]
(let [var (get new-ns-interns var-sym)]
(.add-refer current-ns var-sym var))))
(if-let [var (get new-ns-interns var-sym)]
(.add-refer current-ns var-sym var)
(throw
(ex-info "Cannot find Var in the given namespace"
{:namespace new-ns
:var var-sym})))))

:else nil)))))
nil))
Expand Down Expand Up @@ -6463,18 +6467,28 @@
:method ~method-name
:object-type obj-type#})))))
arglists))))
(let [dotted-method-name (symbol (str "." (name method-name)))]
`(.register ~(vary-meta method-name assoc :no-warn-on-var-indirection true)
~interface-name
(fn ~method-name
~@(map (fn [[obj-sym & args]]
(let [has-varargs (some #(= '& %) args)
clean-args (filter #(not= '& %) args)]
(list `[~obj-sym ~@args]
(if has-varargs
`(apply-method ~obj-sym ~method-name ~@clean-args)
`(~dotted-method-name ~obj-sym ~@clean-args)))))
arglists))))]))
`(.register ~(vary-meta method-name assoc :no-warn-on-var-indirection true)
~interface-name
(fn ~method-name
~@(map (fn [[obj-sym & args]]
(let [has-varargs (some #(= '& %) args)
clean-args (filter #(not= '& %) args)]
(list `[~obj-sym ~@args]
(cond
has-varargs
`(apply-method ~obj-sym ~method-name ~@clean-args)

;; methods starting with "-" will be interpreted
;; by the compiler as a property access (which
;; prohibit arguments to be provided), so we have
;; to hack around that by accessing the method as
;; a property and then calling it
(.startswith (name method-name) "-")
`((. ~obj-sym ~method-name) ~@clean-args)

:else
`(. ~obj-sym ~method-name ~@clean-args)))))
arglists)))]))

;; For each protocol, the following keys are defined:
;;
Expand Down
3 changes: 3 additions & 0 deletions tests/basilisp/test_core_fns.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -1778,6 +1778,9 @@
(ex-info "This is an exception" {})))))
(is (= :a redeffable))))

(deftest require-test
(is (thrown? basilisp.lang.exception/ExceptionInfo (require '[basilisp.set :refer [non-existent-var]]))))

(deftest requiring-resolve-test
(is (thrown? basilisp.lang.exception/ExceptionInfo (requiring-resolve 'a-symbol)))
(is (thrown? basilisp.lang.exception/ExceptionInfo (requiring-resolve :a-keyword)))
Expand Down
17 changes: 17 additions & 0 deletions tests/basilisp/test_protocols.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@
[basilisp.string :as str]
[basilisp.test :refer [deftest is are testing]]))

(defprotocol ProtocolWithLeadingHyphenMethod
(-method [this] [this arg1] [this arg1 & args]))

(extend-protocol ProtocolWithLeadingHyphenMethod
python/str
(-method [this]
"no args")
(-method [this arg1]
"1 arg")
(-method [this arg1 & args]
"varargs"))

(deftest protocol-method-name-test
(is (= "no args" (-method "")))
(is (= "1 arg" (-method "" "other")))
(is (= "varargs" (-method "" "other" "rest"))))

(defprotocol Shape
(area [this]))

Expand Down