-
Notifications
You must be signed in to change notification settings - Fork 78
Expand file tree
/
Copy pathPyCallExt.jl
More file actions
52 lines (41 loc) · 1.82 KB
/
PyCallExt.jl
File metadata and controls
52 lines (41 loc) · 1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
module PyCallExt
# While this extension is precompilable, it can only be used without crashing if PyCall is
# using the same Python interpreter. However Julia precompiles all available extensions
# eagerly, which therefore crashes if PyCall is using a different interpreter. So for now
# we disable precompilation of this extension entirely.
__precompile__(false)
using PythonCall
using PythonCall.Core
using PythonCall.C
using PyCall: PyCall
import PythonCall: Py
# true if PyCall and PythonCall are using the same interpreter
const SAME = Ref{Bool}(false)
function __init__()
# see if PyCall and PythonCall are using the same interpreter by checking if a couple of memory addresses are the same
ptr1 = C.Py_GetVersion()
ptr2 = ccall(PyCall.@pysym(:Py_GetVersion), Ptr{Cchar}, ())
SAME[] = ptr1 == ptr2
if PythonCall.C.CTX.which == :PyCall
@assert SAME[]
end
end
# allow explicit conversion between PythonCall.Py and PyCall.PyObject
# provided they are using the same interpretr
const ERRMSG = """
Conversion between `PyCall.PyObject` and `PythonCall.Py` is only possible when using the same Python interpreter.
There are two ways to achieve this:
- Set the environment variable `JULIA_PYTHONCALL_EXE` to `"@PyCall"`. This forces PythonCall to use the same
interpreter as PyCall, but PythonCall loses the ability to manage its own dependencies.
- Set the environment variable `PYTHON` to `PythonCall.python_executable_path()` and rebuild PyCall. This forces
PyCall to use the same interpreter as PythonCall, but needs to be repeated whenever you switch Julia environment.
"""
function Py(x::PyCall.PyObject)
SAME[] || error(ERRMSG)
return pynew(C.PyPtr(PyCall.pyreturn(x)))
end
function PyCall.PyObject(x::Py)
SAME[] || error(ERRMSG)
return PyCall.PyObject(PyCall.PyPtr(getptr(incref(x))))
end
end