Skip to content

Commit

Permalink
Add import-path
Browse files Browse the repository at this point in the history
  • Loading branch information
Kodiologist committed Apr 23, 2024
1 parent 425346d commit 1490d22
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 1 deletion.
1 change: 1 addition & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ New Features
* New macro `some->`.
* New function `sign`.
* New function `thru`.
* New function `import-path`.

Removals
------------------------------
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ API
.. hy:autofunction:: constantly
.. hy:autofunction:: dec
.. hy:autofunction:: inc
.. hy:autofunction:: import-path
.. hy:automacro:: of
.. hy:autofunction:: parse-args
.. hy:automacro:: profile/calls
Expand Down
28 changes: 28 additions & 0 deletions hyrule/misc.hy
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
hyrule.macrotools [defmacro!])

(import
sys
importlib.util
hy.scoping [ScopeLet]
hyrule.collections [by2s])

Expand Down Expand Up @@ -52,6 +54,32 @@
(+ n 1))


(defn import-path [path [name None]]

#[[Import the Python or Hy source code at ``path`` as a module with
:func:`importlib.util.spec_from_file_location`, per Python's documentation.
Return the new module object. ``name`` defaults to ``(str (hy.gensym
"import-file"))``. ::
(setv p (hy.I.pathlib.Path "mymodule.hy"))
(.write-text p "(setv foo 3)")
(setv m (import-path p))
(print m.foo) ; => 3]]

(when (is name None)
(setv name (str (hy.gensym "import-file"))))
(when (in name sys.modules)
(raise (ValueError f"The name {(hy.repr name)} is already in use in `sys.modules`.")))

; Translated from https://github.com/python/cpython/blob/408e127159e54d87bb3464fd8bd60219dc527fac/Doc/library/importlib.rst?plain=1#L1584
(setv spec (importlib.util.spec-from-file-location name path))
(setv m (importlib.util.module-from-spec spec))
(setv (get sys.modules name) m)
(.loader.exec-module spec m)

m)


(defmacro of [base #* args]

"Shorthand for type annotations with indexing. If only one argument
Expand Down
21 changes: 20 additions & 1 deletion tests/test_misc.hy
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
(require
hyrule [comment of smacrolet])
(import
sys
pytest
typing [List Dict]
hyrule [constantly dec inc parse-args sign xor])
hyrule [constantly dec inc import-path parse-args sign xor])


(defn test-constantly []
Expand Down Expand Up @@ -34,6 +35,24 @@
(assert (= (inc (X)) "__add__ got 1")))


(defn test-import-path [tmp-path]
(setv mp (/ tmp-path "a.hy"))
(.write-text mp "(setv foo 7)")

(setv m (import-path mp "mymod"))
(assert (= m.foo 7))
(assert (= m.__name__ "mymod"))
(assert (is (get sys.modules "mymod") m))

(setv m2 (import-path mp))
(assert (= m2.foo 7))
(assert (is-not m2 m))
(assert (in m2 (.values sys.modules)))

(.write-text (/ tmp-path "b.py") "bar = 3")
(assert (= (. (import-path (/ tmp-path "b.py")) bar) 3)))


(defn test-of []
(assert (= (of str) str))
(assert (= (of List int) (get List int)))
Expand Down

0 comments on commit 1490d22

Please sign in to comment.