Skip to content

Commit c22bdd5

Browse files
author
Christopher Doris
committed
docs
1 parent f51dae0 commit c22bdd5

File tree

6 files changed

+86
-59
lines changed

6 files changed

+86
-59
lines changed

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@ To get started, read the [documentation](https://cjdoris.github.io/PythonCall.jl
2121

2222
## Example 1: Calling Python from Julia
2323

24-
In this example, we use `PythonCall.jl` from a [`Pluto`](https://github.com/fonsp/Pluto.jl) notebook to inspect the Iris dataset:
25-
- We load the Iris dataset as a Julia [`DataFrame`](https://dataframes.juliadata.org/stable/) using [`RDatasets.jl`](https://github.com/JuliaStats/RDatasets.jl).
26-
- We use `pytable(df)` to convert it to a Python [`pandas.DataFrame`](https://pandas.pydata.org/).
27-
- We use the Python package [`seaborn`](https://seaborn.pydata.org/) to produce a pair-plot, which is automatically displayed.
24+
In this example, we use PythonCall from a [Pluto](https://github.com/fonsp/Pluto.jl) notebook to inspect the Iris dataset:
25+
- We load the Iris dataset as a Julia [DataFrame](https://dataframes.juliadata.org/stable/) using [RDatasets](https://github.com/JuliaStats/RDatasets.jl).
26+
- We use `pytable(df)` to convert it to a Python [Pandas DataFrame](https://pandas.pydata.org/).
27+
- We use the Python package [Seaborn](https://seaborn.pydata.org/) to produce a pair-plot, which is automatically displayed.
2828

2929
![Seaborn example screenshot](https://raw.githubusercontent.com/cjdoris/PythonCall.jl/master/examples/seaborn.png)
3030

3131
## Example 2: Calling Julia from Python
3232

33-
In this example we use the Python module `juliacall` from an IPython notebook to train a simple neural network:
34-
- We generate some random training data using Python's `numpy`.
35-
- We construct and train a neural network model using Julia's `Flux`.
36-
- We plot some sample output from the model using Python's `matplotlib.pyplot`.
33+
In this example we use the Python module JuliaCall from an IPython notebook to train a simple neural network:
34+
- We generate some random training data using Python's Numpy.
35+
- We construct and train a neural network model using Julia's Flux.
36+
- We plot some sample output from the model using Python's MatPlotLib.
3737

3838
![Flux example screenshot](https://raw.githubusercontent.com/cjdoris/PythonCall.jl/master/examples/flux.png)
3939

docs/src/conversion-to-julia.md

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
# [Conversion to Julia](@id py2jl)
22

3-
## Conversion Rules
3+
## [Conversion Rules](@id py2jl-conversion)
44

5-
From Julia, one can convert Python objects to a desired type using `pyconvert(T, x)` for example.
6-
7-
From Python, when a value is passed to Julia, it is typically converted to a corresponding Julia value using `pyconvert(Any, x)`.
5+
The following table specifies the conversion rules used whenever converting a Python object to a Julia object. If the initial Python type matches the "From" column and the desired type `T` intersects with the "To" column, then that conversion is attempted. Conversions are tried in priority order, then in specificity order.
86

9-
Quite general conversions are allowed, and the target type `T` can be as specific as you like. For example
10-
```
11-
@pyv `[1, None, 3]`::Tuple{Vararg{Union{AbstractFloat,Missing}}}
12-
```
13-
evaluates to `(1.0, missing, 2.0)`.
7+
From Julia, one can convert Python objects to a desired type using `pyconvert(T, x)` for example.
148

15-
The following table specifies the conversion rules in place. If the initial Python type matches the "From" column and the desired type `T` intersects with the "To" column, then that conversion is attempted. Conversions are tried in priority order, then in specificity order.
9+
From Python, the arguments to a Julia function will be converted according to these rules with `T=Any`.
1610

1711
| From | To |
1812
| :----------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------- |

docs/src/conversion-to-python.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
# [Conversion to Python](@id jl2py)
22

3-
## Conversion Rules
4-
5-
From Julia, one converts Julia objects to Python explicitly using `Py(x)` or implicitly by passing the value to one of the many other functions, such as `pygetattr(x, "append")`.
6-
7-
From Python, calling a Julia function or indexing a Julia object, etc., will convert the result to some Python object.
3+
## [Conversion Rules](@id jl2py-conversion)
84

95
The following table specifies the conversion rules used whenever converting a Julia object to a Python object.
106

11-
The user can always explicitly choose a different conversion (e.g. by calling `pylist` or `pydict`).
7+
From Julia, this occurs explicitly with `Py(x)` or implicitly when passing Julia objects as the argument to a Python function.
8+
To avoid this automatic conversion, the user can convert objects explicitly, such as by calling `pylist` or `pydict`.
9+
10+
From Python, this occurs when converting the return value of a Julia function.
1211

1312
| From | To |
1413
| :------------------------------------------------------------------ | :------------------------------------------------------ |

docs/src/juliacall.md

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,68 @@
1-
# The Python module *juliacall*
1+
# The Python module JuliaCall
22

33
## Installation
44

5-
In the future, the package will be available on PyPI and conda.
6-
For now, you can pip install this package directly from github as follows:
7-
5+
It's as simple as
86
```bash
9-
pip install git+https://github.com/cjdoris/PythonCall.jl
7+
pip install juliacall
108
```
119

12-
Developers may wish to clone the repo directly and pip install the module in editable mode.
13-
This guarantees you are using the latest version of PythonCall in conjunction with juliacall.
14-
15-
Note also that regardless of installing `juliacall`, a module called `juliacall` will
16-
always be loaded into the interpreter by `PythonCall`. This means that other Python
17-
packages can always `import juliacall`.
10+
Developers may wish to clone the repo (https://github.com/cjdoris/PythonCall.jl) directly
11+
and pip install the module in editable mode. This guarantees you are using the latest
12+
version of PythonCall in conjunction with JuliaCall.
1813

1914
## Getting started
2015

2116
For interactive or scripting use, the simplest way to get started is:
22-
2317
```python
2418
from juliacall import Main as jl
2519
```
2620

27-
This loads a single variable `jl` (a [`ModuleValue`](#juliacall.ModuleValue)) which represents the `Main` module in Julia, from which all of Julia's functionality is available.
21+
This loads a single variable `jl` which represents the `Main` module in Julia,
22+
from which all of Julia's functionality is available:
23+
```python
24+
jl.println("Hello from Julia!")
25+
# Hello from Julia!
26+
x = jl.rand(range(10), 3, 5)
27+
x._jl_display()
28+
# 3×5 Matrix{Int64}:
29+
# 8 1 7 0 6
30+
# 9 2 1 4 0
31+
# 1 8 5 4 0
32+
import numpy
33+
numpy.sum(x, axis=0)
34+
# array([18, 11, 13, 8, 6], dtype=int64)
35+
```
2836

29-
If you are writing a package which uses Julia, then to avoid polluting the global `Main` namespace you should do:
37+
In this example:
38+
- We called the `jl.println` function to print a message.
39+
- We called the `jl.rand` function to generate an array of random integers. Note that the
40+
first argument is `range(10)` which is converted to `0:9` in Julia.
41+
- We called its special `_jl_display()` to show it using Julia's display mechanism.
42+
- We called the `numpy.sum` function to sum each column of `x`. This automatically converted
43+
`x` to a NumPy array. (We could have done `jl.sum(x, dims=1)` too.)
3044

45+
If you are writing a package which uses Julia, then to avoid polluting the global `Main`
46+
namespace you instead should start with:
3147
```python
3248
import juliacall; jl = juliacall.newmodule("SomeName");
3349
```
3450

35-
Now you can do `jl.rand(jl.Bool, 5, 5)`, which is equivalent to `rand(Bool, 5, 5)` in Julia.
36-
37-
When a Python value is passed to Julia, then typically it will be converted according to [this table](@ref py2jl) with `T=Any`.
38-
Sometimes a more specific type will be used, such as when assigning to an array whose element type is known.
39-
40-
When a Julia value is returned to Python, it will normally be converted according to [this table](@ref jl2py).
51+
What to read next:
52+
- The main functionality of this package is in `AnyValue` objects, which represent Julia
53+
objects, [documented here](@ref julia-wrappers).
54+
- If you need to install Julia packages, [read here](@ref julia-deps).
55+
- When you call a Julia function, such as `jl.rand(...)` in the above example, its
56+
arguments are converted to Julia according to [this table](@ref py2jl-conversion) and
57+
its return value is converted to Python according to [this table](@ref jl2py-conversion).
4158

42-
## Managing Julia dependencies
59+
## [Managing Julia dependencies](@id julia-deps)
4360

44-
juliacall manages its Julia dependencies using [Pkg](https://pkgdocs.julialang.org/v1) for
61+
JuliaCall manages its Julia dependencies using [Pkg](https://pkgdocs.julialang.org/v1) for
4562
packages and [jill](https://pypi.org/project/jill/) for Julia itself.
46-
If a suitable version of julia is not found on your system, it will automatically be
63+
If a suitable version of Julia is not found on your system, it will automatically be
4764
downloaded and installed into `~/.julia/pythoncall`.
48-
A Julia environment is automatically created when juliacall is loaded, is activated, and is
65+
A Julia environment is automatically created when JuliaCall is loaded, is activated, and is
4966
initialised with at least PythonCall. If you are using a virtual or conda environment then
5067
the Julia environment is created there, otherwise a global environment is created at
5168
`~/.julia/environments/PythonCall`.
@@ -74,9 +91,10 @@ Here is an example:
7491
}
7592
}
7693
```
77-
All parts are optional, except that the UUID of each package is required.
94+
All parts are optional, except that the UUID of each package is required. Typically you
95+
will just include the UUID and compat fields.
7896

79-
When juliacall starts, it will ensure the latest compatible version of julia is installed,
97+
When JuliaCall starts, it will ensure the latest compatible version of Julia is installed,
8098
and will ensure the given packages are installed.
8199

82100
## Utilities

docs/src/pycall.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Coming from *PyCall*?
22

3-
Another similar interface to Python is provided by [`PyCall`](https://github.com/JuliaPy/PyCall.jl).
3+
Another similar interface to Python is provided by [PyCall](https://github.com/JuliaPy/PyCall.jl).
44

55
On this page, we give some tips for migrating between the two modules and a comparison.
66

@@ -61,11 +61,11 @@ PythonCall uses a separate Conda environment for each Julia environment/project/
6161

6262
### Corresponding Python packages
6363

64-
PyCall has the corresponding Python package [pyjulia](https://github.com/JuliaPy/pyjulia) for calling Julia from Python, and PythonCall similarly has juliacall.
64+
PyCall has the corresponding Python package [PyJulia](https://github.com/JuliaPy/pyjulia) for calling Julia from Python, and PythonCall similarly has JuliaCall.
6565

66-
One difference is between them is their code size: pyjulia is a large package, whereas juliacall is very small, with most of the implementation being in PythonCall itself. The practical up-shot is that PythonCall/juliacall have very symmetric interfaces; for example they use identical conversion policies and have the same set of wrapper types available.
66+
One difference is between them is their code size: PyJulia is a large package, whereas JuliaCall is very small, with most of the implementation being in PythonCall itself. The practical up-shot is that PythonCall/JuliaCall have very symmetric interfaces; for example they use identical conversion policies and have the same set of wrapper types available.
6767

68-
Note also that juliacall will use a separate Julia project for each virtual/conda environment. This means that different Python environments can maintain an isolated set of Julia dependencies, including the versions of Julia and PythonCall themselves.
68+
Note also that JuliaCall will use a separate Julia project for each virtual/conda environment. This means that different Python environments can maintain an isolated set of Julia dependencies, including the versions of Julia and PythonCall themselves.
6969

7070
### Compatability
7171

docs/src/pythoncall.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# The Julia module *PythonCall*
1+
# The Julia module PythonCall
22

33
## Installation
44

@@ -45,7 +45,18 @@ In this example:
4545
- We called [`pyconvert`](@ref) to convert the Python string `sentence` to a Julia string
4646
(see [Conversion to Julia](@ref py2jl)).
4747

48-
Read on to find out what else you can do.
48+
What to read next:
49+
- The rest of this page details the functions for interacting with Python objects, of type
50+
[`Py`](@ref).
51+
- If you need to install Python packages, [read here](@ref python-deps).
52+
- When you call a Python function, such as `re.findall(...)` in the above example, its
53+
arguments are converted to Python according to [this table](@ref jl2py-conversion) and
54+
its return value is a [`Py`](@ref).
55+
- Python objects can be converted to Julia objects using [`pyconvert`](@ref) with rules
56+
according to [this table](@ref py2jl-conversion).
57+
- Python objects can also be wrapped to provide more Julian semantics. For example, a
58+
[`PyDict`](@ref) wraps a Python dict as a Julia dict, and a [`PyArray`](@ref) wraps a
59+
Python array or buffer as a Julia array. [See here](@id python-wrappers).
4960

5061
## `Py`
5162

@@ -228,7 +239,7 @@ pyge
228239
pygt
229240
```
230241

231-
## Managing Python dependencies
242+
## [Managing Python dependencies](@id python-deps)
232243

233244
PythonCall manages its Python dependencies using Conda. A Conda environment is automatically
234245
created in your active Julia environment when PythonCall is loaded, is initialised with
@@ -237,7 +248,10 @@ at least `python` and `pip`, and is activated.
237248
If your project requires more Python dependencies, use the mechanisms below to ensure they
238249
are automatically installed.
239250

240-
We **strongly recommend that you specify Conda dependencies** if possible, instead of pip
251+
**Do not install packages using conda or pip directly!** PythonCall can and will delete and
252+
reinstall its Conda environment periodically, such as when any dependencies change.
253+
254+
**We strongly recommend that you specify Conda dependencies** if possible, instead of pip
241255
or script dependencies. This is because Conda can account for all inter-dependencies between
242256
packages and so prevent incompatible combinations of packages from being installed.
243257

@@ -270,6 +284,8 @@ packages installed, and will run the script if specified.
270284
Instead of manually editing `PythonCallDeps.toml`, you can use the submodule
271285
`PythonCall.Deps` to manage the Python dependencies of the current Julia project.
272286

287+
These functions are for interactive use, **do not call them from packages!**
288+
273289
```@docs
274290
PythonCall.Deps.status
275291
PythonCall.Deps.add
@@ -293,7 +309,7 @@ Note that using a non-default interpreter will disable all dependency management
293309
environment will be created and no packages will be automatically installed. It is up to the
294310
user to ensure any required packages are installed.
295311

296-
## Writing packages which depend on *PythonCall*
312+
## Writing packages which depend on PythonCall
297313

298314
### Example
299315

0 commit comments

Comments
 (0)