Skip to content

Commit 03e2ed4

Browse files
authored
v1 migration guide (#704)
* add a migration guide for v1 * actually add the migration guide to the docs * add PyArray to migration guide * tweaks --------- Co-authored-by: Christopher Doris <github.com/cjdoris>
1 parent d5f8ace commit 03e2ed4

File tree

3 files changed

+109
-6
lines changed

3 files changed

+109
-6
lines changed

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ makedocs(
2020
"compat.md",
2121
"faq.md",
2222
"releasenotes.md",
23+
"v1-migration-guide.md",
2324
],
2425
)
2526

docs/src/releasenotes.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
# Release Notes
22

33
## Unreleased (v1)
4-
* Breaking changes to `PythonCall.GC`, which is now more like `Base.GC`:
4+
* The vast majority of these changes are breaking, see the [v1 Migration Guide](@ref) for how to upgrade.
5+
* Changes to core functionality:
6+
* Comparisons like `==(::Py, ::Py)`, `<(::Py, ::Number)`, `isless(::Number, ::Py)` now return `Bool` instead of `Py`.
7+
* Changes to `PythonCall.GC` (now more like `Base.GC`):
58
* `enable(true)` replaces `enable()`.
69
* `enable(false)` replaces `disable()`.
710
* `gc()` added.
8-
* Breaking changes to Python wrapper types:
11+
* Changes to Python wrapper types:
912
* `PyArray` has been reparametrised from `PyArray{T,N,M,L,R}` to `PyArray{T,N,F}`:
1013
* `F` is a tuple of symbols representing flags, with `:linear` replacing `L` and `:mutable` replacing `M`.
1114
* `R` is removed and is now implied by `T`, which currently must be either a bits type (equal to `R`) or `Py`, or a tuple of these.
12-
* Breaking changes to Julia wrapper types:
15+
* Changes to Julia wrapper types:
1316
* Classes renamed: `ValueBase` to `JlBase`, `AnyValue` to `Jl`, `ArrayValue` to `JlArray`, etc.
1417
* Classes removed: `RawValue`, `ModuleValue`, `TypeValue`, `NumberValue`, `ComplexValue`, `RealValue`, `RationalValue`, `IntegerValue`.
1518
* `Jl` now behaves similar to how `RawValue` behaved before. In particular, most methods on `Jl` now return a `Jl` instead of an arbitrary Python object.
@@ -19,9 +22,7 @@
1922
* Methods removed: `_jl_raw()`.
2023
* `pyjl(x)` now always returns a `juliacall.Jl` (it used to select a wrapper type if possible).
2124
* `pyjltype(x)` removed.
22-
* Other breaking changes:
23-
* Comparisons like `==(::Py, ::Py)`, `<(::Py, ::Number)`, `isless(::Number, ::Py)` now return `Bool` instead of `Py`.
24-
* New functions: `pyjlarray`, `pyjldict`, `pyjlset`.
25+
* New functions: `pyjlarray`, `pyjldict`, `pyjlset`.
2526

2627
## Unreleased
2728
* Minimum supported Python version is now 3.10.

docs/src/v1-migration-guide.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# v1 Migration Guide
2+
3+
Use this guide to help with migrating code from v0.9 to v1.
4+
5+
## Core functionality
6+
7+
Comparisons (`==`, `<`, etc.) between Python objects `Py`, or between `Py` and `Number`,
8+
used to return `Py` but now return `Bool`. The old behaviour was a pun but broke the
9+
Base API behaviour of these functions. These comparisons will now raise an error if the
10+
underlying Python operation does not return `bool`.
11+
12+
* Instead of `pytruth(Py(3) < Py(5))` use `Py(3) < Py(5)`.
13+
* Instead of `Py(3) < Py(5)` use `Py(Py(3) < Py(5))`.
14+
* Instead of `np.array([1,2,3]) < Py(3)` use `pylt(np.array([1,2,3]), Py(3))`. This is
15+
because comparisons on numpy arrays return arrays of `bool` rather than a single
16+
`bool`.
17+
* Instead of `pylt(Bool, Py(3), Py(5))` you can use `Py(3) < Py(5)`.
18+
19+
## `PythonCall.GC`
20+
21+
This submodule has been changed to closer mimic the `Base.GC` API.
22+
23+
* Instead of `PythonCall.GC.enable()` use `PythonCall.GC.enable(true)`.
24+
* Instead of `PythonCall.GC.disable()` use `PythonCall.GC.enable(false)`.
25+
26+
## Python wrappers (`PyArray`, etc.)
27+
28+
`PyArray` has been reparametrised from `PyArray{T,N,L,M,R}` to `PyArray{T,N,F}` where
29+
`F` is a `Tuple` of `Symbol` flags replacing `L` (now `:linear`) and `M`
30+
(now `:mutable`). The `R` parameter (the underlying raw type) is removed and now implied
31+
by `T`.
32+
33+
* Instead of `PyArray{Int,2,true,true,Int}` use `PyArray{Int,2,(:mutable,:linear)}`.
34+
* Instead of `PyArray{Bool,1,false,false,Bool}` use `PyArray{Bool,1,()}`.
35+
* Instead of `PyArray{Py,2,false,false,PythonCall.Wrap.UnsafePyObject}` use `PyArray{Py,2,()}`.
36+
37+
Because the `R` parameter is removed, if the underlying array is of Python objects, the
38+
`PyArray` must have eltype `Py`. Previously you could construct a `PyArray{String}` from
39+
such a thing and the elements would be automatically `pyconvert(String, element)`-ed for
40+
you.
41+
42+
* Instead of `PyArray{String}(x)` use `pyconvert.(String, PyArray{Py}(x))` if you are
43+
OK with taking a copy. Or use `mappedarray(x->pyconvert(String, x), PyArray{Py}(x))`
44+
from [MappedArrays.jl](https://github.com/JuliaArrays/MappedArrays.jl) to emulate the
45+
old behaviour.
46+
* Same comments for `pyconvert(PyArray{String}, x)`.
47+
48+
## Julia wrappers (`JlDict`, etc.)
49+
50+
The wrapper types have been renamed.
51+
52+
* Instead of `juliacall.AnyValue` use `juliacall.Jl` (but see below).
53+
* Instead of `juliacall.ArrayValue` use `juliacall.JlArray`.
54+
* Instead of `juliacall.DictValue` use `juliacall.JlDict`.
55+
56+
Most methods on the `Jl` class return a `Jl` now instead of an arbitrary Python object
57+
converted from the Julia return value. This makes generic programming easier and
58+
more closely reflects the behaviour of `Py`.
59+
60+
* Instead of `jl.seval("1+2")` use `jl.jl_eval("1+2").jl_to_py()`.
61+
* Instead of `jl.rand(5)[0]` use `jl.rand(5)[1].jl_to_py()`. Note the shift from 0-based
62+
to 1-based indexing - previously `jl.rand(5)` was a `juliacall.VectorValue` which
63+
supported Python 0-based indexing, but now `jl.rand(5)` is a `juliacall.Jl` which
64+
supports indexing by passing the arguments directly to Julia, which is 1-based.
65+
66+
Some wrapper types have been removed and can mostly be replaced with `Jl`.
67+
68+
* Instead of `juliacall.RawValue` use `juliacall.Jl`, since this behaves much the same
69+
now.
70+
* Instead of `juliacall.IntegerValue` (and other number types) use `int`, `float`,
71+
`complex` or other numeric types as appropriate. Alternatively use `juliacall.Jl`
72+
which supports the basic arithmetic and comparison operators, but is not strictly a
73+
number.
74+
* Instead of `juliacall.ModuleValue` use `juliacall.Jl`. The only benefit of
75+
`ModuleValue` was its `seval` method, which is now `Jl.jl_eval`.
76+
* Instead of `juliacall.TypeValue` use `juliacall.Jl`. The only benefit of `TypeValue`
77+
was that indexing syntax (`jl.Vector[jl.Type]`) was converted to Julia's curly syntax
78+
(`Vector{Type}`) but `Jl` does this now (for types).
79+
80+
Methods with the `_jl_` prefix are renamed with the `jl_` prefix:
81+
* Instead of `x._jl_help()` use `x.jl_help()`.
82+
* Instead of `x._jl_display()` use `x.jl_display()`.
83+
84+
The `seval` function is now called `jl_eval`:
85+
* Instead of `juliacall.Main.seval("1+2")` use `juliacall.Main.jl_eval("1+2")`.
86+
87+
Other methods, functions and attributes removed:
88+
* Instead of `x._jl_raw()` use `x` (if already a `Jl`) or `Jl(x)`. This is because the
89+
old `AnyValue` and `RawValue` are replaced by `Jl`.
90+
* Instead of `juliacall.convert(type, value)` use `juliacall.Jl(value, type)`.
91+
* Instead of `juliacall.Pkg` you must import import it yourself, such as
92+
`juliacall.Main.jl_eval("using Pkg; Pkg")`.
93+
94+
On the Julia side, the `pyjl` function now always returns a `Jl`, whereas before it
95+
would return one of the more specific wrappers (now called `JlDict`, `JlArray`, etc.).
96+
97+
* Instead of `pyjl([1, 2, 3])` use `pyjlarray([1, 2, 3])` if you need a `JlArray`.
98+
* Instead of `pyjl(Dict())` use `pyjldict(Dict())` if you need a `JlDict`.
99+
* Instead of `pyjl(Set())` use `pyjlset(Set())` if you need a `JlSet`.
100+
* Continue to use `pyjl` if you are OK with the result being a `Jl`.
101+
* Note that `Py([1, 2, 3])` still returns a `JlArray`, etc., only `pyjl` itself changed.

0 commit comments

Comments
 (0)