|
| 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