arviz-devs / ArviZ.jl
1 20
import_arviz() = _import_dependency("arviz", "arviz"; channel="conda-forge")
2

3 20
arviz_version() = VersionNumber(arviz.__version__)
4

5
function check_needs_update(; update=true)
6 20
    if arviz_version() < _min_arviz_version
7 0
        @warn "ArviZ.jl only officially supports arviz version $(_min_arviz_version) or " *
8
              "greater but found version $(arviz_version())."
9 0
        if update
10 0
            if update_arviz()
11
                # yay, but we still already imported the old version
12 0
                msg = """
13
                Please rebuild ArviZ.jl with `using Pkg; Pkg.build("ArviZ")` and re-launch Julia
14
                to continue.
15
                """
16
            else
17 0
                msg = """
18
                Could not automatically update arviz. Please manually update arviz, rebuild
19
                ArviZ.jl with `using Pkg; Pkg.build("ArviZ")`, and then re-launch Julia to
20
                continue.
21
                """
22
            end
23 0
            @warn msg
24
        end
25
    end
26 20
    return nothing
27
end
28

29
function check_needs_rebuild()
30 20
    if arviz_version() != _precompile_arviz_version
31 0
        msg = """
32
        ArviZ.jl was built using arviz version $(_precompile_arviz_version) but loaded with
33
        version $(arviz_version()). Please recompile with `using Pkg; Pkg.build("ArviZ")`
34
        and re-launch Julia to continue.
35
        """
36 0
        @warn msg
37
    end
38 20
    return nothing
39
end
40

41
function initialize_arviz()
42 20
    ispynull(arviz) || return nothing
43 20
    copy!(arviz, import_arviz())
44 20
    check_needs_update(; update=true)
45 20
    check_needs_rebuild()
46

47 20
    append!(SUPPORTED_GROUPS, map(Symbol, arviz.data.inference_data.SUPPORTED_GROUPS))
48

49 20
    pytype_mapping(arviz.InferenceData, InferenceData)
50

51
    # pytypemap-ing RcParams produces a Dict
52 20
    copy!(_rcParams, py"$(arviz).rcparams.rcParams"o)
53

54
    # use 1-based indexing by default within arviz
55 20
    rcParams["data.index_origin"] = 1
56

57
    # handle Bokeh showing ourselves
58 20
    rcParams["plot.bokeh.show"] = false
59

60 20
    initialize_xarray()
61 20
    initialize_numpy()
62 20
    return nothing
63
end
64

65
function initialize_xarray()
66 20
    ispynull(xarray) || return nothing
67 20
    copy!(xarray, _import_dependency("xarray", "xarray"; channel="conda-forge"))
68 20
    _import_dependency("dask", "dask"; channel="conda-forge")
69 20
    pytype_mapping(xarray.Dataset, Dataset)
70 20
    return nothing
71
end
72

73
function initialize_numpy()
74
    # Trigger NumPy initialization, see https://github.com/JuliaPy/PyCall.jl/issues/744
75 20
    PyObject([true])
76 20
    return nothing
77
end
78

79
function initialize_pandas()
80 20
    ispynull(pandas) || return nothing
81 20
    copy!(pandas, _import_dependency("pandas", "pandas"; channel="conda-forge"))
82 20
    return nothing
83
end
84

85 0
function update_arviz()
86
    # updating arviz can change other packages, so we always ask for permission
87 0
    if _using_conda() && _isyes(Base.prompt("Try updating arviz using conda? [Y/n]"))
88
        # this syntax isn't officially supported, but it works (for now)
89 0
        try
90 0
            Conda.add("arviz>=$_min_arviz_version"; channel="conda-forge")
91 0
            return true
92
        catch e
93 0
            println(e.msg)
94
        end
95
    end
96 0
    if _has_pip() && _isyes(Base.prompt("Try updating arviz using pip? [Y/n]"))
97
        # can't specify version lower bound, so update to latest
98 0
        try
99 0
            run(PyCall.python_cmd(`-m pip install --upgrade -- arviz`))
100 0
            return true
101
        catch e
102 0
            println(e.msg)
103
        end
104
    end
105 0
    return false
106
end
107

108
function _import_dependency(modulename, pkgname=modulename; channel=nothing)
109 20
    try
110 20
        return if channel === nothing
111 0
            pyimport_conda(modulename, pkgname)
112
        else
113 20
            pyimport_conda(modulename, pkgname, channel)
114
        end
115
    catch e
116 0
        if _has_pip() && _isyes(Base.prompt("Try installing $pkgname using pip? [Y/n]"))
117
            # installing with pip is riskier, so we ask for permission
118 0
            run(PyCall.python_cmd(`-m pip install -- $pkgname`))
119 0
            return pyimport(modulename)
120
        end
121
        # PyCall has a nice error message
122 0
        throw(e)
123
    end
124
end
125

126 0
_isyes(s) = isempty(s) || lowercase(strip(s))  ("y", "yes")
127

128 0
_using_conda() = PyCall.conda
129

130 0
_has_pip() = _has_pymodule("pip")
131

132 0
_has_pymodule(modulename) = !ispynull(pyimport_e(modulename))

Read our documentation on viewing source code .

Loading