libpython-clj2.require

Namespace implementing requiring python modules as Clojure namespaces. This works via scanning the module for metadata and dynamically building the Clojure namespace.

import-python

(import-python)

Loads python, python.list, python.dict, python.set, python.tuple, and python.frozenset.

require-python

(require-python req)(require-python req & reqs)

Basic usage

(require-python 'math) (math/sin 1.0) ;;=> 0.8414709848078965

(require-python 'math :as maaaath)

(maaaath/sin 1.0) ;;=> 0.8414709848078965

(require-python 'math 'csv) (require-python 'math :as pymath 'csv)) (require-python 'math :as pymath 'csv :as py-csv) (require-python 'concurrent.futures) (require-python 'concurrent.futures :as fs) (require-python '(concurrent futures :as fs))

(require-python '[requests :refer get post])

(requests/get "https//www.google.com") ;;=> <Response 200> (get "https//www.google.com") ;;=> <Response 200>

In some cases we may generate invalid arglists metadata for the clojure compiler. In those cases we have a flag, :no-arglists that will disable adding arglists to the generated metadata for the vars. Use the reload flag below if you need to force reload a namespace where invalid arglists have been generated.

(require-python '[numpy :refer linspace :no-arglists :as np])

If you would like to bind the Python module to the namespace, use the :bind-ns flag.

(require-python 'requests :bind-ns true) or (require-python 'requests :bind-ns)

Use with custom modules

For use with a custom namespace foo.py while developing, you can use:

(require-python 'foo :reload)

NOTE: unless you specify the :reload flag, ..: the module will NOT reload. If the :reload flag is set, ..: the behavior mimics importlib.reload

Setting up classpath for custom modules

Note: you may need to setup your PYTHONPATH correctly. WARNING: This is very handy for local REPL development, ..: if you are going to AOT classes, ..: refer to the documentation on codegen ..: or your AOT compilation will fail. If your foo.py lives at /path/to/foodir/foo.py, the easiest way to do it is:

(require-python :from "/path/to/foodir" 'foo) ;; or (require-python "/path/to/foodir" 'foo) ;; or (require-python {:from "/path/to/foodir"} 'foo)

as you prefer.

Additionally, if you want to keep the namespacing as you have it in Python, you may prefer to use a relative import starting from a location of your choosing. If your os.getcwd() => /some/path/foo, and your directory structure looks something like:

/some $ tree . └── path ├── baz │ └── quux.py └── foo └── bar.py

(require-python :from "path" 'baz.quux :as quux :from "path/foo" 'bar)

is perfectly acceptable. It probably makes the most sense to keep you style consistent, but you can mix and match as you see fit between , :from , and {:from }. can either be a file or a directory. If it is a file, the Python path will be set to the directory containing that file.

You may also stack several require-pythons under one path:

(require-python {:from "dir-a"} 'a 'b 'c {:from "dir-b"} 'e.f 'g {:from "dir-c} 'hi.there)

Other options more in keeping with traditional PYTHONPATH management include:

(require-python 'sys) (py/call-attr (py/get-attr sys "path") "append" "/path/to/foodir")

Another option is

(require-python 'os) (os/chdir "/path/to/foodir")

prefix lists

For convenience, if you are loading multiple Python modules with the same prefix, you can use the following notation:

(require-python '(a b c)) is equivalent to (require-python 'a.b 'a.c)

(require-python '(foo [bar :as baz :refer qux])) is equivalent to (require-python '[foo.bar :as baz :refer qux])

(require-python '(foo [bar :as baz :refer qux] buster)) (require-python '[foo.bar :as baz :refer qux] 'foo.buster))

For library developers

If you want to intern all symbols to your current namespace, you can do the following --

(require-python 'math :refer :all)

However, if you only want to use those things designated by the module under the all attribute, you can do

(require-python 'operators :refer :*)