Skip to content

Commit e2f4434

Browse files
authored
basilisp.core/load input path compatibility with clojure (#783)
Hi, could you please consider patch to adjust the `load` input path to be treated as relative to the current namespace or root path. It fixes #782. Thanks --------- Co-authored-by: ikappaki <[email protected]>
1 parent cb16d60 commit e2f4434

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
### Changed
1414
* Optimize calls to Python's `operator` module into their corresponding native operators (#754)
1515
* Allow vars to be callable to adhere to Clojure conventions (#767)
16+
* Adjust input path compatibility in basilisp.core/load input path to be relative to the namespace or the root path (#782)
1617

1718
### Fixed
1819
* Fix issue with `(count nil)` throwing an exception (#759)

src/basilisp/core.lpy

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4356,6 +4356,28 @@
43564356
(with-open [f (python/open path ** :mode "r")]
43574357
(load-reader f)))
43584358

4359+
(defn- resolve-load-path [path]
4360+
"Resolve load ``path`` relative to the current namespace, or, if it
4361+
begins with \"/\", relative to the syspath, and return it.
4362+
4363+
Throw a python/FileNotFoundError if the ``path`` cannot be resolved."
4364+
(let [path-rel (if (.startswith path "/")
4365+
path
4366+
(let [path-parent (-> (name *ns*)
4367+
(.rsplit "." 1)
4368+
(first)
4369+
(.replace "." "/"))]
4370+
(str "/" path-parent "/" path)))
4371+
path-rel (.replace path-rel "-" "_")]
4372+
(if-let [path-full (some (fn [p]
4373+
(let [pf (str p path-rel)]
4374+
(when (os.path/exists (str pf ".lpy"))
4375+
pf)))
4376+
sys/path)]
4377+
path-full
4378+
(throw (python/FileNotFoundError (str "Could not locate `"
4379+
(subs path-rel 1) ".lpy` on syspath."))))))
4380+
43594381
(defn load
43604382
"Read and evaluate the set of forms contained in the files identified by ``paths``.
43614383

@@ -4366,6 +4388,10 @@
43664388
(which is generally preferred, but not right in every scenario). ``load`` will load
43674389
the contents of the named file directly into the current namespace.
43684390

4391+
A path is interpreted relative to the syspath if it starts with a
4392+
forward slash or relative to the root directory of the current
4393+
namespace otherwise.
4394+
43694395
Note that unlike ``require``\\, files loaded by ``load`` will not be cached and will
43704396
thus incur compilation time on subsequent loads.
43714397

@@ -4374,7 +4400,7 @@
43744400
this function."
43754401
[& paths]
43764402
(doseq [path (seq paths)]
4377-
(load-file (str path ".lpy"))))
4403+
(load-file (str (resolve-load-path path) ".lpy"))))
43784404

43794405
(defn ^:inline load-string
43804406
"Read and evaluate the set of forms contained in the string ``s``\\."

tests/basilisp/test_core_fns.lpy

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
(ns tests.basilisp.test-core-fns
2-
(:import time)
2+
(:import shutil
3+
time)
34
(:require
5+
[basilisp.io :as bio]
46
[basilisp.set :as set]
57
[basilisp.test :refer [deftest are is testing]]))
68

@@ -2051,3 +2053,34 @@
20512053
(eval '(ns test-core-fns.ns-with-import (:import [time :as time-alias])))
20522054
(is (= *ns* (the-ns 'test-core-fns.ns-with-import)))
20532055
(is (= "Thu Jan 1 00:00:01 1970" (eval '(time-alias/asctime (time-alias/gmtime 1))))))))
2056+
2057+
2058+
;;;;;;;;;;
2059+
;; load ;;
2060+
;;;;;;;;;;
2061+
2062+
(deftest load-test
2063+
2064+
(let [load-dir-test "tests/basilisp/corpus"
2065+
load-dir-filepath (str load-dir-test "/core_load_1.lpy")]
2066+
(try
2067+
(when (bio/exists? load-dir-test)
2068+
(shutil/rmtree load-dir-test))
2069+
(bio/make-parents load-dir-filepath)
2070+
(spit load-dir-filepath "(print :core-load-1)")
2071+
2072+
(testing "relative load path"
2073+
(let [output (with-out-str (load "corpus/core-load-1"))]
2074+
(is (= ":core-load-1" output))))
2075+
2076+
(testing "absolute (/) load path"
2077+
;; pytest add the top basilisp directory to the classpath
2078+
(let [output (with-out-str (load "/tests/basilisp/corpus/core-load-1"))]
2079+
(is (= ":core-load-1" output))))
2080+
2081+
(testing "non-existent load path"
2082+
(is (thrown? python/FileNotFoundError (load "corpus/core-load-99"))))
2083+
2084+
(finally
2085+
(when (bio/exists? load-dir-test)
2086+
(shutil/rmtree load-dir-test))))))

0 commit comments

Comments
 (0)