Skip to content

Commit e617ad9

Browse files
tkfstevengj
authored andcommitted
Make module loading lazy (#162)
* Make module loading lazy * Catch less in JuliaModule.__getattr__ * Support star import * Special handling for Main module It adds an easier way to set variables in Julia's global namespace: >>> from julia import Main >>> Main.xs = [1, 2, 3] * Deprecate Julia.__getattr__ (and make it lazy) fixes #144 * Initialize Julia in JuliaModuleLoader if required This makes `from julia import <Julia module>` works without the initial setup. Note that a custom setup can still be done by calling `julia.Julia` with appropriate arguments *before* trying to import Julia modules. closes #39, #79 * More interfaces to JuliaMainModule * Document the new API * Properly remove prefix * Fix JuliaModule.__all__; add .__dir__ * Cache original os.environ for tests * Simplify JuliaModule.__try_getattr * Add LegacyJulia to break infinite recursion * Don't import in isamodule Otherwise, trying to access undefined variables such as `julia.Base.__path__` produces a warning from Julia before `JuliaModule.__getattr__` raising `AttributeError`. * Remove core._orig_env; it can be done in test code * Use Enums as example sub-module as Base.REPL was pulled out from Base in Julia 0.7. * More import tests * Remove noop code * Fix wording
1 parent 779808b commit e617ad9

File tree

5 files changed

+278
-104
lines changed

5 files changed

+278
-104
lines changed

README.md

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,24 +58,72 @@ If you run into problems using `pyjulia`, first check the version of `PyCall.jl`
5858

5959
Usage
6060
-----
61-
To call Julia functions from python, first import the library
61+
62+
`pyjulia` provides a high-level interface which assumes a "normal"
63+
setup (e.g., `julia` is in your `PATH`) and a low-level interface
64+
which can be used in a customized setup.
65+
66+
### High-level interface
67+
68+
To call a Julia function in a Julia module, import the Julia module
69+
(say `Base`) with:
70+
71+
```python
72+
from julia import Base
73+
```
74+
75+
and then call Julia functions in `Base` from python, e.g.,
6276

6377
```python
64-
import julia
78+
Base.sind(90)
6579
```
6680

67-
then create a Julia object that makes a bridge to the Julia interpreter (assuming that `julia` is in your `PATH`)
81+
Other variants of Python import syntax also work:
6882

6983
```python
70-
j = julia.Julia()
84+
import julia.Base
85+
from julia.Base import LinAlg # import a submodule
86+
from julia.Base import sin # import a function from a module
7187
```
7288

73-
You can then call Julia functions from python, e.g.
89+
The global namespace of Julia's interpreter can be accessed via a
90+
special module `julia.Main`:
7491

7592
```python
76-
j.sind(90)
93+
from julia import Main
7794
```
7895

96+
You can set names in this module to send Python values to Julia:
97+
98+
```python
99+
Main.xs = [1, 2, 3]
100+
```
101+
102+
which allows it to be accessed directly from Julia code, e.g., it can
103+
be evaluated at Julia side using Julia syntax:
104+
105+
```python
106+
Main.eval("sin.(xs)")
107+
```
108+
109+
### Low-level interface
110+
111+
If you need a custom setup for `pyjulia`, it must be done *before*
112+
importing any Julia modules. For example, to use the Julia
113+
interpreter at `PATH/TO/MY/CUSTOM/julia`, run:
114+
115+
```python
116+
from julia import Julia
117+
j = julia.Julia(jl_runtime_path="PATH/TO/MY/CUSTOM/julia")
118+
```
119+
120+
You can then use, e.g.,
121+
122+
```python
123+
from julia import Base
124+
```
125+
126+
79127
How it works
80128
------------
81129
PyJulia loads the `libjulia` library and executes the statements therein.

julia/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from .core import Julia, JuliaError
1+
from .core import JuliaError, LegacyJulia as Julia

0 commit comments

Comments
 (0)