Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/faq.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# FAQ & Troubleshooting

## Can I use PythonCall and PyCall together?
## [Can I use PythonCall and PyCall together?](@id faq-pycall)

Yes, you can use both PyCall and PythonCall in the same Julia session. This is platform-dependent:
- On most systems the Python interpreter used by PythonCall and PyCall must be the same (see below).
Expand Down
8 changes: 6 additions & 2 deletions docs/src/pythoncall.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,17 +240,21 @@ to your current Julia project containing Python and any required Python packages
ENV["JULIA_CONDAPKG_BACKEND"] = "Null"
ENV["JULIA_PYTHONCALL_EXE"] = "/path/to/python" # optional
ENV["JULIA_PYTHONCALL_EXE"] = "@PyCall" # optional
ENV["JULIA_PYTHONCALL_EXE"] = "@venv" # optional
```

By setting the CondaPkg backend to Null, it will never install any Conda packages. In this
case, PythonCall will use whichever Python is currently installed and in your `PATH`. You
must have already installed any Python packages that you need.

If `python` is not in your `PATH`, you will also need to set `JULIA_PYTHONCALL_EXE` to its
path.
path. Relative paths are resolved relative to the current active project.

If you also use PyCall, you can set `JULIA_PYTHONCALL_EXE=@PyCall` to use the same Python
interpreter.
interpreter. [See here](@ref faq-pycall).

If you have a Python virtual environment at `.venv` in your current active project, you
can set `JULIA_PYTHONCALL_EXE=@venv` to use it.

#### If you already have a Conda environment

Expand Down
2 changes: 2 additions & 0 deletions docs/src/releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* Added `pyconvert` rules for NumpyDates types.
* Added `PyArray` support for NumPy arrays of `datetime64` and `timedelta64`.
* Added `juliacall.ArrayValue` support for Julia arrays of `InlineDateTime64` and `InlineTimeDelta64`.
* If `JULIA_PYTHONCALL_EXE` is a relative path, it is now considered relative to the active project.
* Added option `JULIA_PYTHONCALL_EXE=@venv` to use a Python virtual environment relative to the active project.
* Bug fixes.
* Internal: switch from Requires.jl to package extensions.

Expand Down
24 changes: 24 additions & 0 deletions src/C/context.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,38 @@ function init_context()
exe_path = PyCall.python::String
CTX.lib_path = PyCall.libpython::String
CTX.which = :PyCall
elseif exe_path == "@venv"
# load from a .venv in the active project
exe_path = abspath(dirname(Base.active_project()), ".venv")
if Sys.iswindows()
exe_path = abspath(exe_path, "Scripts", "python.exe")::String
else
exe_path = abspath(exe_path, "bin", "python")::String
end
elseif startswith(exe_path, "@")
error("invalid JULIA_PYTHONCALL_EXE=$exe_path")
else
# Otherwise we use the Python specified
CTX.which = :unknown
if isabspath(exe_path)
# nothing to do
elseif '/' in exe_path || '\\' in exe_path
# it's a relative path, interpret it as relative to the current project
exe_path = abspath(dirname(Base.active_project()), exe_path)::String
else
# it's a command, find it in the PATH
given_exe_path = exe_path
exe_path = Sys.which(exe_path)
exe_path === nothing &&
error("Python executable $(repr(given_exe_path)) not found.")
exe_path::String
end
end

# Ensure Python is runnable
if !ispath(exe_path)
error("Python executable $(repr(exe_path)) does not exist.")
end
try
run(pipeline(`$exe_path --version`, stdout = devnull, stderr = devnull))
catch
Expand Down
Loading